source: tags/arb-6.0/PARSIMONY/AP_tree_edge.cxx

Last change on this file was 12303, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.6 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : AP_tree_edge.cxx                                  //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Coded by Ralf Westram (coder@reallysoft.de) in Summer 1995    //
7//   Institute of Microbiology (Technical University Munich)       //
8//   http://www.arb-home.de/                                       //
9//                                                                 //
10// =============================================================== //
11
12#include "ap_tree_nlen.hxx"
13
14#include <AP_filter.hxx>
15#include <arb_progress.h>
16
17#include <cmath>
18#include <iomanip>
19
20using namespace std;
21
22long AP_tree_edge::timeStamp = 0;
23
24AP_tree_edge::AP_tree_edge(AP_tree_nlen *node1, AP_tree_nlen *node2)
25{
26    // not really necessary, but why not clear all:
27    memset((char *)this, 0, sizeof(AP_tree_edge));
28    age  = timeStamp++;
29
30    // link the nodes:
31
32    relink(node1, node2);
33}
34
35AP_tree_edge::~AP_tree_edge()
36{
37    unlink();
38}
39
40static void buildSonEdges(AP_tree_nlen *node) {
41    /*! Builds edges between a node and his two sons.
42     * We assume there is already an edge to node's father and there are
43     * no edges to his sons.
44     */
45
46    if (!node->is_leaf) {
47        buildSonEdges(node->get_leftson());
48        buildSonEdges(node->get_rightson());
49
50        // to ensure the nodes contain the correct distance to the border
51        // we MUST build all son edges before creating the father edge
52
53        new AP_tree_edge(node, node->get_leftson());
54        new AP_tree_edge(node, node->get_rightson());
55    }
56}
57
58void AP_tree_edge::initialize(AP_tree_nlen *tree) {
59    /*! Builds all edges in the whole tree.
60     * The root node is skipped - instead his two sons are connected with an edge
61     */
62    while (tree->get_father()) tree = tree->get_father(); // go up to root
63    buildSonEdges(tree->get_leftson());             // link left subtree
64    buildSonEdges(tree->get_rightson());            // link right subtree
65
66    // to ensure the nodes contain the correct distance to the border
67    // we MUST build all son edges before creating the root edge
68
69    new AP_tree_edge(tree->get_leftson(), tree->get_rightson()); // link brothers
70}
71
72void AP_tree_edge::destroy(AP_tree_nlen *tree) {
73    /*! Destroys all edges in the whole tree */
74    AP_tree_edge *edge = tree->nextEdge(NULL);
75    if (!edge) {
76        ap_assert(tree->is_root_node());
77        edge = tree->get_leftson()->edgeTo(tree->get_rightson());
78    }
79    ap_assert(edge); // got no edges?
80
81    edge->buildChain(-1);
82    while (edge) {
83        AP_tree_edge *next = edge->Next();
84        delete edge;
85        edge = next;
86    }
87}
88
89
90void AP_tree_edge::tailDistance(AP_tree_nlen *n)
91{
92    ap_assert(!n->is_leaf);    // otherwise call was not necessary!
93
94    int i0 = n->indexOf(this);          // index of this
95    int i1 = i0==0 ? 1 : 0;             // the indices of the other two nodes (beside n)
96    int i2 = i1==1 ? 2 : (i0==1 ? 2 : 1);
97    AP_tree_edge *e1 = n->edge[i1];     // edges to the other two nodes
98    AP_tree_edge *e2 = n->edge[i2];
99
100    cout << "tail n=" << n << " d(n)=" << n->distance << " ";
101
102    if (e1 && e2)
103    {
104        AP_tree_nlen *n1 = e1->node[1-n->index[i1]]; // the other two nodes
105        AP_tree_nlen *n2 = e2->node[1-n->index[i2]];
106
107        cout <<  "n1=" << n1 << " d(n1)=" << n1->distance <<
108            " n2=" << n2 << " d(n2)=" << n2->distance << " ";
109
110        if (n1->distance==n2->distance)
111        {
112            if (n1->distance>n->distance && n2->distance>n->distance)
113            {
114                // both distances (of n1 and n2) are greather that distance of n
115                // so its possible that the nearest connection the border was
116                // via node n and we must recalculate the distance into the other
117                // directions
118
119                ap_assert(n1->distance==n2->distance);
120
121                cout << "special tailDistance-case\n";
122                e1->tailDistance(n1);
123                e2->tailDistance(n2);
124
125                if (n1->distance<n2->distance)
126                {
127                    n->distance = n1->distance+1;
128                    if (!e2->distanceOK()) e2->calcDistance();
129                }
130                else
131                {
132                    n->distance = n2->distance+1;
133                    if (!e1->distanceOK()) e1->calcDistance();
134                }
135            }
136            else
137            {
138                cout << "tail case 2\n";
139                n->distance = n1->distance+1;
140            }
141        }
142        else
143        {
144            ap_assert(n1->distance != n2->distance);
145
146            if (n1->distance<n2->distance)
147            {
148                if (n1->distance<n->distance)
149                {
150                    // in this case the distance via n1 is the same as
151                    // the distance via the cutted edge - so we do nothing
152
153                    cout << "tail case 3\n";
154                    ap_assert(n1->distance==(n->distance-1));
155                }
156                else
157                {
158                    cout << "tail case 4\n";
159                    ap_assert(n1->distance==n->distance);
160                    ap_assert(n2->distance==(n->distance+1));
161
162                    n->distance = n1->distance+1;
163                    e2->tailDistance(n2);
164                }
165            }
166            else
167            {
168                ap_assert(n2->distance<n1->distance);
169
170                if (n2->distance<n->distance)
171                {
172                    // in this case the distance via n2 is the same as
173                    // the distance via the cutted edge - so we do nothing
174
175                    cout << "tail case 5\n";
176                    ap_assert(n2->distance==(n->distance-1));
177                }
178                else
179                {
180                    cout << "tail case 6\n";
181                    ap_assert(n2->distance==n->distance);
182                    ap_assert(n1->distance==(n->distance+1));
183
184                    n->distance = n2->distance+1;
185                    e1->tailDistance(n1);
186                }
187            }
188        }
189
190        cout << "d(n)=" << n->distance <<
191            " d(n1)=" << n1->distance <<
192            " d(n2)=" << n2->distance <<
193            " D(e1)=" << e1->Distance() <<
194            " D(e2)=" << e2->Distance() <<
195            " dtb(e1)=" << e1->distanceToBorder(INT_MAX, n) <<
196            " dtb(e2)=" << e2->distanceToBorder(INT_MAX, n) << endl;
197    }
198    else
199    {
200        if (e1)
201        {
202            AP_tree_nlen *n1 = e1->node[1-n->index[i1]];
203
204            cout << "tail case 7\n";
205            ap_assert(n1!=0);
206            if (n1->distance>n->distance) e1->tailDistance(n1);
207            n->distance = n1->distance+1;
208
209            cout << "d(n)=" << n->distance <<
210                " d(n1)=" << n1->distance <<
211                " D(e1)=" << e1->Distance() <<
212                " dtb(e1)=" << e1->distanceToBorder(INT_MAX, n) << endl;
213        }
214        else if (e2)
215        {
216            AP_tree_nlen *n2 = e2->node[1-n->index[i2]];
217
218            cout << "tail case 8\n";
219            ap_assert(n2!=0);
220            cout << "d(n2)=" << n2->distance << " d(n)=" << n->distance << endl;
221
222            if (n2->distance>n->distance) e2->tailDistance(n2);
223            n->distance = n2->distance+1;
224
225            cout << "d(n)=" << n->distance <<
226                " d(n2)=" << n2->distance <<
227                " D(e2)=" << e2->Distance() <<
228                " dtb(e2)=" << e2->distanceToBorder(INT_MAX, n) << endl;
229        }
230        else
231        {
232            cout << "tail case 9\n";
233            n->distance = INT_MAX;
234        }
235    }
236}
237
238AP_tree_edge* AP_tree_edge::unlink()
239{
240    ap_assert(this!=0);
241
242    node[0]->edge[index[0]] = NULL;
243    node[1]->edge[index[1]] = NULL;
244
245    node[0] = NULL;
246    node[1] = NULL;
247
248    return this;
249}
250
251void AP_tree_edge::calcDistance()
252{
253    ap_assert(!distanceOK());  // otherwise call was not necessary
254    ap_assert (node[0]->distance!=node[1]->distance);
255
256    if (node[0]->distance < node[1]->distance)  // node[1] has wrong distance
257    {
258        cout << "dist(" << node[1] << ") " << node[1]->distance;
259
260        if (node[1]->distance==INT_MAX) // not initialized -> do not recurse
261        {
262            node[1]->distance = node[0]->distance+1;
263            cout  << " -> " << node[1]->distance << endl;
264        }
265        else
266        {
267            node[1]->distance = node[0]->distance+1;
268            cout  << " -> " << node[1]->distance << endl;
269
270            if (!node[1]->is_leaf)
271            {
272                for (int e=0; e<3; e++)     // recursively correct distance where necessary
273                {
274                    AP_tree_edge *ed = node[1]->edge[e];
275                    if (ed && ed!=this && !ed->distanceOK()) ed->calcDistance();
276                }
277            }
278        }
279    }
280    else                        // node[0] has wrong distance
281    {
282        cout << "dist(" << node[0] << ") " << node[0]->distance;
283
284        if (node[0]->distance==INT_MAX) // not initialized -> do not recurse
285        {
286            node[0]->distance = node[1]->distance+1;
287            cout  << " -> " << node[0]->distance << endl;
288        }
289        else
290        {
291            node[0]->distance = node[1]->distance+1;
292            cout  << " -> " << node[0]->distance << endl;
293
294            if (!node[0]->is_leaf)
295            {
296                for (int e=0; e<3; e++)     // recursively correct distance where necessary
297                {
298                    AP_tree_edge *ed = node[0]->edge[e];
299                    if (ed && ed!=this && !ed->distanceOK()) ed->calcDistance();
300                }
301            }
302        }
303    }
304
305    ap_assert(distanceOK());   // invariant of AP_tree_edge (if fully constructed)
306}
307
308void AP_tree_edge::relink(AP_tree_nlen *node1, AP_tree_nlen *node2) {
309    node[0] = node1;
310    node[1] = node2;
311
312    node1->edge[index[0] = node1->unusedEdgeIndex()] = this;
313    node2->edge[index[1] = node2->unusedEdgeIndex()] = this;
314
315    node1->index[index[0]] = 0;
316    node2->index[index[1]] = 1;
317}
318
319int AP_tree_edge::test() const
320{
321    int ok = 1;     // result is used by
322    int n;
323
324    for (n=0; n<2; n++)
325    {
326        if (node[n]->edge[index[n]]!=this)
327        {
328            int i;
329
330            for (i=0; i<3; i++)
331            {
332                if (node[n]->edge[i]==this) break;
333            }
334
335            if (i==3)
336            {
337                cout << *this << " points to wrong node " << node[n]
338                     << '\n';
339                ok = 0;
340            }
341            else
342            {
343                cout << *this << " has wrong index ("
344                     << index[n] << "instead of " << i << ")\n";
345                ok = 0;
346            }
347        }
348    }
349
350    if (!distanceOK() ||
351        (node[0]->is_leaf && node[0]->distance!=0) ||
352        (node[1]->is_leaf && node[1]->distance!=0))
353    {
354        cout << "distance not set correctly at" << *this << '\n';
355    }
356    else if (Distance()!=distanceToBorder())
357    {
358        cout << "Distance() != distanceToBorder()" << endl;
359    }
360
361    return ok;
362}
363
364void AP_tree_edge::testChain(int deep)
365{
366    cout << "Building chain (deep=" << deep << ")\n";
367    buildChain(deep, false);
368    int inChain = dumpChain();
369    cout << "Edges in Chain = " << inChain << '\n';
370}
371
372int AP_tree_edge::dumpChain() const
373{
374    return next ? 1+next->dumpChain() : 1;
375}
376
377AP_tree_edge* AP_tree_edge::buildChain(int deep, bool skip_hidden,
378                                       int distanceToInsert,
379                                       const AP_tree_nlen *skip,
380                                       AP_tree_edge *comesFrom)
381{
382    AP_tree_edge *last = this;
383
384    data.distance = distanceToInsert++;
385    if (comesFrom) comesFrom->next = this;
386    this->next = NULL;
387    if (skip_hidden) {
388        if (node[0]->gr.hidden) return last;
389        if (node[1]->gr.hidden) return last;
390        if ((!node[0]->gr.has_marked_children) && (!node[1]->gr.has_marked_children)) return last;
391    }
392
393    if (deep--)
394        for (int n=0; n<2; n++)
395            if (node[n]!=skip && !node[n]->is_leaf) {
396                for (int e=0; e<3; e++) {
397                    if (node[n]->edge[e]!=this) {
398                        last = node[n]->edge[e]->buildChain(deep, skip_hidden, distanceToInsert, node[n], last);
399                    }
400                }
401            }
402
403    return last;
404}
405
406long AP_tree_edge::sizeofChain() {
407    AP_tree_edge *f;
408    long c = 0;
409    for (f=this; f;  f = f->next) c++;
410    return c;
411}
412
413int AP_tree_edge::distanceToBorder(int maxsearch, AP_tree_nlen *skipNode) const {
414    /*! @return the minimal distance to the borders of the tree (aka leafs).
415     * a return value of 0 means: one of the nodes is a leaf
416     *
417     * @param maxsearch         max search depth
418     * @param skipNode          do not descent into that part of the tree
419     */
420
421    if ((node[0] && node[0]->is_leaf) || (node[1] && node[1]->is_leaf))
422    {
423        return 0;
424    }
425
426    for (int n=0; n<2 && maxsearch; n++)
427    {
428        if (node[n] && node[n]!=skipNode)
429        {
430            for (int e=0; e<3; e++)
431            {
432                AP_tree_edge *ed = node[n]->edge[e];
433
434                if (ed && ed!=this)
435                {
436                    int dist = ed->distanceToBorder(maxsearch-1, node[n])+1;
437                    if (dist<maxsearch) maxsearch = dist;
438                }
439            }
440        }
441    }
442
443    return maxsearch;
444}
445
446void AP_tree_edge::countSpecies(int deep, const AP_tree_nlen *skip)
447{
448    if (!skip)
449    {
450        speciesInTree = 0;
451        nodesInTree   = 0;
452    }
453
454    if (deep--)
455    {
456        for (int n=0; n<2; n++)
457        {
458            if (node[n]->is_leaf)
459            {
460                speciesInTree++;
461                nodesInTree++;
462            }
463            else if (node[n]!=skip)
464            {
465                nodesInTree++;
466
467                for (int e=0; e<3; e++)
468                {
469                    if (node[n]->edge[e]!=this)
470                    {
471                        node[n]->edge[e]->countSpecies(deep, node[n]);
472                    }
473                }
474            }
475        }
476    }
477}
478
479class MutationsPerSite : virtual Noncopyable {
480    char   *Data;
481    size_t  length;
482
483public:
484    MutationsPerSite(size_t len)
485        : Data((char*)GB_calloc(sizeof(char), len*3))
486        , length(len)
487    {}
488    ~MutationsPerSite() {
489        free(Data);
490    }
491
492    char *data(int block) {
493        ap_assert(block >= 0 && block<3);
494        return Data+block*length;
495    }
496    const char *data(int block) const {
497        return const_cast<MutationsPerSite*>(this)->data(block);
498    }
499};
500
501static double ap_calc_bootstrap_remark_sub(int seq_len, const char *old, const char *ne) {
502    int sum[3] = { 0, 0, 0 };
503    for (int i=0; i<seq_len; i++) {
504        int diff = ne[i] - old[i];
505        if (diff > 1 || diff < -1) {
506#if defined(DEBUG)
507            fprintf(stderr, "diff by nni at one position not in [-1,1]: %i:%i - %i", diff, old[i], ne[i]);
508#endif // DEBUG
509            continue;
510        }
511        sum[diff+1] ++;
512    }
513
514    double prob = 0;
515    {
516        int asum = 0;
517        for (int i=0; i<3; i++) asum += sum[i];
518
519        double freq[3];
520        double log_freq[3];
521        for (int i=0; i<3; i++) {
522            freq[i] = sum[i] / double(asum); // relative frequencies of -1, 0, 1
523            if (sum[i] >0) {
524                log_freq[i] = log(freq[i]);
525            }
526            else {
527                log_freq[i] = -1e100; // minus infinit
528            }
529        }
530
531        int max = seq_len;  // bootstrap can select seq_len ones maximum
532        double log_fak_seq_len = GB_log_fak(seq_len);
533        double log_eps = log(1e-11);
534
535        // loop over all delta_mutations, begin in the middle
536        for (int tsum_add = 1; tsum_add >= -1; tsum_add -= 2) {
537            int tsum = sum[2]-sum[0];
538            if (tsum <= 0) tsum = 1;
539            for (; tsum < max && tsum > 0; tsum += tsum_add) {      // sum of mutations in bootstrap sample, loop over all possibilities
540                if (tsum_add < 0 && tsum == sum[2]-sum[0]) continue; // don't double count tsum
541
542
543
544                int max_minus = max;        // we need tsum + n_minus ones, we cannot have more than max_minux minus, reduce also
545                for (int minus_add = 1; minus_add>=-1; minus_add-=2) {
546                    int first_minus = 1;
547                    for (int n_minus = sum[0]; n_minus<max_minus && n_minus>=0; first_minus = 0, n_minus+=minus_add) {
548                        if (minus_add < 0 && first_minus) continue; // don't double count center
549                        int n_zeros = seq_len - n_minus * 2 - tsum; // number of minus
550                        int n_plus = tsum + n_minus; // number of plus ones  (n_ones + n_minus + n_zeros = seq_len)
551
552                        double log_a =
553                            n_minus * log_freq[0] +
554                            n_zeros * log_freq[1] +
555                            n_plus  * log_freq[2] +
556                            log_fak_seq_len - GB_log_fak(n_minus) - GB_log_fak(n_zeros) - GB_log_fak(n_plus);
557
558                        if (log_a < log_eps) {
559                            if (first_minus && minus_add>0) goto end;
560                            break; // cannot go with so many minus, try next
561                        }
562                        double a = exp(log_a);
563                        prob += a;
564                    }
565                }
566            }
567        end :;
568        }
569    }
570    return prob;
571}
572
573static void ap_calc_bootstrap_remark(AP_tree_nlen *son_node, AP_BL_MODE mode, const MutationsPerSite& mps) {
574    if (!son_node->is_leaf) {
575        size_t seq_len = son_node->get_seq()->get_sequence_length();
576        float  one     = ap_calc_bootstrap_remark_sub(seq_len, mps.data(0), mps.data(1));
577        float  two     = ap_calc_bootstrap_remark_sub(seq_len, mps.data(0), mps.data(2));
578
579        if ((mode & AP_BL_BOOTSTRAP_ESTIMATE) == AP_BL_BOOTSTRAP_ESTIMATE) {
580            one = one * two;    // assume independent bootstrap values for both nnis
581        }
582        else {
583            if (two<one) one = two; // dependent bootstrap values, take minimum (safe)
584        }
585
586        double bootstrap = one<1.0 ? 100.0 * one : 100.0;
587        son_node->set_bootstrap(bootstrap);
588        son_node->get_brother()->set_remark(son_node->get_remark());
589    }
590}
591
592
593static void ap_calc_leaf_branch_length(AP_tree_nlen *leaf) {
594    AP_FLOAT Seq_len = leaf->get_seq()->weighted_base_count();
595    if (Seq_len <= 1.0) Seq_len = 1.0;
596
597    AP_FLOAT parsbest = rootNode()->costs();
598    ap_main->push();
599    leaf->remove();
600    AP_FLOAT Blen     = parsbest - rootNode()->costs();
601    ap_main->pop();
602    double   blen     = Blen/Seq_len;
603
604    if (!leaf->father->father) { // at root
605        leaf->father->leftlen = blen*.5;
606        leaf->father->rightlen = blen*.5;
607    }
608    else {
609        if (leaf->father->leftson == leaf) {
610            leaf->father->leftlen = blen;
611        }
612        else {
613            leaf->father->rightlen = blen;
614        }
615    }
616}
617
618
619
620
621static void ap_calc_branch_lengths(AP_tree_nlen * /* root */, AP_tree_nlen *son, double /* parsbest */, double blen) {
622    AP_FLOAT seq_len = son->get_seq()->weighted_base_count();
623    if (seq_len <= 1.0) seq_len = 1.0;
624    blen *= 0.5 / seq_len * 2.0;        // doubled counted sum * corr
625
626    AP_tree_nlen *fathr = son->get_father();
627    if (!fathr->father) {   // at root
628        fathr->leftlen = blen *.5;
629        fathr->rightlen = blen *.5;
630    }
631    else {
632        if (fathr->leftson == son) {
633            fathr->leftlen = blen;
634        }
635        else {
636            fathr->rightlen = blen;
637        }
638    }
639
640    if (son->leftson->is_leaf) {
641        ap_calc_leaf_branch_length(son->get_leftson());
642    }
643
644    if (son->rightson->is_leaf) {
645        ap_calc_leaf_branch_length(son->get_rightson());
646    }
647}
648const double ap_undef_bl = 10.5;
649
650static void ap_check_leaf_bl(AP_tree_nlen *node) {
651    if (node->is_leaf) {
652        if (!node->father->father) {
653            if (node->father->leftlen + node->father->rightlen == ap_undef_bl) {
654                ap_calc_leaf_branch_length(node);
655            }
656        }
657        else if (node->father->leftson == node) {
658            if (node->father->leftlen == ap_undef_bl) {
659                ap_calc_leaf_branch_length(node);
660            }
661        }
662        else {
663            if (node->father->rightlen == ap_undef_bl) {
664                ap_calc_leaf_branch_length(node);
665            }
666        }
667        return;
668    }
669    else {
670        if (node->leftlen == ap_undef_bl)   ap_calc_leaf_branch_length(node->get_leftson());
671        if (node->rightlen == ap_undef_bl)  ap_calc_leaf_branch_length(node->get_rightson());
672    }
673}
674
675AP_FLOAT AP_tree_edge::nni_rek(int deep, bool skip_hidden, AP_BL_MODE mode, AP_tree_nlen *skipNode) {
676    if (!rootNode())        return 0.0;
677    if (rootNode()->is_leaf)    return rootNode()->costs();
678
679    AP_tree_edge *oldRootEdge = rootEdge();
680
681    if (deep>=0) set_root();
682
683    AP_FLOAT old_parsimony = rootNode()->costs();
684    AP_FLOAT new_parsimony = old_parsimony;
685
686    buildChain(deep, skip_hidden, 0, skipNode);
687    long cs = sizeofChain();
688    arb_progress progress(cs*2);
689    AP_tree_edge *follow;
690    {
691        // set all branch lengths to undef
692        for (follow = this; follow; follow = follow->next) {
693            follow->node[0]->leftlen          = ap_undef_bl;
694            follow->node[0]->rightlen         = ap_undef_bl;
695            follow->node[1]->leftlen          = ap_undef_bl;
696            follow->node[1]->rightlen         = ap_undef_bl;
697            follow->node[0]->father->leftlen  = ap_undef_bl;
698            follow->node[0]->father->rightlen = ap_undef_bl;
699        }
700        rootNode()->leftlen  = ap_undef_bl *.5;
701        rootNode()->rightlen = ap_undef_bl *.5;
702    }
703
704    for (follow = this; follow && !progress.aborted(); follow = follow->next) {
705        AP_tree_nlen *son = follow->sonNode();
706        AP_tree_nlen *fath = son;
707
708        if (follow->otherNode(fath)==fath->get_father()) fath = fath->get_father();
709        if (fath->father) {
710            if (fath->father->father) {
711                fath->set_root();
712                new_parsimony = rootNode()->costs();
713            }
714        }
715        if (mode & AP_BL_BOOTSTRAP_LIMIT) {
716            if (fath->father) {
717                son->set_root();
718                new_parsimony = rootNode()->costs();
719            }
720
721            MutationsPerSite mps(son->get_seq()->get_sequence_length());
722            new_parsimony = follow->nni_mutPerSite(new_parsimony, mode, &mps);
723            ap_calc_bootstrap_remark(son, mode, mps);
724        }
725        else {
726            new_parsimony = follow->nni(new_parsimony, mode);
727        }
728
729        progress.inc();
730    }
731
732    for (follow = this; follow && !progress.aborted(); follow = follow->next) {
733        ap_check_leaf_bl(follow->node[0]);
734        ap_check_leaf_bl(follow->node[1]);
735        progress.inc();
736    }
737    oldRootEdge->set_root();
738    new_parsimony = rootNode()->costs();
739
740    return new_parsimony;
741}
742
743int AP_tree_edge::dumpNNI = 0;
744int AP_tree_edge::distInsertBorder;
745int AP_tree_edge::basesChanged;
746int AP_tree_edge::speciesInTree;
747int AP_tree_edge::nodesInTree;
748
749AP_FLOAT AP_tree_edge::nni_mutPerSite(AP_FLOAT pars_one, AP_BL_MODE mode, MutationsPerSite *mps)
750{
751    AP_tree_nlen *root = rootNode();
752
753    if (node[0]->is_leaf || node[1]->is_leaf) { // a son at root
754#if 0
755        // calculate branch lengths at root
756        if (mode&AP_BL_BL_ONLY) {
757            AP_tree_nlen *tip, *brother;
758
759            if (node[0]->is_leaf) {
760                tip = node[0]; brother = node[1];
761            }
762            else {
763                tip = node[1]; brother = node[0];
764            }
765
766            AP_FLOAT    Blen = pars_one - brother->costs();
767            AP_FLOAT    Seq_len = tip->sequence->real_len();
768
769            node[0]->father->leftlen = node[0]->father->rightlen = Blen/Seq_len*.5;
770        }
771#endif
772        return pars_one;
773    }
774
775    AP_tree_edge_data oldData = data;
776
777    AP_FLOAT    parsbest = pars_one,
778        pars_two,
779        pars_three;
780    AP_tree_nlen *son = sonNode();
781    int     betterValueFound = 0;
782    {               // ******** original tree
783        if ((mode & AP_BL_BOOTSTRAP_LIMIT)) {
784            root->costs();
785            son->unhash_sequence();
786            son->get_father()->unhash_sequence();
787            ap_assert(!son->father->father);
788            AP_tree_nlen *brother = son->get_brother();
789            brother->unhash_sequence();
790
791            ap_assert(mps);
792            pars_one = root->costs(mps->data(0));
793        }
794        else if (pars_one==0.0) {
795            pars_one = root->costs();
796        }
797    }
798    {               // ********* first nni
799        ap_main->push();
800        son->swap_assymetric(AP_LEFT);
801        pars_two = root->costs(mps ? mps->data(1) : NULL);
802
803        if (pars_two <= parsbest) {
804            if ((mode & AP_BL_NNI_ONLY) == 0) ap_main->pop();
805            else                              ap_main->clear();
806
807            parsbest         = pars_two;
808            betterValueFound = (int)(pars_one-pars_two);
809        }
810        else {
811            ap_main->pop();
812        }
813    }
814    {               // ********** second nni
815        ap_main->push();
816        son->swap_assymetric(AP_RIGHT);
817        pars_three = root->costs(mps ? mps->data(2) : NULL);
818
819        if (pars_three <= parsbest) {
820            if ((mode & AP_BL_NNI_ONLY) == 0) ap_main->pop();
821            else                              ap_main->clear();
822
823            parsbest         = pars_three;
824            betterValueFound = (int)(pars_one-pars_three);
825        }
826        else {
827            ap_main->pop();
828        }
829    }
830
831    if (mode & AP_BL_BL_ONLY) { // ************* calculate branch lengths **************
832        AP_FLOAT blen = (pars_one + pars_two + pars_three) - (3.0 * parsbest);
833        if (blen <0) blen = 0;
834        ap_calc_branch_lengths(root, son, parsbest, blen);
835    }
836
837    // zu Auswertungszwecken doch unsortiert uebernehmen:
838
839    data.parsValue[0] = pars_one;
840    data.parsValue[1] = pars_two;
841    data.parsValue[2] = pars_three;
842
843
844    if (dumpNNI) {
845        if (dumpNNI==2) GBK_terminate("NNI called between optimize and statistics");
846
847        AP_tree_nlen *node0 = this->node[0];
848        AP_tree_nlen *node1 = this->node[1];
849        if (node0->gr.leaf_sum > node1->gr.leaf_sum) { // node0 is final son
850            node0 = node1;
851        }
852
853        static int num = 0;
854
855        node0->use_as_remark(GBS_global_string_copy("%i %4.0f:%4.0f:%4.0f     %4.0f:%4.0f:%4.0f\n",
856                                                    num++,
857                                                    oldData.parsValue[0], oldData.parsValue[1], oldData.parsValue[2],
858                                                    data.parsValue[0], data.parsValue[1], data.parsValue[2]));
859
860        cout
861            << setw(4) << distInsertBorder
862            << setw(6) << basesChanged
863            << setw(4) << distanceToBorder()
864            << setw(4) << data.distance
865            << setw(4) << betterValueFound
866            << setw(8) << oldData.parsValue[0]
867            << setw(8) << oldData.parsValue[1]
868            << setw(8) << oldData.parsValue[2]
869            << setw(8) << data.parsValue[0]
870            << setw(8) << data.parsValue[1]
871            << setw(8) << data.parsValue[2]
872            << '\n';
873    }
874
875    return parsbest;
876}
877
878ostream& operator<<(ostream& out, const AP_tree_edge& e)
879{
880    static int notTooDeep;
881
882    out << ' ';
883
884    if (notTooDeep || &e==NULL) {
885        out << e;
886    }
887    else {
888        notTooDeep = 1;
889        out << "AP_tree_edge(" << e
890            << ", node[0]=" << *(e.node[0])
891            << ", node[1]=" << *(e.node[1])
892            << ")";
893        notTooDeep = 0; // cppcheck-suppress redundantAssignment
894    }
895
896    return out << ' ';
897}
898
899void AP_tree_edge::mixTree(int cnt)
900{
901    buildChain(-1);
902
903    while (cnt--)
904    {
905        AP_tree_edge *follow = this;
906
907        while (follow) {
908            AP_tree_nlen *son = follow->sonNode();
909            if (!son->is_leaf) son->swap_assymetric(GB_random(2) ? AP_LEFT : AP_RIGHT);
910            follow = follow->next;
911        }
912    }
913}
914
Note: See TracBrowser for help on using the repository browser.