source: branches/ali/GDE/PHYML20130708/phyml/src/mixt.c

Last change on this file was 10307, checked in by aboeckma, 11 years ago

added most recent version of phyml

File size: 53.0 KB
Line 
1/*
2
3PhyML:  a program that  computes maximum likelihood phylogenies from
4DNA or AA homologous sequences.
5
6Copyright (C) Stephane Guindon. Oct 2003 onward.
7
8All parts of the source except where indicated are distributed under
9the GNU public licence. See http://www.opensource.org for details.
10
11*/
12
13#include "mixt.h"
14
15int n_sec1 = 0;
16
17//////////////////////////////////////////////////////////////
18//////////////////////////////////////////////////////////////
19
20void MIXT_Chain_All(t_tree *mixt_tree)
21{
22  t_tree *curr, *next;
23  int i;
24
25  curr = mixt_tree;
26  next = mixt_tree->next;
27 
28  do
29    {
30      MIXT_Chain_String(curr->mod->aa_rate_mat_file,next->mod->aa_rate_mat_file);     
31      MIXT_Chain_String(curr->mod->modelname,next->mod->modelname);     
32      MIXT_Chain_String(curr->mod->custom_mod_string,next->mod->custom_mod_string);           
33      MIXT_Chain_Scalar_Dbl(curr->mod->kappa,next->mod->kappa);           
34      MIXT_Chain_Scalar_Dbl(curr->mod->lambda,next->mod->lambda);
35      MIXT_Chain_Scalar_Dbl(curr->mod->br_len_multiplier,next->mod->br_len_multiplier);           
36      MIXT_Chain_Scalar_Dbl(curr->mod->mr,next->mod->mr);
37      MIXT_Chain_Vector_Dbl(curr->mod->Pij_rr,next->mod->Pij_rr);   
38      MIXT_Chain_Vector_Dbl(curr->mod->user_b_freq,next->mod->user_b_freq);
39      For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l,next->a_edges[i]->l);
40      For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l_old,next->a_edges[i]->l_old);
41      For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l_var,next->a_edges[i]->l_var);
42      For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l_var_old,next->a_edges[i]->l_var_old);
43      MIXT_Chain_Rmat(curr->mod->r_mat,next->mod->r_mat);           
44      MIXT_Chain_RAS(curr->mod->ras,next->mod->ras);           
45      MIXT_Chain_Efrq(curr->mod->e_frq,next->mod->e_frq);           
46      MIXT_Chain_Eigen(curr->mod->eigen,next->mod->eigen);           
47
48      curr = next;
49      next = next->next;
50    }
51  while(next);
52
53  curr = mixt_tree;
54  do
55    {
56      MIXT_Chain_Edges(curr);
57      MIXT_Chain_Nodes(curr);
58      MIXT_Chain_Sprs(curr);
59      MIXT_Chain_Triplets(curr);
60     
61      curr = curr->next;
62    }
63  while(curr);
64
65  Make_Rmat_Weight(mixt_tree);
66  Make_Efrq_Weight(mixt_tree);
67 
68}
69
70//////////////////////////////////////////////////////////////
71//////////////////////////////////////////////////////////////
72
73void MIXT_Chain_Edges(t_tree *tree)
74{
75  int i;
76  t_edge *b;
77
78  For(i,2*tree->n_otu-1)
79    {
80      b = tree->a_edges[i];
81
82      if(tree->next)      b->next       = tree->next->a_edges[i];
83      if(tree->prev)      b->prev       = tree->prev->a_edges[i];
84      if(tree->next_mixt) b->next_mixt  = tree->next_mixt->a_edges[i];
85      if(tree->prev_mixt) b->prev_mixt  = tree->prev_mixt->a_edges[i];
86    }
87}
88
89//////////////////////////////////////////////////////////////
90//////////////////////////////////////////////////////////////
91
92void MIXT_Chain_Nodes(t_tree *tree)
93{
94  int i;
95  t_node *n;
96
97  For(i,2*tree->n_otu-2)
98    {
99      n = tree->a_nodes[i];
100
101      if(tree->next)      n->next       = tree->next->a_nodes[i];
102      if(tree->prev)      n->prev       = tree->prev->a_nodes[i];
103      if(tree->next_mixt) n->next_mixt  = tree->next_mixt->a_nodes[i];
104      if(tree->prev_mixt) n->prev_mixt  = tree->prev_mixt->a_nodes[i];
105    }
106}
107
108//////////////////////////////////////////////////////////////
109//////////////////////////////////////////////////////////////
110
111void MIXT_Chain_Sprs(t_tree *tree)
112{
113  int i;
114 
115  if(tree->next)      tree->best_spr->next      = tree->next->best_spr;
116  if(tree->prev)      tree->best_spr->prev      = tree->prev->best_spr;
117  if(tree->next_mixt) tree->best_spr->next_mixt = tree->next_mixt->best_spr;
118  if(tree->prev_mixt) tree->best_spr->prev_mixt = tree->prev_mixt->best_spr;
119
120  For(i,2*tree->n_otu-2)
121    {
122      if(tree->next)      tree->spr_list[i]->next      = tree->next->spr_list[i];
123      if(tree->prev)      tree->spr_list[i]->prev      = tree->prev->spr_list[i];
124      if(tree->next_mixt) tree->spr_list[i]->next_mixt = tree->next_mixt->spr_list[i];
125      if(tree->prev_mixt) tree->spr_list[i]->prev_mixt = tree->prev_mixt->spr_list[i];
126    }   
127}
128
129//////////////////////////////////////////////////////////////
130//////////////////////////////////////////////////////////////
131
132void MIXT_Chain_Triplets(t_tree *tree)
133{
134  if(tree->next)      tree->triplet_struct->next      = tree->next->triplet_struct;
135  if(tree->prev)      tree->triplet_struct->prev      = tree->prev->triplet_struct;
136}
137
138//////////////////////////////////////////////////////////////
139//////////////////////////////////////////////////////////////
140
141void MIXT_Chain_String(t_string *curr, t_string *next)
142{
143  if(!next)
144    {
145      return;
146    }
147  else
148    {
149      t_string *buff,*last;
150
151      last = NULL;
152
153      /*! Search backward */
154      buff = curr;
155      while(buff)
156        {
157          if(buff == next) break;
158          buff = buff->prev;
159        }
160     
161      /*! Search forward */
162      if(!buff)
163        {
164          buff = curr;
165          while(buff)
166            {
167              if(buff == next) break;
168              buff = buff->next;
169            }
170        }
171
172
173      if(!buff) 
174        {
175          last = curr;
176          while(last->next) { last = last->next; }
177
178          last->next = next;
179          next->prev = last;
180        }
181    }
182}
183
184//////////////////////////////////////////////////////////////
185//////////////////////////////////////////////////////////////
186
187void MIXT_Chain_Vector_Dbl(vect_dbl *curr, vect_dbl *next)
188{
189  if(!next)
190    {
191      return;
192    }
193  else
194    {
195      vect_dbl *buff,*last;
196
197      last = NULL;
198
199      buff = curr;
200      while(buff)
201        {
202          if(buff == next) break;
203          buff = buff->prev;
204        }
205     
206      /*! Search forward */
207      if(!buff)
208        {
209          buff = curr;
210          while(buff)
211            {
212              if(buff == next) break;
213              buff = buff->next;
214            }
215        }
216
217      if(!buff) 
218        {
219          last = curr;
220          while(last->next) { last = last->next; }
221
222          last->next = next;
223          next->prev = last;
224        }
225    }
226}
227
228//////////////////////////////////////////////////////////////
229//////////////////////////////////////////////////////////////
230
231void MIXT_Chain_Scalar_Dbl(scalar_dbl *curr, scalar_dbl *next)
232{
233  if(!next)
234    {
235      return;
236    }
237  else
238    {
239      scalar_dbl *buff, *last;
240
241      last = NULL;
242
243      buff = curr;
244      while(buff)
245        {
246          if(buff == next) break;
247          buff = buff->prev;
248        }
249     
250      /*! Search forward */
251      if(!buff)
252        {
253          buff = curr;
254          while(buff)
255            {
256              if(buff == next) break;
257              buff = buff->next;
258            }
259        }
260
261      if(!buff) 
262        {
263          last = curr;
264          while(last->next) { last = last->next; }
265
266          last->next = next;
267          next->prev = last;
268        }
269    }
270}
271
272//////////////////////////////////////////////////////////////
273//////////////////////////////////////////////////////////////
274
275void MIXT_Chain_Rmat(t_rmat *curr, t_rmat *next)
276{
277  if(!next)
278    {
279      return;
280    }
281  else
282    {
283      t_rmat *buff, *last;
284
285      last = NULL;
286
287      buff = curr;
288      while(buff)
289        {
290          if(buff == next) break;
291          buff = buff->prev;
292        }
293     
294      /*! Search forward */
295      if(!buff)
296        {
297          buff = curr;
298          while(buff)
299            {
300              if(buff == next) break;
301              buff = buff->next;
302            }
303        }
304
305      if(!buff)
306        {
307          last = curr;
308          while(last->next) { last = last->next; }
309
310          last->next = next;
311          next->prev = last;
312        }
313    }
314}
315
316//////////////////////////////////////////////////////////////
317//////////////////////////////////////////////////////////////
318
319void MIXT_Chain_Efrq(t_efrq *curr, t_efrq *next)
320{
321  if(!next)
322    {
323      return;
324    }
325  else
326    {
327      t_efrq *buff,*last;
328
329      last = NULL;
330
331      buff = curr;
332      while(buff)
333        {
334          if(buff == next) break;
335          buff = buff->prev;
336        }
337     
338      /*! Search forward */
339      if(!buff)
340        {
341          buff = curr;
342          while(buff)
343            {
344              if(buff == next) break;
345              buff = buff->next;
346            }
347        }
348
349      if(!buff) 
350        {
351          last = curr;
352          while(last->next) { last = last->next; }
353
354          last->next = next;
355          next->prev = last;
356        }
357    }
358}
359
360//////////////////////////////////////////////////////////////
361//////////////////////////////////////////////////////////////
362
363void MIXT_Chain_Eigen(eigen *curr, eigen *next)
364{
365  if(!next)
366    {
367      return;
368    }
369  else
370    {
371      eigen *buff,*last;
372
373      last = NULL;
374
375      buff = curr;
376      while(buff)
377        {
378          if(buff == next) break;
379          buff = buff->prev;
380        }
381     
382      /*! Search forward */
383      if(!buff)
384        {
385          buff = curr;
386          while(buff)
387            {
388              if(buff == next) break;
389              buff = buff->next;
390            }
391        }
392
393      if(!buff) 
394        {
395          last = curr;
396          while(last->next) { last = last->next; }
397
398          last->next = next;
399          next->prev = last;
400        }
401    }
402}
403
404//////////////////////////////////////////////////////////////
405//////////////////////////////////////////////////////////////
406
407void MIXT_Chain_RAS(t_ras *curr, t_ras *next)
408{
409  if(!next) return;
410  else
411    {
412      t_ras *buff,*last;
413     
414      last = NULL;
415     
416      buff = curr;
417      while(buff)
418        {
419          if(buff == next) break;
420          buff = buff->prev;
421        }
422     
423      /*! Search forward */
424      if(!buff)
425        {
426          buff = curr;
427          while(buff)
428            {
429              if(buff == next) break;
430              buff = buff->next;
431            }
432        }
433
434      if(!buff) 
435        {
436          last = curr;
437          while(last->next) { last = last->next; }
438
439          last->next = next;
440          next->prev = last;
441        }
442    }
443}
444
445//////////////////////////////////////////////////////////////
446//////////////////////////////////////////////////////////////
447
448void MIXT_Turn_Branches_OnOff(int onoff, t_tree *mixt_tree)
449{
450  int i;
451  t_tree *tree;
452
453  if(mixt_tree->is_mixt_tree == NO)
454    {
455      PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__);
456      Exit("\n");
457    }
458
459  tree = mixt_tree;
460 
461  do
462    {
463      For(i,2*tree->n_otu-1) tree->a_edges[i]->l->onoff = onoff;
464      tree = tree->next;
465    }
466  while(tree && tree->is_mixt_tree == NO);
467}
468
469//////////////////////////////////////////////////////////////
470//////////////////////////////////////////////////////////////
471
472phydbl *MIXT_Get_Lengths_Of_This_Edge(t_edge *mixt_b, t_tree *mixt_tree)
473{
474  phydbl *lens;
475  t_edge *b;
476  t_tree *tree;
477  int n_lens;
478
479  lens = NULL;
480  n_lens = 0;
481
482  b = mixt_b; 
483  tree = mixt_tree;
484  do
485    {
486     
487      if(!lens) lens = (phydbl *)mCalloc(2,sizeof(phydbl));
488      else      lens = (phydbl *)realloc(lens,(n_lens+2)*sizeof(phydbl));
489     
490      lens[n_lens]   = b->l->v;     
491      lens[n_lens+1] = b->l_var->v;
492
493      n_lens+=2;
494      b = b->next;
495      tree = tree->next;
496    }
497  while(b);
498
499  return(lens);
500}
501
502//////////////////////////////////////////////////////////////
503//////////////////////////////////////////////////////////////
504
505void MIXT_Set_Lengths_Of_This_Edge(phydbl *lens, t_edge *mixt_b, t_tree *mixt_tree)
506{
507  t_edge *b;
508  int n_lens;
509  t_tree *tree;
510
511  n_lens = 0;
512
513  tree = mixt_tree;
514  b = mixt_b;
515  do
516    {
517      b->l->v = lens[n_lens];     
518      b->l_var->v = lens[n_lens+1];
519
520      n_lens+=2;
521      b = b->next;
522      tree = tree->next;
523    }
524  while(b);
525}
526
527//////////////////////////////////////////////////////////////
528//////////////////////////////////////////////////////////////
529
530void MIXT_Post_Order_Lk(t_node *mixt_a, t_node *mixt_d, t_tree *mixt_tree)
531{
532  t_tree *tree;
533  t_node *a,*d;
534
535  tree = mixt_tree;
536  a    = mixt_a;
537  d    = mixt_d;
538
539  do
540    {
541      if(tree->is_mixt_tree)
542        {
543          tree = tree->next;
544          a    = a->next;
545          d    = d->next;
546        }
547
548      if(tree->mod->ras->invar == NO) Post_Order_Lk(a,d,tree);
549     
550      tree = tree->next;
551      a    = a->next;
552      d    = d->next;
553    }
554  while(tree);
555 
556}
557
558//////////////////////////////////////////////////////////////
559//////////////////////////////////////////////////////////////
560
561void MIXT_Pre_Order_Lk(t_node *mixt_a, t_node *mixt_d, t_tree *mixt_tree)
562{
563  t_tree *tree;
564  t_node *a,*d;
565
566  tree = mixt_tree;
567  a    = mixt_a;
568  d    = mixt_d;
569
570  do
571    {
572      if(tree->is_mixt_tree)
573        {
574          tree = tree->next;
575          a    = a->next;
576          d    = d->next;
577        }
578     
579      if(tree->mod->ras->invar == NO) Pre_Order_Lk(a,d,tree);
580
581      tree = tree->next;
582      a    = a->next;
583      d    = d->next;
584    }
585  while(tree);
586 
587}
588
589//////////////////////////////////////////////////////////////
590//////////////////////////////////////////////////////////////
591
592phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
593{
594  t_tree *tree,*cpy_mixt_tree;
595  t_edge *b,*cpy_mixt_b;
596  phydbl sum_lnL;
597  int site, class, br;
598  phydbl *sum_scale_left_cat,*sum_scale_rght_cat;
599  phydbl sum,tmp;
600  int exponent;
601  phydbl site_lk_cat,site_lk,log_site_lk,inv_site_lk;
602  int num_prec_issue,fact_sum_scale;
603  phydbl max_sum_scale,min_sum_scale;
604  int ambiguity_check,state;
605  int k,l;
606  int dim1,dim2;
607  phydbl r_mat_weight_sum, e_frq_weight_sum, sum_probas;
608 
609  tree            = NULL;
610  b               = NULL;
611  cpy_mixt_tree   = mixt_tree;
612  cpy_mixt_b      = mixt_b;
613
614
615  do /*! Consider each element of the data partition */
616    {
617      if(!cpy_mixt_b) Set_Model_Parameters(mixt_tree->mod);     
618
619      Set_Br_Len_Var(mixt_tree);
620
621      if(!cpy_mixt_b)
622        {
623          For(br,2*mixt_tree->n_otu-3) Update_PMat_At_Given_Edge(mixt_tree->a_edges[br],mixt_tree);
624          if(mixt_tree->n_root)
625            {
626              Update_PMat_At_Given_Edge(mixt_tree->n_root->b[1],tree);
627              Update_PMat_At_Given_Edge(mixt_tree->n_root->b[2],tree);
628            }
629        }
630      else
631        {
632          Update_PMat_At_Given_Edge(mixt_b,mixt_tree);
633        }
634
635      if(!cpy_mixt_b)
636        {
637          if(mixt_tree->n_root)
638            {
639              MIXT_Post_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree);
640              MIXT_Post_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree);
641
642              MIXT_Update_P_Lk(mixt_tree,mixt_tree->n_root->b[1],mixt_tree->n_root);
643              MIXT_Update_P_Lk(mixt_tree,mixt_tree->n_root->b[2],mixt_tree->n_root);
644
645              if(tree->both_sides == YES)
646                {
647                  MIXT_Pre_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree);             
648                  MIXT_Pre_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree);
649                }
650            }
651          else
652            {
653              MIXT_Post_Order_Lk(mixt_tree->a_nodes[0],mixt_tree->a_nodes[0]->v[0],mixt_tree);
654              if(mixt_tree->both_sides == YES)
655                MIXT_Pre_Order_Lk(mixt_tree->a_nodes[0],
656                                  mixt_tree->a_nodes[0]->v[0],
657                                  mixt_tree);
658            }
659        }
660     
661
662      if(!cpy_mixt_b) 
663        {
664          if(mixt_tree->n_root) mixt_b = (mixt_tree->n_root->v[1]->tax == NO)?(mixt_tree->n_root->b[2]):(mixt_tree->n_root->b[1]);
665          else                  mixt_b = mixt_tree->a_nodes[0]->b[0];
666        }
667
668      sum_scale_left_cat = (phydbl *)mCalloc(MAX(mixt_tree->mod->ras->n_catg,mixt_tree->mod->n_mixt_classes),sizeof(phydbl));
669      sum_scale_rght_cat = (phydbl *)mCalloc(MAX(mixt_tree->mod->ras->n_catg,mixt_tree->mod->n_mixt_classes),sizeof(phydbl));
670     
671      r_mat_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->r_mat_weight);
672      e_frq_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->e_frq_weight);
673      sum_probas       = MIXT_Get_Sum_Of_Probas_Across_Mixtures(r_mat_weight_sum, e_frq_weight_sum, mixt_tree);
674     
675      mixt_tree->c_lnL = .0;
676      dim1 = mixt_tree->mod->ns;
677      dim2 = mixt_tree->mod->ns;
678     
679      For(site,mixt_tree->n_pattern)
680        {
681          b    = mixt_b->next;         
682          tree = mixt_tree->next;
683         
684
685          /*! Skip calculations if model has zero rate */
686          while(tree->mod->ras->invar == YES) 
687            {
688              tree = tree->next;
689              b    = b->next;
690              if(!tree || tree->is_mixt_tree == YES)
691                {
692                  PhyML_Printf("\n== %p",(void *)tree);
693                  PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__);
694                  Exit("\n");
695                }
696            }
697         
698          ambiguity_check = -1;
699          state           = -1;
700         
701          if((b->rght->tax)                   && 
702             (!mixt_tree->mod->s_opt->greedy) &&
703             (mixt_tree->data->wght[site] > SMALL))
704            {
705              ambiguity_check = b->rght->c_seq->is_ambigu[site];             
706              if(!ambiguity_check) state = b->rght->c_seq->d_state[site];
707            }
708
709                   
710          /*! For all the classes of the mixture */
711          do
712            {
713              if(tree->is_mixt_tree)
714                {
715                  tree = tree->next;
716                  b    = b->next;
717                }
718             
719              tree->curr_site        = site;
720              tree->apply_lk_scaling = NO;
721             
722              if(!(tree->mod->ras->invar == YES && mixt_tree->is_mixt_tree == YES) &&
723                 (tree->data->wght[tree->curr_site] > SMALL)) 
724                {                 
725                  site_lk_cat = .0;
726                 
727                  if((b->rght->tax) && (!tree->mod->s_opt->greedy))
728                    {
729                      if(!ambiguity_check)
730                        {
731                          sum = .0;
732                          For(l,tree->mod->ns)
733                            {
734                              sum +=
735                                b->Pij_rr[state*dim2+l] *
736                                b->p_lk_left[site*dim1+l];
737                            }
738                         
739                          site_lk_cat += sum * tree->mod->e_frq->pi->v[state];
740                        }
741                      else
742                        {
743                          For(k,tree->mod->ns)
744                            {
745                              sum = .0;
746                              if(b->p_lk_tip_r[site*dim2+k] > .0)
747                                {
748                                  For(l,tree->mod->ns)
749                                    {
750                                      sum +=
751                                        b->Pij_rr[k*dim2+l] *
752                                        b->p_lk_left[site*dim1+l];
753                                    }
754                                 
755                                  site_lk_cat +=
756                                    sum *
757                                    tree->mod->e_frq->pi->v[k] *
758                                    b->p_lk_tip_r[site*dim2+k];
759                                }
760                            }
761                        }
762                    }
763                  else
764                    {
765                      For(k,tree->mod->ns)
766                        {
767                          sum = .0;
768                          if(b->p_lk_rght[site*dim1+k] > .0)
769                            {
770                              For(l,tree->mod->ns)
771                                {
772                                  sum +=
773                                    b->Pij_rr[k*dim2+l] *
774                                    b->p_lk_left[site*dim1+l];
775                                }
776                             
777                              site_lk_cat +=
778                                sum *
779                                tree->mod->e_frq->pi->v[k] *
780                                b->p_lk_rght[site*dim1+k];
781                            }
782                        }
783                    }
784                  tree->site_lk_cat[0] = site_lk_cat;
785                }
786              tree = tree->next;
787              b    = b->next;
788            }
789          while(tree && tree->is_mixt_tree == NO);
790         
791         
792          max_sum_scale =  (phydbl)BIG;
793          min_sum_scale = -(phydbl)BIG;
794         
795          tree  = mixt_tree->next;
796          b     = mixt_b->next;
797          class = 0;
798          do
799            {
800              if(tree->mod->ras->invar == YES) 
801                {
802                  tree = tree->next;
803                  b    = b->next;
804                  if(!(tree && tree->is_mixt_tree == NO)) break;
805                }
806             
807              sum_scale_left_cat[class] =
808                (b->sum_scale_left)?
809                (b->sum_scale_left[site]):
810                (0.0);                 
811             
812              sum_scale_rght_cat[class] =
813                (b->sum_scale_rght)?
814                (b->sum_scale_rght[site]):
815                (0.0);
816             
817              sum = sum_scale_left_cat[class] + sum_scale_rght_cat[class];
818             
819              if(sum < .0)
820                {
821                  PhyML_Printf("\n== sum = %G",sum);
822                  PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__);
823                  Warn_And_Exit("\n");
824                }
825             
826              tmp = sum + ((phydbl)LOGBIG - LOG(tree->site_lk_cat[0]))/(phydbl)LOG2;
827              if(tmp < max_sum_scale) max_sum_scale = tmp; /* min of the maxs */
828             
829              tmp = sum + ((phydbl)LOGSMALL - LOG(tree->site_lk_cat[0]))/(phydbl)LOG2;
830              if(tmp > min_sum_scale) min_sum_scale = tmp; /* max of the mins */
831             
832              class++;
833             
834              tree = tree->next;
835              b    = b->next;
836            }
837          while(tree && tree->is_mixt_tree == NO);
838         
839          tree = NULL; /*! For debugging purpose */
840         
841          if(min_sum_scale > max_sum_scale) min_sum_scale = max_sum_scale;
842         
843          fact_sum_scale = (int)((max_sum_scale + min_sum_scale) / 2);         
844         
845         
846          /*! Populate the mixt_tree->site_lk_cat[class] table after
847            scaling */
848         
849          tree  = mixt_tree->next;
850          b     = mixt_b->next;
851          class = 0;
852         
853          do
854            {
855              if(tree->mod->ras->invar == YES) 
856                {
857                  tree = tree->next;
858                  b    = b->next;
859                  if(!(tree && tree->is_mixt_tree == NO)) break;
860                }
861             
862              exponent = -(sum_scale_left_cat[class]+sum_scale_rght_cat[class])+fact_sum_scale;
863              site_lk_cat = tree->site_lk_cat[0];
864              Rate_Correction(exponent,&site_lk_cat,mixt_tree);
865              mixt_tree->site_lk_cat[class] = site_lk_cat;
866              tree->site_lk_cat[0] = site_lk_cat;
867              class++;
868             
869              tree = tree->next;
870              b    = b->next;
871            }
872          while(tree && tree->is_mixt_tree == NO);
873         
874          tree    = mixt_tree->next;
875          b       = mixt_b->next;
876          class   = 0;
877          site_lk = .0;
878         
879          do
880            {
881              if(tree->mod->ras->invar == YES) 
882                {
883                  tree = tree->next;
884                  b    = b->next;
885                  if(!(tree && tree->is_mixt_tree == NO)) break;
886                }
887             
888              site_lk +=
889                mixt_tree->site_lk_cat[class] *
890                mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number] *
891                tree->mod->r_mat_weight->v / r_mat_weight_sum *
892                tree->mod->e_frq_weight->v / e_frq_weight_sum /
893                sum_probas;
894
895              /* mixt_tree->site_lk_cat[class] * */
896              /* mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number]; */
897             
898              /* printf("\n. %f %f %f %f ", */
899              /*        tree->mod->r_mat_weight->v,r_mat_weight_sum, */
900              /*        tree->mod->e_frq_weight->v,e_frq_weight_sum); */
901             
902              tree = tree->next;
903              b    = b->next;
904              class++;
905            }
906          while(tree && tree->is_mixt_tree == NO);
907         
908          /* Scaling for invariants */
909          if(mixt_tree->mod->ras->invar == YES)
910            {
911              num_prec_issue = NO;
912             
913              tree = mixt_tree->next;
914              while(tree->mod->ras->invar == NO)
915                {
916                  tree = tree->next;
917                  if(!tree || tree->is_mixt_tree == YES)
918                    {
919                      PhyML_Printf("\n== tree: %p",tree);
920                      PhyML_Printf("\n== Err in file %s at line %d",__FILE__,__LINE__);
921                      Exit("\n");
922                    }
923                }
924             
925              tree->apply_lk_scaling = YES;
926             
927              /*! 'tree' will give the correct state frequencies (as opposed to mixt_tree */ 
928              inv_site_lk = Invariant_Lk(&fact_sum_scale,site,&num_prec_issue,tree); 
929             
930              if(num_prec_issue == YES) // inv_site_lk >> site_lk
931                {
932                  site_lk = inv_site_lk * mixt_tree->mod->ras->pinvar->v;
933                }
934              else
935                {
936                  site_lk = site_lk * (1. - mixt_tree->mod->ras->pinvar->v) + inv_site_lk * mixt_tree->mod->ras->pinvar->v;
937                }
938            }
939         
940          log_site_lk = LOG(site_lk) - (phydbl)LOG2 * fact_sum_scale;
941         
942         
943          int mixt_class = 0;
944          int rate_class = 0;
945          For(rate_class,mixt_tree->mod->ras->n_catg) 
946            {
947              mixt_class = 0;
948              tree = mixt_tree->next;
949              do
950                {
951                  if(tree->mod->ras->parent_class_number == rate_class)
952                    {
953                      mixt_tree->log_site_lk_cat[rate_class][site] += 
954                        // TO DO: add correct weight here
955                        LOG(mixt_tree->site_lk_cat[mixt_class]) - 
956                        (phydbl)LOG2 * fact_sum_scale;                                             
957                      break;
958                    }
959                  mixt_class++;
960                  tree = tree->next;
961                }
962              while(tree && tree->is_mixt_tree == NO);
963            }
964         
965          if(isinf(log_site_lk) || isnan(log_site_lk))
966            {
967              PhyML_Printf("\n== Site = %d",site);
968              PhyML_Printf("\n== Invar = %d",mixt_tree->data->invar[site]);
969              PhyML_Printf("\n== Mixt = %d",mixt_tree->is_mixt_tree);
970              PhyML_Printf("\n== Lk = %G LOG(Lk) = %f < %G",site_lk,log_site_lk,-BIG);
971              For(class,mixt_tree->mod->ras->n_catg) PhyML_Printf("\n== rr=%f p=%f",mixt_tree->mod->ras->gamma_rr->v[class],mixt_tree->mod->ras->gamma_r_proba->v[class]);
972              PhyML_Printf("\n== Pinv = %G",mixt_tree->mod->ras->pinvar->v);
973              PhyML_Printf("\n== Bl mult = %G",mixt_tree->mod->br_len_multiplier->v);
974              PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__);
975              Exit("\n");
976            }
977         
978          mixt_tree->cur_site_lk[site] = log_site_lk;
979         
980          /* Multiply log likelihood by the number of times this site pattern is found in the data */
981          mixt_tree->c_lnL_sorted[site] = mixt_tree->data->wght[site]*log_site_lk;
982         
983          mixt_tree->c_lnL += mixt_tree->data->wght[site]*log_site_lk;
984          /*   tree->sum_min_sum_scale += (int)tree->data->wght[site]*min_sum_scale; */
985         
986        }
987     
988      Free(sum_scale_left_cat);
989      Free(sum_scale_rght_cat);
990     
991      mixt_tree = mixt_tree->next_mixt;
992      mixt_b    = mixt_b->next_mixt;
993    }
994  while(mixt_tree);
995 
996  mixt_tree = cpy_mixt_tree;
997  mixt_b    = cpy_mixt_b;
998
999  sum_lnL = .0;
1000  do
1001    {
1002      sum_lnL += mixt_tree->c_lnL;
1003      mixt_tree = mixt_tree->next_mixt;
1004    }
1005  while(mixt_tree);
1006
1007  mixt_tree = cpy_mixt_tree;
1008  do
1009    {
1010      mixt_tree->c_lnL = sum_lnL;
1011      mixt_tree = mixt_tree->next_mixt;
1012    }
1013  while(mixt_tree);
1014
1015  mixt_tree = cpy_mixt_tree;
1016 
1017  return mixt_tree->c_lnL;
1018}
1019
1020//////////////////////////////////////////////////////////////
1021//////////////////////////////////////////////////////////////
1022
1023void MIXT_Update_Eigen(t_mod *mixt_mod)
1024{
1025  t_mod *mod;
1026
1027  mod = mixt_mod;
1028
1029  do
1030    {
1031      if(mod->is_mixt_mod) mod = mod->next;
1032      Update_Eigen(mod);
1033      mod = mod->next;
1034    }
1035  while(mod);
1036 
1037}
1038
1039//////////////////////////////////////////////////////////////
1040//////////////////////////////////////////////////////////////
1041
1042void MIXT_Update_P_Lk(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d)
1043{
1044  t_tree *tree;
1045  t_edge *b;
1046  t_node *d;
1047
1048  tree = mixt_tree;
1049  b    = mixt_b;
1050  d    = mixt_d;
1051
1052  do
1053    {
1054      if(tree->is_mixt_tree) 
1055        {
1056          tree = tree->next;
1057          b    = b->next;
1058          d    = d->next;
1059        }
1060
1061      Update_P_Lk(tree,b,d);
1062
1063      tree = tree->next;
1064      b    = b->next;
1065      d    = d->next;
1066
1067    }
1068  while(tree);
1069
1070}
1071
1072//////////////////////////////////////////////////////////////
1073//////////////////////////////////////////////////////////////
1074
1075void MIXT_Update_PMat_At_Given_Edge(t_edge *mixt_b, t_tree *mixt_tree)
1076{
1077  t_tree *tree;
1078  t_edge *b;
1079
1080  tree = mixt_tree;
1081  b    = mixt_b;
1082
1083  do
1084    {
1085      if(tree->is_mixt_tree) 
1086        {
1087          tree = tree->next;
1088          b    = b->next;
1089        }
1090     
1091      if(tree->mod->ras->invar == NO) Update_PMat_At_Given_Edge(b,tree);
1092
1093      tree = tree->next;
1094      b    = b->next;
1095    }
1096  while(tree);
1097
1098}
1099
1100//////////////////////////////////////////////////////////////
1101//////////////////////////////////////////////////////////////
1102
1103int *MIXT_Get_Number_Of_Classes_In_All_Mixtures(t_tree *mixt_tree)
1104{
1105  int *n_catg;
1106  t_tree *tree;
1107  int class;
1108 
1109  if(mixt_tree->is_mixt_tree == YES)
1110    {
1111      n_catg = NULL;
1112      tree = mixt_tree;
1113      class = 0;
1114      do
1115        {
1116          if(!class) n_catg = (int *)mCalloc(1,sizeof(int));
1117          else       n_catg = (int *)realloc(n_catg,(class+1)*sizeof(int));
1118         
1119          tree = tree->next;
1120         
1121          n_catg[class]=0;
1122          do
1123            {
1124              n_catg[class]++;
1125              tree = tree->next;
1126            }
1127          while(tree && tree->is_mixt_tree == NO);
1128         
1129          class++;
1130        }
1131      while(tree);
1132    }
1133  else
1134    {
1135      n_catg = (int *)mCalloc(1,sizeof(int));
1136      n_catg[0] = mixt_tree->mod->ras->n_catg;
1137    }
1138  return(n_catg);
1139}
1140
1141//////////////////////////////////////////////////////////////
1142//////////////////////////////////////////////////////////////
1143
1144t_tree **MIXT_Record_All_Mixtures(t_tree *mixt_tree)
1145{
1146  t_tree **tree_list;
1147  int n_trees;
1148  t_tree *tree;
1149
1150  tree_list = NULL;
1151  n_trees   = 0;
1152  tree      = mixt_tree;
1153  do
1154    {
1155      if(!tree_list) tree_list = (t_tree **)mCalloc(1,sizeof(t_tree *));
1156      else           tree_list = (t_tree **)realloc(tree_list,(n_trees+1)*sizeof(t_tree *));
1157     
1158      tree_list[n_trees] = tree;
1159      n_trees++;
1160      tree = tree->next;
1161    }
1162  while(tree);
1163
1164  tree_list = (t_tree **)realloc(tree_list,(n_trees+1)*sizeof(t_tree *));
1165  tree_list[n_trees] = NULL;
1166
1167  return(tree_list);
1168}
1169
1170//////////////////////////////////////////////////////////////
1171//////////////////////////////////////////////////////////////
1172
1173void MIXT_Break_All_Mixtures(int *c_max, t_tree *mixt_tree)
1174{
1175  t_tree *tree;
1176  int c,i,n;
1177 
1178  if(mixt_tree->is_mixt_tree == NO) return;
1179
1180  c = 0;
1181  n = -1;
1182  tree = mixt_tree;
1183  do
1184    {
1185      if(tree->is_mixt_tree == YES) 
1186        {
1187          c = 0;
1188          n++;
1189          tree = tree->next;
1190        }
1191
1192      if(c == (c_max[n]-1)           && 
1193         tree->next != NULL          && 
1194         tree->next->is_mixt_tree == NO) 
1195        {
1196          if(tree->mixt_tree->next_mixt == NULL)
1197            {
1198              tree->next = NULL;
1199              For(i,2*tree->n_otu-1) tree->a_edges[i]->next  = NULL;
1200              For(i,2*tree->n_otu-1) tree->a_nodes[i]->next  = NULL;
1201              For(i,2*tree->n_otu-2) tree->spr_list[i]->next = NULL;
1202            }
1203          else
1204            {
1205              tree->next = tree->mixt_tree->next_mixt;
1206              For(i,2*tree->n_otu-1) tree->a_edges[i]->next  = tree->mixt_tree->next_mixt->a_edges[i];
1207              For(i,2*tree->n_otu-1) tree->a_nodes[i]->next  = tree->mixt_tree->next_mixt->a_nodes[i];
1208              For(i,2*tree->n_otu-2) tree->spr_list[i]->next = tree->mixt_tree->next_mixt->spr_list[i];
1209            }
1210        }
1211
1212      tree = tree->next;
1213      c++;
1214    }
1215  while(tree);
1216}
1217
1218//////////////////////////////////////////////////////////////
1219//////////////////////////////////////////////////////////////
1220
1221void MIXT_Reconnect_All_Mixtures(t_tree **tree_list, t_tree *mixt_tree)
1222{
1223  t_tree *tree;
1224  int n_trees;
1225
1226  if(mixt_tree->is_mixt_tree == NO) return;
1227
1228  tree = mixt_tree;
1229  n_trees = 0;
1230  do
1231    {
1232      tree = tree_list[n_trees];
1233      if(tree->is_mixt_tree == NO) tree->next = tree_list[n_trees+1];
1234      n_trees++;
1235      tree = tree->next;
1236    }
1237  while(tree);
1238 
1239  MIXT_Chain_All(mixt_tree);
1240}
1241
1242//////////////////////////////////////////////////////////////
1243//////////////////////////////////////////////////////////////
1244
1245int *MIXT_Record_Has_Invariants(t_tree *mixt_tree)
1246{
1247  int *has_invariants;
1248  t_tree *tree;
1249  int n_trees;
1250
1251  has_invariants = NULL;
1252  tree = mixt_tree;
1253  n_trees = 0;
1254  do
1255    {
1256      if(!n_trees) has_invariants = (int *)mCalloc(1,sizeof(int));
1257      else         has_invariants = (int *)realloc(has_invariants,(n_trees+1)*sizeof(int));
1258      has_invariants[n_trees] = (tree->mod->ras->invar == YES)?1:0;
1259      n_trees++;
1260      tree = tree->next;
1261    }
1262  while(tree);
1263
1264  return(has_invariants);
1265}
1266
1267//////////////////////////////////////////////////////////////
1268//////////////////////////////////////////////////////////////
1269
1270void MIXT_Reset_Has_Invariants(int *has_invariants, t_tree *mixt_tree)
1271{
1272  t_tree *tree;
1273  int n_trees;
1274
1275  tree = mixt_tree;
1276  n_trees = 0;
1277  do
1278    {
1279      tree->mod->ras->invar = has_invariants[n_trees];
1280      n_trees++;
1281      tree = tree->next;
1282    }
1283  while(tree);
1284
1285}
1286
1287//////////////////////////////////////////////////////////////
1288//////////////////////////////////////////////////////////////
1289
1290void MIXT_Check_Invar_Struct_In_Each_Partition_Elem(t_tree *mixt_tree)
1291{
1292  if(mixt_tree->is_mixt_tree == NO) return;
1293  else
1294    {
1295      t_tree *tree;
1296      int n_inv;
1297     
1298      n_inv = 0;
1299      tree = mixt_tree;
1300      do
1301        {
1302          if(tree->is_mixt_tree) 
1303            {
1304              tree  = tree->next;
1305              n_inv = 0;
1306            }
1307
1308          if(tree->mod->ras->invar == YES) n_inv++; 
1309
1310          if(n_inv > 1)
1311            {
1312              PhyML_Printf("\n== Found %d classes of the mixture for file '%s' set to",n_inv,tree->mixt_tree->io->in_align_file);
1313              PhyML_Printf("\n== invariable. Only one such class per mixture is allowed.");
1314              PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__);
1315              Warn_And_Exit("\n");
1316            }
1317
1318          if(tree->mixt_tree->mod->ras->invar == NO && 
1319             tree->mod->ras->invar == YES)
1320            {
1321              PhyML_Printf("\n== Unexpected settings for 'siterates' in a partition element (file '%s')",tree->mixt_tree->io->in_align_file);
1322              PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__);
1323              Warn_And_Exit("\n");
1324            }
1325         
1326          tree = tree->next;
1327        }
1328      while(tree);
1329    }
1330}
1331
1332//////////////////////////////////////////////////////////////
1333//////////////////////////////////////////////////////////////
1334
1335void MIXT_Check_RAS_Struct_In_Each_Partition_Elem(t_tree *mixt_tree)
1336{
1337  if(mixt_tree->is_mixt_tree == NO) return;
1338  else
1339    {
1340      t_tree *tree;
1341      int n_classes;
1342     
1343      n_classes = 0;
1344      tree = mixt_tree;
1345      do
1346        {
1347          if(tree->is_mixt_tree) 
1348            {
1349              if(tree->mod->ras->invar == YES)
1350                {
1351                  if(tree->next->mod->ras->invar == NO)
1352                    {
1353                      PhyML_Printf("\n== The invariant site class has to be the first element in");
1354                      PhyML_Printf("\n== each <mixtureelem> component. Please amend you XML");
1355                      PhyML_Printf("\n== file accordingly.\n");
1356                      Exit("\n.");
1357                    }
1358                }
1359              tree  = tree->next;
1360              n_classes = 0;
1361            }
1362
1363          if(tree && tree->mod->ras->invar == NO) n_classes++;
1364
1365          if((tree->next && tree->next->is_mixt_tree == YES) || (!tree->next)) /*! current tree is the last element of this mixture */
1366            {
1367              if(n_classes < tree->mixt_tree->mod->ras->n_catg)
1368                {                 
1369                  PhyML_Printf("\n== %d class%s found in 'partitionelem' for file '%s' while",
1370                               n_classes,
1371                               (n_classes>1)?"es\0":"\0",
1372                               tree->mixt_tree->io->in_align_file);
1373                  PhyML_Printf("\n== the corresponding 'siterates' element defined %d class%s.",
1374                               tree->mixt_tree->mod->ras->n_catg,
1375                               (tree->mixt_tree->mod->ras->n_catg>1)?"es\0":"\0");
1376                  PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__);
1377                  Warn_And_Exit("\n");
1378                }
1379            }
1380
1381          tree = tree->next;
1382        }
1383      while(tree);
1384    }
1385}
1386
1387//////////////////////////////////////////////////////////////
1388//////////////////////////////////////////////////////////////
1389
1390void MIXT_Prune_Subtree(t_node *mixt_a, t_node *mixt_d, t_edge **mixt_target, t_edge **mixt_residual, t_tree *mixt_tree)
1391{
1392  t_node *a,*d;
1393  t_edge *target, *residual;
1394  t_tree *tree;
1395 
1396  MIXT_Turn_Branches_OnOff(OFF,mixt_tree);
1397
1398  tree     = mixt_tree;
1399  a        = mixt_a;
1400  d        = mixt_d;
1401  target   = *mixt_target;
1402  residual = *mixt_residual;
1403
1404  do
1405    {     
1406      if(tree->is_mixt_tree) 
1407        {
1408          tree     = tree->next;
1409          a        = a->next;
1410          d        = d->next;
1411          target   = target->next;
1412          residual = residual->next;
1413        }
1414
1415      Prune_Subtree(a,d,&target,&residual,tree);
1416     
1417      tree     = tree->next;
1418      a        = a->next;
1419      d        = d->next;
1420      target   = target->next;
1421      residual = residual->next;
1422    }
1423  while(tree && tree->is_mixt_tree == NO);
1424
1425  if(tree) Prune_Subtree(a,d,&target,&residual,tree);
1426
1427  /*! Turn branches of this mixt_tree to ON after recursive call
1428    to Prune_Subtree such that, if branches of mixt_tree->next
1429    point to those of mixt_tree, they are set to OFF when calling
1430    Prune */
1431  MIXT_Turn_Branches_OnOff(ON,mixt_tree);
1432
1433}
1434
1435//////////////////////////////////////////////////////////////
1436//////////////////////////////////////////////////////////////
1437
1438void MIXT_Graft_Subtree(t_edge *mixt_target, t_node *mixt_link, t_edge *mixt_residual, t_tree *mixt_tree)
1439{
1440  t_edge *target,*residual;
1441  t_node *link;
1442  t_tree *tree;
1443
1444  MIXT_Turn_Branches_OnOff(OFF,mixt_tree);
1445
1446  tree     = mixt_tree;
1447  target   = mixt_target;
1448  residual = mixt_residual;
1449  link     = mixt_link;
1450 
1451  do
1452    {
1453      if(tree->is_mixt_tree)
1454        {
1455          tree     = tree->next;
1456          target   = target->next;
1457          residual = residual->next;
1458          link     = link->next;
1459        }
1460
1461      Graft_Subtree(target,link,residual,tree);
1462
1463      tree     = tree->next;
1464      target   = target->next;
1465      residual = residual->next;
1466      link     = link->next;
1467    }
1468  while(tree && tree->is_mixt_tree == NO);
1469
1470  if(tree) Graft_Subtree(target,link,residual,tree);
1471
1472  /*! Turn branches of this mixt_tree to ON after recursive call
1473    to Graft_Subtree such that, if branches of mixt_tree->next
1474    point to those of mixt_tree, they are set to OFF when calling
1475    Graft */
1476  MIXT_Turn_Branches_OnOff(ON,mixt_tree);
1477}
1478
1479//////////////////////////////////////////////////////////////
1480//////////////////////////////////////////////////////////////
1481
1482void MIXT_Br_Len_Brent(phydbl prop_min,
1483                       phydbl prop_max,
1484                       t_edge *mixt_b, 
1485                       t_tree *mixt_tree)
1486{
1487  t_tree *tree;
1488  t_edge *b;
1489
1490  b    = mixt_b;
1491  tree = mixt_tree;
1492 
1493  do
1494    {
1495      if(tree->is_mixt_tree)
1496        {
1497          tree = tree->next;
1498          b    = b->next;
1499        }
1500     
1501      Br_Len_Brent(prop_min,prop_max,b,tree);
1502
1503      b->l->onoff = OFF;     
1504      tree = tree->next;
1505      b    = b->next;
1506    }
1507  while(tree);
1508
1509  tree = mixt_tree;
1510  do
1511    {     
1512      MIXT_Turn_Branches_OnOff(ON,tree);
1513      tree = tree->next_mixt;
1514    }
1515  while(tree);
1516}
1517
1518//////////////////////////////////////////////////////////////
1519//////////////////////////////////////////////////////////////
1520
1521void MIXT_Prepare_Tree_For_Lk(t_tree *mixt_tree)
1522{
1523  t_tree *tree;
1524 
1525  tree = mixt_tree;
1526  do
1527    {
1528      if(tree->is_mixt_tree) tree = tree->next;
1529      Prepare_Tree_For_Lk(tree);     
1530      tree = tree->next;
1531    }
1532  while(tree && tree->is_mixt_tree == NO);
1533
1534  if(tree) Prepare_Tree_For_Lk(tree);
1535}
1536
1537//////////////////////////////////////////////////////////////
1538//////////////////////////////////////////////////////////////
1539
1540void MIXT_Br_Len_Involving_Invar(t_tree *mixt_tree)
1541{
1542  int i;
1543  scalar_dbl *l;
1544
1545  For(i,2*mixt_tree->n_otu-1) 
1546    {
1547      l = mixt_tree->a_edges[i]->l;
1548      do
1549        {
1550          l->v *= (1.-mixt_tree->mod->ras->pinvar->v);
1551          l = l->next;
1552        }
1553      while(l);
1554    }
1555}
1556
1557//////////////////////////////////////////////////////////////
1558//////////////////////////////////////////////////////////////
1559
1560void MIXT_Br_Len_Not_Involving_Invar(t_tree *mixt_tree)
1561{
1562  int i;
1563  scalar_dbl *l;
1564
1565  For(i,2*mixt_tree->n_otu-1) 
1566    {
1567      l = mixt_tree->a_edges[i]->l;
1568      do
1569        {
1570          l->v /= (1.-mixt_tree->mod->ras->pinvar->v);
1571          l = l->next;
1572        }
1573      while(l);
1574    }
1575}
1576
1577//////////////////////////////////////////////////////////////
1578//////////////////////////////////////////////////////////////
1579
1580phydbl MIXT_Unscale_Br_Len_Multiplier_Tree(t_tree *mixt_tree)
1581{
1582  int i;
1583  scalar_dbl *l;
1584
1585  For(i,2*mixt_tree->n_otu-1) 
1586    {
1587      l = mixt_tree->a_edges[i]->l;
1588      do
1589        {
1590          l->v /= mixt_tree->mod->br_len_multiplier->v;
1591          l = l->next;
1592        }
1593      while(l);
1594    }
1595  return(-1);
1596}
1597
1598//////////////////////////////////////////////////////////////
1599//////////////////////////////////////////////////////////////
1600
1601phydbl MIXT_Rescale_Br_Len_Multiplier_Tree(t_tree *mixt_tree)
1602{
1603  int i;
1604  scalar_dbl *l;
1605
1606  For(i,2*mixt_tree->n_otu-1) 
1607    {
1608      l = mixt_tree->a_edges[i]->l;
1609      do
1610        {
1611          l->v *= mixt_tree->mod->br_len_multiplier->v;
1612          l = l->next;
1613        }
1614      while(l);
1615    }
1616  return(-1);
1617}
1618
1619//////////////////////////////////////////////////////////////
1620//////////////////////////////////////////////////////////////
1621
1622phydbl MIXT_Rescale_Free_Rate_Tree(t_tree *mixt_tree)
1623{
1624  int i,side_effect,at_boundary;
1625  t_edge *b;
1626
1627  side_effect = NO;
1628  For(i,2*mixt_tree->n_otu-1)
1629    {
1630      b = mixt_tree->a_edges[i]->next;
1631
1632      at_boundary = NO;
1633      if(b->l->v > mixt_tree->mod->l_max-1.E-100 && b->l->v < mixt_tree->mod->l_max+1.E-100) at_boundary = YES;
1634      if(b->l->v > mixt_tree->mod->l_min-1.E-100 && b->l->v < mixt_tree->mod->l_min+1.E-100) at_boundary = YES;
1635     
1636      b->l->v *= mixt_tree->mod->ras->free_rate_mr->v;
1637     
1638      if(b->l->v > mixt_tree->mod->l_max && at_boundary == NO) side_effect = YES;
1639      if(b->l->v < mixt_tree->mod->l_min && at_boundary == NO) side_effect = YES;
1640    }
1641 
1642  return side_effect;
1643}
1644
1645//////////////////////////////////////////////////////////////
1646//////////////////////////////////////////////////////////////
1647
1648void MIXT_Set_Alias_Subpatt(int onoff, t_tree *mixt_tree)
1649{
1650  t_tree *tree;
1651
1652  tree = mixt_tree;
1653  do
1654    {
1655      tree->update_alias_subpatt = onoff;
1656      tree = tree->next;
1657    }
1658  while(tree);
1659}
1660
1661//////////////////////////////////////////////////////////////
1662//////////////////////////////////////////////////////////////
1663
1664void MIXT_Check_Single_Edge_Lens(t_tree *mixt_tree)
1665{
1666  t_tree *tree;
1667  int i;
1668
1669  tree = mixt_tree->next;
1670  do
1671    {
1672      if(tree->next && tree->next->is_mixt_tree == NO)
1673        {
1674          For(i,2*tree->n_otu-1)
1675            {
1676              if(tree->a_edges[i]->l != tree->next->a_edges[i]->l)
1677                {
1678                  PhyML_Printf("\n== %p %p",tree->a_edges[i]->l,tree->next->a_edges[i]->l);
1679                  PhyML_Printf("\n== Only one set of edge lengths is allowed ");
1680                  PhyML_Printf("\n== in a 'partitionelem'. Please fix your XML file.");
1681                  Exit("\n");
1682                }
1683            }
1684        }
1685      tree = tree->next;
1686    }
1687  while(tree && tree->next && tree->next->is_mixt_tree == NO);
1688}
1689
1690//////////////////////////////////////////////////////////////
1691//////////////////////////////////////////////////////////////
1692
1693int MIXT_Pars(t_edge *mixt_b, t_tree *mixt_tree)
1694{
1695  t_edge *b;
1696  t_tree *tree;
1697
1698  b    = mixt_b;
1699  tree = mixt_tree;
1700
1701  do
1702    {     
1703      b    = b->next_mixt;
1704      tree = tree->next_mixt;
1705     
1706      if(tree) 
1707        {
1708          Pars(b,tree);
1709          mixt_tree->c_pars += tree->c_pars; 
1710        }
1711    }
1712  while(tree);
1713
1714  tree = mixt_tree;
1715  do
1716    {
1717      tree->c_pars = mixt_tree->c_pars;     
1718      tree = tree->next_mixt;
1719    }
1720  while(tree);
1721 
1722  return(mixt_tree->c_pars);
1723}
1724
1725//////////////////////////////////////////////////////////////
1726//////////////////////////////////////////////////////////////
1727
1728void MIXT_Bootstrap(char *best_tree, xml_node *root)
1729{
1730  xml_node *n,*p_elem;
1731  char *bootstrap;
1732
1733  n = XML_Search_Node_Name("phyml",NO,root);
1734
1735  bootstrap = XML_Get_Attribute_Value(n,"bootstrap");
1736
1737  if(!bootstrap) return;
1738  else
1739    {
1740      int n_boot,i,j,k;
1741      xml_attr *boot_attr,*seqfile_attr,*out_attr,*boot_out_attr;
1742      char *orig_align,*boot_out_file_name,*xml_boot_file_name,*buff;
1743      FILE *boot_fp_in_align,*xml_boot_file_fp;
1744      option *io;
1745      align **boot_data,**orig_data;
1746      int position,elem;
1747      xml_node *boot_root;
1748      int pid;
1749      char *s;
1750
1751      orig_align = (char *)mCalloc(T_MAX_NAME,sizeof(char));
1752
1753      xml_boot_file_name = (char *)mCalloc(T_MAX_NAME,sizeof(char));
1754      strcpy(xml_boot_file_name,"phyml_boot_config.");
1755      pid = (int)getpid();
1756      sprintf(xml_boot_file_name+strlen(xml_boot_file_name),"%d",pid);
1757      strcat(xml_boot_file_name,".xml");
1758
1759      out_attr = XML_Search_Attribute(root,"outputfile");
1760      boot_out_file_name = (char *)mCalloc(T_MAX_NAME,sizeof(char));
1761      strcpy(boot_out_file_name,out_attr->value);
1762      s = XML_Get_Attribute_Value(root,"run.id");
1763      if(s)
1764        {
1765          strcat(boot_out_file_name,"_"); 
1766          strcat(boot_out_file_name,s); 
1767        }
1768
1769
1770
1771      n_boot = atoi(bootstrap);
1772     
1773      io = NULL;
1774      For(i,n_boot)
1775        {
1776          boot_root = XML_Copy_XML_Graph(root);
1777
1778          /*! Set the number of bootstrap repeats to 0
1779            in each generated XML file */
1780          boot_attr = XML_Search_Attribute(boot_root,"bootstrap");
1781          strcpy(boot_attr->value,"0");
1782
1783          /*! Set the output file name for each bootstrap analysis */
1784          boot_out_attr = XML_Search_Attribute(boot_root,"outputfile");         
1785          buff = (char *)mCalloc(T_MAX_NAME,sizeof(char));
1786          strcpy(buff,boot_out_attr->value);
1787          Free(boot_out_attr->value);
1788          boot_out_attr->value = buff;
1789          sprintf(boot_out_attr->value+strlen(boot_out_attr->value),"_boot.%d",pid);
1790
1791          p_elem = boot_root;
1792          elem   = 0;
1793          do
1794            {
1795              p_elem = XML_Search_Node_Name("partitionelem",YES,p_elem);
1796              if(!p_elem) break;
1797             
1798              io = (option *)Make_Input();
1799              Set_Defaults_Input(io);
1800
1801              /*! Get the original sequence file name and the corresponding
1802                attribute in the XML graph
1803              */
1804              seqfile_attr    = NULL;
1805              seqfile_attr    = XML_Search_Attribute(p_elem,"filename");
1806
1807              strcpy(orig_align,seqfile_attr->value);
1808
1809              /*! Open the original sequence file */
1810              io->fp_in_align = Openfile(orig_align,0);
1811             
1812              /*! Read in the original sequence file */
1813              orig_data       = Get_Seq(io);
1814              rewind(io->fp_in_align);
1815
1816
1817              /*! Read in the original sequence file and put
1818               it in 'boot_data' structure */
1819              boot_data       = Get_Seq(io);
1820
1821              fclose(io->fp_in_align);
1822             
1823              /*! Bootstrap resampling: sample from original and put in boot */
1824              For(j,boot_data[0]->len)
1825                {
1826                  position = Rand_Int(0,(int)(boot_data[0]->len-1.0));
1827                  For(k,io->n_otu)
1828                    {
1829                      boot_data[k]->state[j] = orig_data[k]->state[position];
1830                    }
1831                }
1832             
1833              /*! Modify the sequence file attribute in the original XML
1834                graph */
1835              buff = (char *)mCalloc(T_MAX_NAME,sizeof(char));
1836              Free(seqfile_attr->value);
1837              seqfile_attr->value = buff;
1838              sprintf(seqfile_attr->value,"%s_%d_%d",orig_align,elem,i);
1839
1840              /*! Open a new sequence file with the modified attribute name */
1841              boot_fp_in_align = Openfile(seqfile_attr->value,1);
1842             
1843              /*! Print the bootstrap data set in it */
1844              Print_Seq(boot_fp_in_align,boot_data,io->n_otu);
1845              fclose(boot_fp_in_align);
1846
1847
1848              Free_Seq(orig_data,io->n_otu);
1849              Free_Seq(boot_data,io->n_otu);
1850
1851
1852              Free_Input(io);
1853              elem++;
1854            }
1855          while(p_elem);
1856         
1857          /*! Open bootstrap XML file in writing mode */
1858          xml_boot_file_fp = Openfile(xml_boot_file_name,1);
1859
1860          /*! Write the bootstrap XML graph */
1861          XML_Write_XML_Graph(xml_boot_file_fp,boot_root);
1862          fclose(xml_boot_file_fp);
1863
1864          /*! Reconstruct the tree */
1865          PhyML_XML(xml_boot_file_name);
1866
1867          /*! Remove the bootstrap alignment files */
1868          p_elem = boot_root;
1869          do
1870            {
1871              p_elem = XML_Search_Node_Name("partitionelem",YES,p_elem);
1872              if(!p_elem) break;
1873              seqfile_attr = XML_Search_Attribute(p_elem,"filename");
1874              /* unlink(seqfile_attr->value); */
1875            }
1876          while(p_elem);
1877
1878          XML_Free_XML_Tree(boot_root);         
1879        }
1880
1881      Free(xml_boot_file_name);
1882      Free(orig_align);
1883      Free(boot_out_file_name);
1884    }
1885
1886}
1887
1888//////////////////////////////////////////////////////////////
1889//////////////////////////////////////////////////////////////
1890
1891void MIXT_Set_Pars_Thresh(t_tree *mixt_tree)
1892{
1893  t_tree *tree;
1894
1895  tree = mixt_tree;
1896  do
1897    {
1898      tree->mod->s_opt->pars_thresh = (tree->io->datatype == AA)?(15):(5);
1899      tree = tree->next_mixt;
1900    }
1901  while(tree);
1902}
1903
1904//////////////////////////////////////////////////////////////
1905//////////////////////////////////////////////////////////////
1906
1907phydbl MIXT_Get_Mean_Edge_Len(t_edge *mixt_b, t_tree *mixt_tree)
1908{
1909  phydbl sum;
1910  int n;
1911  t_tree *tree;
1912  t_edge *b;
1913
1914  b    = mixt_b;
1915  tree = mixt_tree;
1916  sum  = .0;
1917  n    = 0 ;
1918  do 
1919    {
1920      sum += b->l->v;
1921      n++;
1922      b    = b->next;
1923      tree = tree->next;
1924    }
1925  while(b);
1926 
1927  return(sum / (phydbl)n);
1928
1929}
1930
1931//////////////////////////////////////////////////////////////
1932//////////////////////////////////////////////////////////////
1933
1934phydbl MIXT_Get_Sum_Chained_Scalar_Dbl(scalar_dbl *s)
1935{
1936  scalar_dbl *s_buff;
1937  phydbl sum;
1938
1939  s_buff = s;
1940  sum = .0;
1941  do
1942    {
1943      sum += s_buff->v;
1944      s_buff = s_buff->next;
1945    }
1946  while(s_buff);
1947 
1948  return sum;
1949
1950}
1951
1952//////////////////////////////////////////////////////////////
1953//////////////////////////////////////////////////////////////
1954
1955phydbl MIXT_Get_Sum_Of_Probas_Across_Mixtures(phydbl r_mat_weight_sum, phydbl e_frq_weight_sum, t_tree *mixt_tree)
1956{
1957  t_tree *tree;
1958  phydbl sum;
1959
1960  sum = .0;
1961  tree = mixt_tree->next;
1962  do
1963    {
1964      sum += 
1965        mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number] *
1966        tree->mod->r_mat_weight->v / r_mat_weight_sum *
1967        tree->mod->e_frq_weight->v / e_frq_weight_sum;
1968     
1969      tree = tree->next; 
1970     
1971    }
1972  while(tree && tree->is_mixt_tree == NO);
1973
1974  return(sum); 
1975}
1976
1977//////////////////////////////////////////////////////////////
1978//////////////////////////////////////////////////////////////
1979
1980void MIXT_Set_Br_Len_Var(t_tree *mixt_tree)
1981{
1982  t_tree *tree;
1983
1984  tree = mixt_tree->next;
1985 
1986  do
1987    {
1988      Set_Br_Len_Var(tree);
1989      tree = tree->next;
1990    }
1991  while(tree);
1992 
1993}
1994//////////////////////////////////////////////////////////////
1995//////////////////////////////////////////////////////////////
1996
1997//////////////////////////////////////////////////////////////
1998//////////////////////////////////////////////////////////////
1999
2000//////////////////////////////////////////////////////////////
2001//////////////////////////////////////////////////////////////
2002
2003//////////////////////////////////////////////////////////////
2004//////////////////////////////////////////////////////////////
2005
2006//////////////////////////////////////////////////////////////
2007//////////////////////////////////////////////////////////////
2008
2009//////////////////////////////////////////////////////////////
2010//////////////////////////////////////////////////////////////
2011
2012
2013
Note: See TracBrowser for help on using the repository browser.