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

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

added most recent version of phyml

File size: 36.6 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
14/* Routines for molecular clock trees and molecular dating */
15
16
17#include "tiporder.h"
18
19//////////////////////////////////////////////////////////////
20//////////////////////////////////////////////////////////////
21
22
23/* int TIPO_main(int argc, char **argv) */
24/* { */
25/*   t_tree **list_tree,*ref_tree,*tree; */
26/*   FILE *fp_ref_tree,*fp_list_tree,*fp_coord,*ps_tree; */
27/*   int i,j,k; */
28/*   int n_trees; */
29/*   option *ref_io,*list_io; */
30/*   char **name_table; */
31/*   int r_seed; */
32
33/*   r_seed = time(NULL); */
34/*   srand(r_seed); */
35
36
37/*   ref_io  = (option *)Make_Input(); */
38/*   list_io = (option *)Make_Input(); */
39
40/*   fp_ref_tree  = (FILE *)fopen(argv[1],"r"); */
41/*   fp_list_tree = (FILE *)fopen(argv[2],"r"); */
42/*   fp_coord     = (FILE *)fopen(argv[3],"r"); */
43
44/*   if(!fp_ref_tree)  */
45/*     { */
46/*       PhyML_Printf("\n. Can't find %s",argv[1]); */
47/*       PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */
48/*       Warn_And_Exit(""); */
49/*     } */
50
51/*   if(!fp_list_tree)  */
52/*     { */
53/*       PhyML_Printf("\n. Can't find %s",argv[2]); */
54/*       PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */
55/*       Warn_And_Exit(""); */
56/*     } */
57
58/*   ref_io->fp_in_tree = fp_ref_tree; */
59/*   Read_Tree_File(ref_io); */
60/*   fclose(ref_io->fp_in_tree); */
61/*   ref_tree = ref_io->treelist->tree[0]; */
62/*   ref_tree->io = ref_io; */
63
64 
65/*   list_io->fp_in_tree = fp_list_tree; */
66/*   Read_Tree_File(list_io); */
67/*   fclose(list_io->fp_in_tree); */
68/*   list_tree = list_io->treelist->tree; */
69/*   n_trees = list_io->treelist->list_size; */
70/*   PhyML_Printf("\n. Read %d trees\n",n_trees); */
71
72/*   For(i,n_trees) list_tree[i]->io = list_io; */
73
74/*   name_table = (char **)mCalloc(ref_tree->n_otu,sizeof(char **)); */
75/*   For(i,ref_tree->n_otu) name_table[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); */
76
77
78/*   /\* Sort translation table such that tree->a_nodes[i]->name == tree->io->short_tax_name[i] for all i *\/ */
79/*   TIPO_Sort_Translation_Table(ref_tree); */
80
81/*   ref_tree->io->z_scores = (phydbl *)mCalloc(ref_tree->n_otu,sizeof(phydbl)); */
82
83/* /\*   TIPO_Read_Taxa_Zscores(fp_coord,ref_tree); *\/ */
84
85/*   For(i,ref_tree->n_otu) ref_tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord,ref_tree->a_nodes[i]->name,ref_tree); */
86
87/*   TIPO_Normalize_Zscores(ref_tree); */
88
89/*   /\* Find matching tips *\/ */
90/*   For(i,n_trees) */
91/*     { */
92/*       TIPO_Sort_Translation_Table(list_tree[i]); */
93
94/*       For(j,ref_tree->n_otu)  */
95/*      { */
96/*        For(k,ref_tree->n_otu)  */
97/*          { */
98/*            if(!strcmp(ref_io->long_tax_names[j],list_io->long_tax_names[k])) */
99/*              { */
100/*                list_tree[i]->a_nodes[k]->ext_node = ref_tree->a_nodes[j]; */
101/*                break; */
102/*              } */
103/*          } */
104/*        if(k == ref_tree->n_otu) */
105/*          { */
106/*            PhyML_Printf("\n. Could not find matching tips for \"%s\" (tree %d)",ref_tree->a_nodes[j]->name,i); */
107/*            PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */
108/*            Warn_And_Exit(""); */
109/*          } */
110/*      } */
111/*     } */
112
113/*   PhyML_Printf("\n. Getting ancestors"); fflush(NULL); */
114/*   Update_Ancestors(ref_tree->n_root,ref_tree->n_root->v[2],ref_tree); */
115/*   Update_Ancestors(ref_tree->n_root,ref_tree->n_root->v[1],ref_tree); */
116
117/*   For(i,n_trees)    */
118/*     { */
119/*       Update_Ancestors(list_tree[i]->n_root,list_tree[i]->n_root->v[2],list_tree[i]); */
120/*       Update_Ancestors(list_tree[i]->n_root,list_tree[i]->n_root->v[1],list_tree[i]); */
121/*       list_tree[i]->n_root->anc = NULL; */
122/*     } */
123
124/*   PhyML_Printf("\n. Getting bipartitions"); fflush(NULL); */
125
126/*   Free_Bip(ref_tree); */
127/*   Alloc_Bip(ref_tree); */
128/*   Get_Bip(ref_tree->a_nodes[0], */
129/*        ref_tree->a_nodes[0]->v[0], */
130/*        ref_tree); */
131
132/*   For(i,n_trees)  */
133/*     { */
134/*       if(!(i%10)) */
135/*       PhyML_Printf("\n. Getting bipartition for tree %d",i); */
136/*       Free_Bip(list_tree[i]); */
137/*       Alloc_Bip(list_tree[i]); */
138/*       Get_Bip(list_tree[i]->a_nodes[0], */
139/*            list_tree[i]->a_nodes[0]->v[0], */
140/*            list_tree[i]); */
141/*     } */
142
143
144/*   PhyML_Printf("\n. Getting tip ranks"); fflush(NULL); */
145/* /\*   TIPO_Get_Tips_Y_Rank(ref_tree); *\/ */
146
147/*   TIPO_Get_Tips_Y_Rank_From_Zscores(ref_tree); */
148
149/* /\*   PhyML_Printf("\n. Minimizing"); fflush(NULL); *\/ */
150/* /\*   TIPO_Minimize_Tip_Order_Score(n_trees,list_tree,ref_tree); *\/ */
151
152/*   PhyML_Printf("\n. N_OTU = %d",ref_tree->n_otu); */
153/*   TIPO_Untangle_Tree(ref_tree); */
154/*   PhyML_Printf("\n ** ORIGINAL %f",ref_tree->tip_order_score); */
155
156/* /\*   i = 0; *\/ */
157/* /\*   do *\/ */
158/* /\*     { *\/ */
159/* /\* /\\*       TIPO_Get_Tips_Y_Rank_From_Zscores(ref_tree); *\\/ *\/ */
160/* /\*       TIPO_Randomize_Tip_Y_Ranks(ref_tree); *\/ */
161/* /\*       TIPO_Untangle_Tree(ref_tree); *\/ */
162/* /\*       PhyML_Printf("\n ** %f",ref_tree->tip_order_score); *\/ */
163/* /\*       i++; *\/ */
164/* /\*     }while(i < 5000); *\/ */
165
166/*   Test_Node_Table_Consistency(ref_tree); */
167
168/*   ref_tree->ps_tree = DR_Make_Tdraw_Struct(ref_tree); */
169/*   DR_Get_Tree_Coord(ref_tree); */
170/*   For(j,ref_tree->n_otu)  */
171/*     { */
172/*       ref_tree->ps_tree->ycoord[j] =  */
173/*      (ref_tree->a_nodes[j]->y_rank/ref_tree->n_otu)* */
174/*      ref_tree->ps_tree->page_height; */
175/*     } */
176
177/*   ps_tree  = (FILE *)fopen("order_tree.ps","w"); */
178
179
180/*   list_io->z_scores = (phydbl *)mCalloc(ref_tree->n_otu,sizeof(phydbl)); */
181
182/*   DR_Print_Postscript_Header(1,ps_tree); */
183/*   For(i,n_trees) */
184/*     { */
185/*       tree = list_tree[i]; */
186
187/*       Test_Node_Table_Consistency(tree); */
188/*       tree->rates = RATES_Make_Rate_Struct(tree->n_otu); */
189/*       RATES_Init_Rate_Struct(tree->rates,tree->n_otu); */
190/*       TIMES_Least_Square_Node_Times(tree->e_root,tree); */
191/*       TIMES_Adjust_Node_Times(tree); */
192/*       RATES_Update_Cur_Bl(tree); */
193
194/*       tree->ps_tree = DR_Make_Tdraw_Struct(tree); */
195/*       DR_Init_Tdraw_Struct(tree->ps_tree); */
196/*       DR_Get_Tree_Box_Width(tree->ps_tree,tree); */
197/*       Dist_To_Root(tree->n_root,tree); */
198/*       tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree); */
199 
200/*       For(j,ref_tree->n_otu) tree->io->z_scores[j] = ref_tree->io->z_scores[tree->a_nodes[j]->ext_node->num]; */
201/*       TIPO_Get_Tips_Y_Rank_From_Zscores(tree); */
202/*       TIPO_Untangle_Tree(tree); */
203/*       For(j,ref_tree->n_otu) tree->ps_tree->ycoord[j] =  (tree->a_nodes[j]->y_rank/tree->n_otu)*tree->ps_tree->page_height; */
204
205/* /\*       For(j,ref_tree->n_otu) tree->ps_tree->ycoord[j] = ref_tree->ps_tree->ycoord[tree->a_nodes[j]->ext_node->num]; *\/ */
206/*       For(j,ref_tree->n_otu) list_io->z_scores[j] = ref_io->z_scores[tree->a_nodes[j]->ext_node->num]; */
207
208/*       DR_Get_Y_Coord(YES,tree->ps_tree,tree); */
209/*       DR_Get_X_Coord( NO,tree->ps_tree,tree); */
210
211/*       if(!i) DR_Print_Tree_Postscript(1,YES,ps_tree,tree); */
212/*       else   DR_Print_Tree_Postscript(1, NO,ps_tree,tree); */
213/*     } */
214/*   DR_Print_Postscript_EOF(ps_tree); */
215/*   fclose(ps_tree); */
216
217
218/*   ps_tree  = (FILE *)fopen("ref_tree.ps","w"); */
219
220/*   DR_Print_Postscript_Header(1,ps_tree); */
221/*   tree = ref_tree; */
222/*   tree->rates = RATES_Make_Rate_Struct(tree->n_otu); */
223/*   RATES_Init_Rate_Struct(tree->rates,tree->n_otu); */
224/*   TIMES_Least_Square_Node_Times(tree->e_root,tree); */
225/*   TIMES_Adjust_Node_Times(tree); */
226/*   RATES_Update_Cur_Bl(tree); */
227/*   DR_Init_Tdraw_Struct(tree->ps_tree); */
228/*   DR_Get_Tree_Box_Width(tree->ps_tree,tree); */
229/*   Dist_To_Root(tree->n_root,tree); */
230/*   tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree); */
231 
232/*   TIPO_Get_Tips_Y_Rank_From_Zscores(tree); */
233/* /\*   TIPO_Untangle_Tree(tree); *\/ */
234/*   For(j,tree->n_otu) tree->ps_tree->ycoord[j] =  (tree->a_nodes[j]->y_rank/tree->n_otu)*tree->ps_tree->page_height; */
235
236/*   DR_Get_Y_Coord(YES,tree->ps_tree,tree); */
237/*   DR_Get_X_Coord( NO,tree->ps_tree,tree); */
238/*   DR_Print_Tree_Postscript(1,YES,ps_tree,tree); */
239/*   DR_Print_Postscript_EOF(ps_tree); */
240/*   fclose(ps_tree); */
241
242
243/*   PhyML_Printf("\n"); */
244
245/*   fclose(fp_ref_tree); */
246/*   fclose(fp_list_tree); */
247/*   fclose(fp_coord); */
248/* } */ 
249
250int TIPO_main(int argc, char **argv)
251{
252  t_tree *tree;
253  option *io;
254  FILE *fp_tree_file, *fp_coord_file;
255  int i;
256
257/*   Rprintf("%s\n",tree_file_name[0]); */
258/*   Rprintf("%s\n",coord_file_name[0]); */
259
260
261  srand(time(NULL)); rand();
262
263
264  fp_tree_file  = (FILE *)fopen(argv[1],"r");
265  fp_coord_file = (FILE *)fopen(argv[2],"r");
266
267  io = (option *)Make_Input();
268  io->fp_in_tree = fp_tree_file;
269  Read_Tree_File(io);
270  tree = io->treelist->tree[0];
271  tree->io = io;
272
273  tree->io->z_scores = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl));
274
275  For(i,tree->n_otu) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->a_nodes[i]->name,1,tree);
276  /* TIPO_Normalize_Zscores(tree); */
277  Free_Bip(tree);
278  Alloc_Bip(tree);
279  Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
280  TIPO_Get_Tips_Y_Rank_From_Zscores(tree);
281  /* TIPO_Get_Tips_Y_Rank(tree); */
282 
283
284  tree->geo_mig_sd = 0.1;
285  Generic_Brent_Lk(&(tree->geo_mig_sd),
286                   1.E-3,1.E+2,1.E-6,
287                   100,NO,
288                   &Wrap_Geo_Lk,
289                   NULL,tree,NULL,NO);
290
291  PhyML_Printf("\n. sd=%f",tree->geo_mig_sd);
292
293
294  fclose(fp_tree_file);
295  fclose(fp_coord_file);
296
297  return 0;
298}
299
300//////////////////////////////////////////////////////////////
301//////////////////////////////////////////////////////////////
302
303/* Z_scores have already been recorder here */
304void TIPO_Get_Min_Number_Of_Tip_Permut(t_tree *tree)
305{
306  Update_Ancestors(tree->n_root,tree->n_root->v[2],tree);
307  Update_Ancestors(tree->n_root,tree->n_root->v[1],tree);
308
309  Free_Bip(tree);
310  Alloc_Bip(tree);
311  Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
312
313  TIPO_Get_Tips_Y_Rank_From_Zscores(tree);
314
315  TIPO_Untangle_Tree(tree);
316
317}
318
319//////////////////////////////////////////////////////////////
320//////////////////////////////////////////////////////////////
321
322
323void TIPO_Get_Tips_Y_Rank(t_tree *tree)
324{
325  phydbl curr_rank;
326
327  curr_rank = .0;
328  TIPO_Get_Tips_Y_Rank_Pre(tree->n_root,tree->n_root->v[2],&curr_rank,tree);
329  TIPO_Get_Tips_Y_Rank_Pre(tree->n_root,tree->n_root->v[1],&curr_rank,tree);
330 
331  if(curr_rank != tree->n_otu)
332    {
333      PhyML_Printf("\n. tree->n_otu = %d curr_rank = %d",tree->n_otu,curr_rank);
334      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
335      Warn_And_Exit("");
336    }
337}
338
339//////////////////////////////////////////////////////////////
340//////////////////////////////////////////////////////////////
341
342
343void TIPO_Get_Tips_Y_Rank_Pre(t_node *a, t_node *d, phydbl *curr_rank, t_tree *tree)
344{
345  if(d->tax) 
346    {
347      d->y_rank = *curr_rank;
348      *curr_rank += 1.;
349      return;
350    }
351  else
352    {
353      int i;
354      For(i,3)
355        {
356          if(d->v[i] != a && d->b[i] != tree->e_root)
357            {
358              TIPO_Get_Tips_Y_Rank_Pre(d,d->v[i],curr_rank,tree);
359            }
360        }
361    }
362}
363
364//////////////////////////////////////////////////////////////
365//////////////////////////////////////////////////////////////
366
367
368void TIPO_Get_All_Y_Rank(t_tree *tree)
369{
370  tree->sum_y_dist_sq = .0;
371  tree->sum_y_dist    = .0;
372  TIPO_Get_All_Y_Rank_Pre(tree->n_root,tree->n_root->v[2],tree);
373  TIPO_Get_All_Y_Rank_Pre(tree->n_root,tree->n_root->v[1],tree);
374  tree->n_root->y_rank = (tree->n_root->v[2]->y_rank+tree->n_root->v[1]->y_rank)/2.;
375  tree->n_root->y_rank_min = MIN(tree->n_root->v[2]->y_rank_min,tree->n_root->v[1]->y_rank_min);
376  tree->n_root->y_rank_max = MAX(tree->n_root->v[2]->y_rank_max,tree->n_root->v[1]->y_rank_max);
377}
378
379//////////////////////////////////////////////////////////////
380//////////////////////////////////////////////////////////////
381
382
383void TIPO_Get_All_Y_Rank_Pre(t_node *a, t_node *d, t_tree *tree)
384{
385  if(d->tax) 
386    {
387      d->y_rank_min = d->y_rank;
388      d->y_rank_max = d->y_rank;
389      return;
390    }
391  else
392    {
393      int i;
394      int dir1,dir2;
395      phydbl v1,v2;
396
397      For(i,3)
398        {
399          if(d->v[i] != a && d->b[i] != tree->e_root)
400            {
401              TIPO_Get_All_Y_Rank_Pre(d,d->v[i],tree);
402            }
403        }
404
405      dir1 = dir2 = -1;
406      For(i,3)
407        {
408          if(d->v[i] != a && d->b[i] != tree->e_root)
409            {
410              if(dir1 < 0) dir1 = i;
411              else         dir2 = i;
412            }
413        }
414
415      v1 = d->v[dir1]->y_rank;
416      v2 = d->v[dir2]->y_rank;
417
418      d->y_rank            = (v1+v2)/2.;
419      tree->sum_y_dist_sq += POW(v1-v2,2);
420      tree->sum_y_dist    += FABS(v1-v2);
421      d->y_rank_min        = MIN(d->v[dir1]->y_rank_min,d->v[dir2]->y_rank_min);
422      d->y_rank_max        = MAX(d->v[dir1]->y_rank_max,d->v[dir2]->y_rank_max);
423    }
424}
425
426//////////////////////////////////////////////////////////////
427//////////////////////////////////////////////////////////////
428
429
430void TIPO_Swap_One_Node(t_node *d, t_tree *tree)
431{
432  if(d->tax) return;
433  else
434    {
435      int i;
436      int dir1, dir2;
437      t_node *tmp_n;
438      t_edge *tmp_e;
439
440      if(d != tree->n_root)
441        {
442          dir1 = dir2 = -1;
443          For(i,3)
444            {
445              if((d->v[i] != d->anc) && (d->b[i] != tree->e_root))
446                {
447                  if(dir1 < 0) dir1 = i;
448                  else         dir2 = i;
449                }
450            }
451        }
452      else
453        {
454          dir1 = 0;
455          dir2 = 1;
456        }
457
458      tmp_n      = d->v[dir2];
459      d->v[dir2] = d->v[dir1];
460      d->v[dir1] = tmp_n;
461
462      tmp_e      = d->b[dir2];
463      d->b[dir2] = d->b[dir1];
464      d->b[dir1] = tmp_e;
465    }
466}
467
468//////////////////////////////////////////////////////////////
469//////////////////////////////////////////////////////////////
470
471
472void TIPO_Minimize_Tip_Order_Score(int n_trees, t_tree **list_tree, t_tree *ref_tree)
473{
474  int i,j;
475  phydbl score,min_score,old_min_score;
476  phydbl diff,eps;
477  t_node **node_table;
478  int swapped;
479  t_node *tmp;
480
481  eps = 1.E-3;
482  old_min_score = min_score = score = INT_MAX;
483  /*   TIPO_Print_Tip_Ordered(ref_tree); */
484
485  do
486    {
487      for(i=ref_tree->n_otu;i<2*ref_tree->n_otu-1;i++)
488        {         
489          TIPO_Swap_One_Node(ref_tree->a_nodes[i],ref_tree);
490          TIPO_Get_Tips_Y_Rank(ref_tree);
491          score = (phydbl)TIPO_Untangle_Tree_List(n_trees,list_tree,ref_tree);
492          if(score == -1) 
493            {
494              return;
495            }
496
497          if(score < min_score) 
498            {
499              min_score = score;
500              PhyML_Printf("\n- Score = %f",score);
501            }
502          else 
503            {
504              TIPO_Swap_One_Node(ref_tree->a_nodes[i],ref_tree);   
505              TIPO_Get_Tips_Y_Rank(ref_tree);
506/*            PhyML_Printf("\n+ Score = %f",score); */
507            }
508        }
509      diff = fabs(old_min_score - min_score);
510      old_min_score = min_score;
511    }while(diff > eps);
512
513  PhyML_Printf("\n");
514
515  node_table = (t_node **)mCalloc(ref_tree->n_otu,sizeof(t_node *));
516
517
518  For(i,ref_tree->n_otu)
519    {
520      For(j,ref_tree->n_otu)
521        {
522          if(!strcmp(ref_tree->io->short_tax_names[i],ref_tree->a_nodes[j]->name))
523            {
524              Free(ref_tree->a_nodes[j]->name);
525              ref_tree->a_nodes[j]->name = (char *)mCalloc((int)strlen(ref_tree->io->long_tax_names[i])+1,sizeof(char));
526              strcpy(ref_tree->a_nodes[j]->name,ref_tree->io->long_tax_names[i]);
527              break;
528            }
529        }
530    }
531
532  For(i,ref_tree->n_otu) node_table[i] = ref_tree->a_nodes[i];
533
534/*       bubble sort of conflict nodes according to their y_rank */
535  do
536    {
537      swapped = NO;
538      For(i,ref_tree->n_otu-1)
539        {
540          if(node_table[i]->y_rank > node_table[i+1]->y_rank)
541            {
542              swapped = YES;
543              tmp             = node_table[i];
544              node_table[i]   = node_table[i+1];
545              node_table[i+1] = tmp;
546            }
547        }
548    }while(swapped == YES);
549
550  For(i,ref_tree->n_otu)
551    {
552      PhyML_Printf("\n%s",node_table[i]->name,node_table[i]->y_rank);
553    }
554
555
556
557  Free(node_table);
558
559}
560
561//////////////////////////////////////////////////////////////
562//////////////////////////////////////////////////////////////
563
564
565void TIPO_Print_Tip_Ordered(t_tree *tree)
566{
567  TIPO_Print_Tip_Ordered_Pre(tree->n_root,tree->n_root->v[2],tree);
568  TIPO_Print_Tip_Ordered_Pre(tree->n_root,tree->n_root->v[1],tree);
569}
570
571//////////////////////////////////////////////////////////////
572//////////////////////////////////////////////////////////////
573
574
575void TIPO_Print_Tip_Ordered_Pre(t_node *a, t_node *d, t_tree *tree)
576{
577 
578  if(d->tax)
579    {
580      PhyML_Printf("\n. %f \"%s\"",d->y_rank,d->name);
581    }
582  else
583    {
584      int i,dir1,dir2;
585
586      dir1 = dir2 = -1;
587      For(i,3)
588        {
589          if((d->v[i] != a) && (d->b[i] != tree->e_root))
590            {
591              if(dir1 < 0) dir1 = i;
592              else         dir2 = i;
593            }
594        }
595      if(d->v[dir1]->y_rank < d->v[dir2]->y_rank)
596        {
597          TIPO_Print_Tip_Ordered_Pre(d,d->v[dir1],tree);
598          TIPO_Print_Tip_Ordered_Pre(d,d->v[dir2],tree);
599        }
600      else
601        {
602          TIPO_Print_Tip_Ordered_Pre(d,d->v[dir2],tree);
603          TIPO_Print_Tip_Ordered_Pre(d,d->v[dir1],tree);
604        }
605    }
606}
607
608//////////////////////////////////////////////////////////////
609//////////////////////////////////////////////////////////////
610
611
612int TIPO_Untangle_Tree_List(int n_trees, t_tree **list_tree, t_tree *ref_tree)
613{
614  int i,j;
615  int tree_score,score;
616
617  score = 0;
618  For(i,n_trees) 
619    {
620/*       PhyML_Printf("\n. Untangling tree %3d",i); */
621      For(j,ref_tree->n_otu) list_tree[i]->a_nodes[j]->y_rank = list_tree[i]->a_nodes[j]->ext_node->y_rank;
622      tree_score = TIPO_Untangle_Tree(list_tree[i]);
623/*       PhyML_Printf(" score = %3d",tree_score); */
624      score += tree_score;
625      if(tree_score < 0) 
626        {
627          return -1;
628        }
629    }
630
631  return score;
632}
633
634//////////////////////////////////////////////////////////////
635//////////////////////////////////////////////////////////////
636
637
638phydbl TIPO_Untangle_Tree(t_tree *tree)
639{
640  int conflict;
641  int n_trials;
642  t_node **node_table;
643  int i,swapped;
644  t_node *tmp;
645
646  node_table = (t_node **)mCalloc(tree->n_otu,sizeof(t_node *));
647
648  For(i,tree->n_otu) node_table[i] = tree->a_nodes[i];
649  For(i,tree->n_otu) tree->a_nodes[i]->y_rank_ori = tree->a_nodes[i]->y_rank;
650
651
652/* bubble sort of nodes according to their y_rank */
653  do
654    {
655      swapped = NO;
656      For(i,tree->n_otu-1)
657        {
658          if(node_table[i]->y_rank > node_table[i+1]->y_rank)
659            {
660              swapped = YES;
661              tmp             = node_table[i];
662              node_table[i]   = node_table[i+1];
663              node_table[i+1] = tmp;
664            }
665        }
666    }
667  while(swapped == YES);
668 
669
670  /* Work out the y_rank values for every internal node given the external node ranks */
671  TIPO_Get_All_Y_Rank(tree);
672
673  tree->tip_order_score = .0;
674     
675  n_trials = 0;
676  do
677    {
678      conflict= NO;
679      /* Recusrssive untangling of the tree */ 
680      TIPO_Untangle_Node(tree->n_root,tree->n_root->v[2],node_table,&conflict,tree);
681      TIPO_Untangle_Node(tree->n_root,tree->n_root->v[1],node_table,&conflict,tree);
682      n_trials++;
683
684
685      if(n_trials > 2) /* We should have been able to untangle the tree after just one tree traversal */
686        {
687          int i;
688          FILE *ps_tree;
689
690          PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
691          ps_tree = (FILE *)fopen("failed_tree.ps","w");
692
693          Test_Node_Table_Consistency(tree);
694          tree->rates = RATES_Make_Rate_Struct(tree->n_otu);
695          RATES_Init_Rate_Struct(tree->rates,tree->io->rates,tree->n_otu);
696          TIMES_Least_Square_Node_Times(tree->e_root,tree);
697          TIMES_Adjust_Node_Times(tree);
698          RATES_Update_Cur_Bl(tree);
699
700          DR_Print_Postscript_Header(1,ps_tree);
701          tree->ps_tree = DR_Make_Tdraw_Struct(tree);
702          DR_Init_Tdraw_Struct(tree->ps_tree);
703          DR_Get_Tree_Box_Width(tree->ps_tree,tree);
704          Dist_To_Root(tree->n_root,tree);
705          tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree);
706          For(i,tree->n_otu) tree->ps_tree->ycoord[i] = tree->a_nodes[i]->y_rank * (int)(tree->ps_tree->page_height / (tree->n_otu));
707          DR_Get_X_Coord(NO,tree->ps_tree,tree);
708          DR_Get_Y_Coord(YES,tree->ps_tree,tree);
709          DR_Print_Tree_Postscript(1,NO,ps_tree,tree);
710          DR_Print_Postscript_EOF(ps_tree);
711          fclose(ps_tree);
712          Warn_And_Exit("");     
713        }
714    }while(conflict == YES); 
715
716  Free(node_table);
717  return tree->tip_order_score;
718}
719
720//////////////////////////////////////////////////////////////
721//////////////////////////////////////////////////////////////
722
723
724void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict, t_tree *tree)
725{
726
727  if(d->tax) return;
728  else
729    {
730      int    i,j;
731      int    d_a;
732      int    beg,end;
733      phydbl min,max;
734      t_node *lca;
735      t_node **conflict_tips, **anc_conflict;
736      int    n_conflicts;
737      phydbl eps,tmp_rank;
738      t_node *tmp_node;
739      int    n_moved;
740      int    n_anc_conflicts;
741
742      anc_conflict = NULL;
743      d_a = -1;
744
745      /* It is a post order traversal */
746      For(i,3)
747        {
748          if((d->v[i] != d->anc) && (d->b[i] != tree->e_root))
749            {
750              TIPO_Untangle_Node(d,d->v[i],node_table,conflict,tree);
751            }
752        }
753     
754     
755      lca = NULL;
756      eps = 1.E-10;
757
758      /* Find direction fron node d ((d)escendant) to a ((a)ncestor) */
759      For(i,3)
760        {
761          if((d->v[i] == d->anc) || (d->b[i] == tree->e_root))
762            {
763              d_a = i;
764              break;
765            }
766        }
767
768     
769      /* y_rank_min is the minimum rank among all the ranks of the tips that
770         can be reached when going from a to d */
771      min = d->y_rank_min;
772      max = d->y_rank_max;
773
774      /* Get the list of tip nodes which ranks are between d->y_rank_min and d->y_rank_max */
775      n_conflicts = 0;
776      For(i,tree->n_otu)
777        {
778          if((node_table[i]->y_rank > min - eps) && (node_table[i]->y_rank < max + eps))
779            {
780              n_conflicts++;         
781            }
782        }
783     
784      conflict_tips = NULL;
785      For(i,tree->n_otu)
786        {
787          if(node_table[i]->y_rank > min - eps)
788            {
789              conflict_tips = node_table+i;
790              break;
791            }
792        }     
793
794
795      beg = 0;
796      end = n_conflicts;
797      n_moved = 0;
798      n_anc_conflicts = 0;
799      do
800        {
801          for(i=beg;i<end;i++)
802            {
803              For(j,d->bip_size[d_a]) if(conflict_tips[i] == d->bip_node[d_a][j]) break;
804             
805              if(j == d->bip_size[d_a])               
806                /* conflict_tips[i] does not belong to the list of descendant of node d. It is
807                   therefore responsible for a conflict */
808                {
809                  *conflict = YES;
810
811/*                printf("\n. Moving %d with rank %f",conflict_tips[i]->num,conflict_tips[i]->y_rank); */
812                 
813                  n_moved++;
814                 
815                  /* Move from conflict_tips[i] towards the root as long as the rank of the node lca is between min and max */
816                  lca = conflict_tips[i];
817                  while(lca->y_rank_min > min && lca->y_rank_max < max) lca = lca->anc;
818
819
820                  if(lca->y_rank_min > max && lca->y_rank_max > max)
821                    {
822                      PhyML_Printf("\n. lca = %d (%d)",lca->num,lca==tree->n_root);
823                      PhyML_Printf("\n. Err in file %s at line %d",__FILE__,__LINE__);
824                      Warn_And_Exit("");
825                    }
826
827                  if(lca->y_rank_min < min && lca->y_rank_max < min)
828                    {
829                      PhyML_Printf("\n. lca = %d (root ? %d) (tip ? %d)",lca->num,lca==tree->n_root,lca->tax);
830                      PhyML_Printf("\n. lca->y_rank_min = %f lca->y_rank_max = %f",lca->y_rank_min,lca->y_rank_max);
831                      PhyML_Printf("\n. min=%f max=%f",min,max);
832                      PhyML_Printf("\n. Err in file %s at line %d",__FILE__,__LINE__);
833                      Warn_And_Exit("");
834                    }
835                  if(lca->tax)
836                    {
837                      PhyML_Printf("\n. lca  (%d) cannot be a tip.",lca->num);
838                      PhyML_Printf("\n. lca->anc->y_rank=%f",lca->anc->y_rank);
839                      PhyML_Printf("\n. lca->y_rank=%f",lca->y_rank);
840                      PhyML_Printf("\n. lca->y_rank_min=%f lca=>y_rank_max=%f",lca->y_rank_min,lca->y_rank_max);
841                      PhyML_Printf("\n. min=%f max=%f",min,max);
842                      PhyML_Printf("\n. %p %p",lca,conflict_tips[i]);
843                      PhyML_Printf("\n. Err in file %s at line %d",__FILE__,__LINE__);
844                      Warn_And_Exit("");
845                    }
846                 
847                  /* Have you found lca previously ? */
848                  For(j,n_anc_conflicts) if(anc_conflict[j] == lca) break;
849                  if(j == n_anc_conflicts) /* if no, then update the tree score and the list of ancestral nodes at the origin of conflicts */
850                    {
851                      /* tree->tip_order_score+=1.; */
852                      /* tree->tip_order_score+=(lca->y_rank_max-lca->y_rank_min); */
853                      n_anc_conflicts++;
854                      anc_conflict = (t_node **)realloc(anc_conflict,n_anc_conflicts*sizeof(t_node *));
855                      anc_conflict[n_anc_conflicts-1] = lca;
856                    }
857                     
858                  /*              PhyML_Printf("\n. Detected conflict for ``%s'' (rank:%f min=%f max=%f lca=%f)", */
859                  /*                           conflict_tips[i]->name, */
860                  /*                           conflict_tips[i]->y_rank, */
861                  /*                           min,max,lca->y_rank); */
862                 
863                  /* Solve the conflict by shifting tip nodes to the left or to the right */
864                  if(lca->y_rank > d->y_rank)
865                    {
866                      end--;
867/*                    max-=1.; */
868                      max = conflict_tips[end-1]->y_rank;
869/*                    printf("\n. max=%f %f",max,conflict_tips[end-1]->y_rank); */
870
871                      for(j=i;j<n_conflicts-1;j++)                     
872                        {
873/*                        PhyML_Printf("\n+ Moved (%d,%d) from (%f,%f)", */
874/*                                     conflict_tips[j]->num,conflict_tips[j+1]->num, */
875/*                                     conflict_tips[j]->y_rank,conflict_tips[j+1]->y_rank); */
876
877                          tmp_rank                   = conflict_tips[j]->y_rank;
878                          conflict_tips[j]->y_rank   = conflict_tips[j+1]->y_rank;
879                          conflict_tips[j+1]->y_rank = tmp_rank;
880
881                          tmp_node           = conflict_tips[j];
882                          conflict_tips[j]   = conflict_tips[j+1];
883                          conflict_tips[j+1] = tmp_node;
884
885                          tree->tip_order_score += fabs(conflict_tips[j]->y_rank - conflict_tips[j+1]->y_rank)/n_conflicts;
886
887/*                        PhyML_Printf(" to (%d,%d) (%f,%f)", */
888/*                                     conflict_tips[j]->num,conflict_tips[j+1]->num, */
889/*                                     conflict_tips[j]->y_rank,conflict_tips[j+1]->y_rank); */
890                        }
891                    }
892                  else
893                    {
894                      beg++;
895/*                    min+=1.; */
896                      min = conflict_tips[beg]->y_rank;
897/*                    printf("\n. min=%f %f",min,conflict_tips[beg]->y_rank); */
898
899                      for(j=i;j>0;j--)
900                        {
901/*                        PhyML_Printf("\n- Moved (%d,%d) from (%f,%f)", */
902/*                                     conflict_tips[j]->num,conflict_tips[j-1]->num, */
903/*                                     conflict_tips[j]->y_rank,conflict_tips[j-1]->y_rank); */
904
905               
906                          tmp_rank                   = conflict_tips[j]->y_rank;
907                          conflict_tips[j]->y_rank   = conflict_tips[j-1]->y_rank;
908                          conflict_tips[j-1]->y_rank = tmp_rank;
909                         
910                          tmp_node           = conflict_tips[j];
911                          conflict_tips[j]   = conflict_tips[j-1];
912                          conflict_tips[j-1] = tmp_node;                     
913
914                          tree->tip_order_score += fabs(conflict_tips[j]->y_rank - conflict_tips[j+1]->y_rank)/n_conflicts;
915
916/*                        PhyML_Printf(" to (%d,%d) (%f,%f)", */
917/*                                     conflict_tips[j]->num,conflict_tips[j-1]->num, */
918/*                                     conflict_tips[j]->y_rank,conflict_tips[j-1]->y_rank); */
919                        }
920                    }
921
922/*                printf("\n"); */
923/*                For(j,n_conflicts) printf("%.0f ",conflict_tips[j]->y_rank); */
924/*                printf("\n. min=%f max=%f",min,max); */
925/*                printf("\n. Node %d has now rank %f",c_node->num,c_node->y_rank); */
926
927
928                  /* Update internal nodes y ranks */
929                  TIPO_Get_All_Y_Rank(tree);
930
931                  break;
932                }
933            }
934        }while(n_moved + d->bip_size[d_a] != n_conflicts);
935
936
937      For(i,tree->n_otu)
938        {
939          if((tree->a_nodes[i]->y_rank > min - eps) && (tree->a_nodes[i]->y_rank < max + eps))
940            {
941              For(j,d->bip_size[d_a])
942                {
943                  if(tree->a_nodes[i] == d->bip_node[d_a][j]) break;
944                }
945              if(j == d->bip_size[d_a])
946                {
947                  printf("\n. Conflict remaining for node %d (%d)",d->num,a->num);
948                  PhyML_Printf("\n. Err in file %s at line %d",__FILE__,__LINE__);
949                  Warn_And_Exit("");
950                }
951            }
952        }
953
954      if(anc_conflict) Free(anc_conflict);
955
956      return;
957    }
958}
959
960//////////////////////////////////////////////////////////////
961//////////////////////////////////////////////////////////////
962
963
964int TIPO_Check_Tip_Ranks(t_tree *tree)
965{
966  int i,j;
967  phydbl eps;
968
969  eps = 1.E-6;
970
971  For(i,tree->n_otu-1)
972    {
973      for(j=i+1;j<tree->n_otu;j++)
974        {
975          if(fabs(tree->a_nodes[i]->y_rank - tree->a_nodes[j]->y_rank) < eps)
976            {
977              return 0;
978            }
979        }
980    }
981  return 1;
982}
983
984//////////////////////////////////////////////////////////////
985//////////////////////////////////////////////////////////////
986
987
988void TIPO_Read_Taxa_Zscores(FILE *fp_coord, t_tree *tree)
989{
990  char *name,*line;
991  phydbl z;
992  int i;
993
994  name = (char *)mCalloc(T_MAX_NAME,sizeof(char));
995  line = (char *)mCalloc(T_MAX_LINE,sizeof(char));
996
997  if(!fgets(line,T_MAX_LINE,fp_coord))
998    {
999      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
1000      Warn_And_Exit("");
1001    }
1002  Free(line);
1003
1004
1005  do
1006    {
1007      if(fscanf(fp_coord,"%s\t%lf\n",name,&z) == EOF) break;
1008      PhyML_Printf("\n. Read %s. Z-score: %f",name,z);
1009
1010      For(i,tree->n_otu) if(!strcmp(tree->io->long_tax_names[i],name)) break;
1011     
1012      if(i == tree->n_otu)
1013        {
1014          PhyML_Printf("\n. Could not find taxon '%s' in coordinate file.",name);
1015          PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
1016          Warn_And_Exit("");
1017        }
1018
1019      tree->io->z_scores[i] = z;
1020     
1021    }while(1);
1022
1023  Free(name);
1024}
1025
1026//////////////////////////////////////////////////////////////
1027//////////////////////////////////////////////////////////////
1028
1029
1030void TIPO_Read_Taxa_Coordinates(FILE *fp_coord, t_tree *tree)
1031{
1032  char *name,*line;
1033  phydbl lon, lat;
1034  int i;
1035
1036  name = (char *)mCalloc(T_MAX_NAME,sizeof(char));
1037  line = (char *)mCalloc(T_MAX_LINE,sizeof(char));
1038
1039  if(!fgets(line,T_MAX_LINE,fp_coord))
1040    {
1041      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
1042      Warn_And_Exit("");
1043    }
1044  Free(line);
1045
1046  tree->io->lat = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl));
1047  tree->io->lon = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl));
1048
1049  do
1050    {
1051      if(fscanf(fp_coord,"%s\t%lf\t%lf\n",name,&lat,&lon) == EOF) break;
1052      PhyML_Printf("\n. Read %s %f %f",name,lat,lon);
1053
1054      For(i,tree->n_otu) if(!strcmp(tree->io->long_tax_names[i],name)) break;
1055     
1056      if(i == tree->n_otu)
1057        {
1058          PhyML_Printf("\n. Could not find taxon '%s' in coordinate file.",name);
1059          PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
1060          Warn_And_Exit("");
1061        }
1062
1063      tree->io->lat[i] = lat;
1064      tree->io->lon[i] = lon;
1065     
1066    }while(1);
1067       
1068  Free(name);
1069}
1070
1071//////////////////////////////////////////////////////////////
1072//////////////////////////////////////////////////////////////
1073
1074
1075void TIPO_Get_Tips_Y_Rank_From_Zscores(t_tree *tree)
1076{
1077  int i;
1078
1079  For(i,tree->n_otu) tree->a_nodes[i]->y_rank = .0;
1080
1081  /* Randomization in order to avoid ties */
1082  For(i,tree->n_otu) tree->io->z_scores[i] += Rnorm(0.0,0.001);
1083
1084  For(i,tree->n_otu) tree->a_nodes[i]->y_rank = tree->io->z_scores[i];
1085
1086/*   For(i,tree->n_otu) tree->a_nodes[i]->y_rank = .0; */
1087
1088/*   For(i,tree->n_otu-1) */
1089/*     { */
1090/*       for(j=i+1;j<tree->n_otu;j++) */
1091/*      { */
1092/*        if(tree->io->z_scores[i] > tree->io->z_scores[j]) */
1093/*          { */
1094/*            tree->a_nodes[i]->y_rank += 1.0; */
1095/*          } */
1096/*        else */
1097/*        if(tree->io->z_scores[i] < tree->io->z_scores[j]) */
1098/*          { */
1099/*            tree->a_nodes[j]->y_rank += 1.0; */
1100/*          } */
1101/*        else */
1102/*          { */
1103/*            PhyML_Printf("\n. Ties not allowed.\n"); */
1104/*            PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */
1105/*            Warn_And_Exit(""); */
1106/*          } */
1107/*      } */
1108/*     } */
1109
1110/*   For(i,tree->n_otu) printf("- %f\n",tree->a_nodes[i]->y_rank); */
1111
1112}
1113
1114//////////////////////////////////////////////////////////////
1115//////////////////////////////////////////////////////////////
1116
1117/* Sort translation table such that tree->a_nodes[i]->name == tree->io->short_tax_name[i] for all i */
1118void  TIPO_Sort_Translation_Table(t_tree *tree)
1119{
1120  int i,j;
1121  char *s;
1122
1123
1124  Test_Node_Table_Consistency(tree);
1125
1126  For(i,tree->n_otu-1)
1127    {
1128      for(j=i+1;j<tree->n_otu;j++)
1129        {
1130          if(!strcmp(tree->a_nodes[i]->name,tree->io->short_tax_names[j]))
1131            {
1132              s = tree->io->short_tax_names[i];
1133              tree->io->short_tax_names[i] = tree->io->short_tax_names[j];
1134              tree->io->short_tax_names[j] = s;
1135
1136              s = tree->io->long_tax_names[i];
1137              tree->io->long_tax_names[i] = tree->io->long_tax_names[j];
1138              tree->io->long_tax_names[j] = s;
1139             
1140              break;
1141            }
1142        }
1143    }
1144}
1145
1146//////////////////////////////////////////////////////////////
1147//////////////////////////////////////////////////////////////
1148
1149
1150void TIPO_Randomize_Tip_Y_Ranks(t_tree *tree)
1151{
1152
1153  int i;
1154  phydbl rk_tmp;
1155  int rnd_node_num;
1156 
1157  For(i,tree->n_otu) tree->a_nodes[i]->y_rank_ori = tree->a_nodes[i]->y_rank;
1158
1159  For(i,tree->n_otu)
1160    {
1161      rnd_node_num = Rand_Int(0,tree->n_otu-1);
1162
1163      rk_tmp                            = tree->a_nodes[rnd_node_num]->y_rank;
1164      tree->a_nodes[rnd_node_num]->y_rank = tree->a_nodes[i]->y_rank;
1165      tree->a_nodes[i]->y_rank            = rk_tmp;
1166    }
1167}
1168
1169//////////////////////////////////////////////////////////////
1170//////////////////////////////////////////////////////////////
1171
1172
1173phydbl TIPO_Read_One_Taxon_Zscore(FILE *fp_coord, char *seqname_qry, int col, t_tree *tree)
1174{
1175  char *seqname, *place;
1176  phydbl lat;
1177
1178  seqname = (char *)mCalloc(T_MAX_NAME,sizeof(char));
1179  place   = (char *)mCalloc(T_MAX_NAME,sizeof(char));
1180
1181  rewind(fp_coord);
1182
1183  /* skip first line */
1184/*   if(!fgets(line,T_MAX_LINE,fp_coord)) */
1185/*     { */
1186/*       PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */
1187/*       Warn_And_Exit(""); */
1188/*     } */
1189/*   Free(line); */
1190
1191  do
1192    {
1193/*       if(fscanf(fp_coord,"%s\t%s\t%lf\t%lf\t%d\n",seqname,place,&lat,&lon,&year) == EOF) */
1194/*       if(fscanf(fp_coord,"%s\t%s\t%lf\t%lf\n",seqname,place,&lat,&lon) == EOF) */
1195/*       if(fscanf(fp_coord,"%s\t%lf\t%lf\n",seqname,&lat,&lon) == EOF) */
1196      if(fscanf(fp_coord,"%s %lf\n",seqname,&lat) == EOF)
1197        {
1198          PhyML_Printf("\n. Could not find sequence '%s' in coordinate file",seqname_qry);
1199          PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
1200          Warn_And_Exit("");
1201        }
1202
1203
1204      if(!strcmp(seqname,seqname_qry)) break;
1205     
1206    }while(1);
1207       
1208/*   PhyML_Printf("\n. Found %20s %s @ %10.2f %10.2f. Recording %10.2f",seqname,place,lat,lon,(col==1)?lat:lon); */
1209
1210  Free(seqname);
1211  Free(place);
1212 
1213/*   if(col == 1)      return lat; */
1214/*   else if(col == 2) return lon; */
1215/*   else              return -1.; */
1216
1217  return lat;
1218}
1219
1220//////////////////////////////////////////////////////////////
1221//////////////////////////////////////////////////////////////
1222
1223
1224void TIPO_Normalize_Zscores(t_tree *tree)
1225{
1226  int i;
1227  phydbl min_z,max_z;
1228  phydbl eps;
1229
1230  eps = 1.E-10;
1231
1232  min_z = FLT_MAX;
1233  For(i,tree->n_otu)
1234    {
1235      if(tree->io->z_scores[i] < min_z)
1236        {
1237          min_z = tree->io->z_scores[i];
1238        }
1239    }
1240 
1241  max_z = -FLT_MAX;
1242  For(i,tree->n_otu)
1243    {
1244      if(tree->io->z_scores[i] > max_z)
1245        {
1246          max_z = tree->io->z_scores[i];
1247        }
1248    }
1249
1250  For(i,tree->n_otu) tree->io->z_scores[i] = (tree->io->z_scores[i] - min_z)/(max_z-min_z+eps); 
1251
1252}
1253
1254//////////////////////////////////////////////////////////////
1255//////////////////////////////////////////////////////////////
1256
1257
1258phydbl TIPO_Lk(t_tree *tree)
1259{
1260  tree->geo_lnL = 0.0;
1261  TIPO_Lk_Post(tree->n_root,tree->n_root->v[2],tree);
1262  TIPO_Lk_Post(tree->n_root,tree->n_root->v[1],tree);
1263  TIPO_Lk_Core(NULL,tree->n_root,tree);
1264  return(tree->geo_lnL);
1265}
1266
1267//////////////////////////////////////////////////////////////
1268//////////////////////////////////////////////////////////////
1269
1270
1271phydbl TIPO_Lk_Post(t_node *a, t_node *d, t_tree *tree)
1272{
1273  if(!d->tax)
1274    {
1275      int i;
1276
1277      For(i,3)
1278        {
1279          if(d->v[i] != a && d->b[i] != tree->e_root)
1280            {
1281              TIPO_Lk_Post(d,d->v[i],tree);
1282            }
1283        }
1284      TIPO_Lk_Core(a,d,tree);
1285    }
1286
1287  return .0;
1288}
1289
1290//////////////////////////////////////////////////////////////
1291//////////////////////////////////////////////////////////////
1292
1293
1294phydbl TIPO_Lk_Core(t_node *a, t_node *d, t_tree *tree)
1295{
1296
1297  int i,j;
1298  int d_v1,d_v2,v1_d,v2_d;
1299  t_node *v1, *v2;
1300  phydbl dist,dens,min_dist;
1301   
1302
1303  if(d->tax)
1304    {
1305      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
1306      Warn_And_Exit("");
1307    }
1308
1309  if(d == tree->n_root)
1310    {
1311      d_v1 = 0;
1312      d_v2 = 1;
1313    }
1314  else
1315    {
1316      d_v1 = d_v2 = -1;
1317      For(i,3)
1318        {
1319          if(d->v[i] != a && d->b[i] != tree->e_root)
1320            {
1321              if(d_v1 < 0) d_v1 = i;
1322              else         d_v2 = i;
1323            }
1324        }
1325    }
1326
1327  v1 = d->v[d_v1];
1328  v2 = d->v[d_v2];
1329
1330  v1_d = v2_d = -1;
1331  if(d == tree->n_root)
1332    {
1333      For(i,3)
1334        {
1335          if(v1->b[i] == tree->e_root) v1_d = i;
1336          if(v2->b[i] == tree->e_root) v2_d = i;
1337        }
1338    }
1339  else
1340    {
1341      For(i,3)
1342        {
1343          if(v1->v[i] == d) v1_d = i;
1344          if(v2->v[i] == d) v2_d = i;
1345        }
1346    }
1347 
1348
1349  dens = 0.0;
1350  min_dist = FLT_MAX;
1351  For(i,v1->bip_size[v1_d])
1352    {
1353      For(j,v2->bip_size[v2_d])
1354        {
1355          dist = fabs(v1->bip_node[v1_d][i]->y_rank - 
1356                      v2->bip_node[v2_d][j]->y_rank);
1357
1358          if(dist < min_dist) min_dist = dist;
1359
1360          dens += Dnorm(dist,0.0,tree->geo_mig_sd);
1361          /* printf("\n. dist=%f dens=%f %f %f", */
1362          /*     dist,Dnorm(dist,0.0,tree->geo_mig_sd), */
1363          /*     v1->bip_node[v1_d][i]->y_rank, */
1364          /*     v2->bip_node[v2_d][j]->y_rank); */
1365        }
1366    }
1367
1368  /* printf("\n. min_dist=%f dens=%f", */
1369  /*     min_dist,Dnorm(dist,0.0,tree->geo_mig_sd)); */
1370
1371  /* dens = Dnorm(min_dist,0.0,tree->geo_mig_sd); */
1372  tree->geo_lnL += LOG(dens);
1373
1374  return tree->geo_lnL;
1375}
1376
1377//////////////////////////////////////////////////////////////
1378//////////////////////////////////////////////////////////////
1379
1380//////////////////////////////////////////////////////////////
1381//////////////////////////////////////////////////////////////
1382
1383//////////////////////////////////////////////////////////////
1384//////////////////////////////////////////////////////////////
1385
1386//////////////////////////////////////////////////////////////
1387//////////////////////////////////////////////////////////////
1388
Note: See TracBrowser for help on using the repository browser.