1 /*
2 
3 PHYML :  a program that  computes maximum likelihood  phylogenies from
4 DNA or AA homologous sequences
5 
6 Copyright (C) Stephane Guindon. Oct 2003 onward
7 
8 All parts of  the source except where indicated  are distributed under
9 the GNU public licence.  See http://www.opensource.org for details.
10 
11 */
12 
13 #include "draw.h"
14 
15 
DR_Draw_Tree(char * file_name,t_tree * tree)16 void DR_Draw_Tree(char *file_name, t_tree *tree)
17 {
18   FILE *ps_tree;
19 
20   ps_tree = (FILE *)fopen(file_name,"w");
21   DR_Print_Postscript_Header(1,ps_tree);
22   tree->ps_tree = DR_Make_Tdraw_Struct(tree);
23   DR_Init_Tdraw_Struct(tree->ps_tree);
24   DR_Get_Tree_Box_Width(tree->ps_tree,tree);
25   Dist_To_Root(tree);
26   tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree);
27   DR_Get_X_Coord(NO,tree->ps_tree,tree);
28   DR_Get_Y_Coord(NO,tree->ps_tree,tree);
29   DR_Print_Tree_Postscript(1,NO,ps_tree,tree);
30   DR_Print_Postscript_EOF(ps_tree);
31   fclose(ps_tree);
32 }
33 
34 //////////////////////////////////////////////////////////////
35 //////////////////////////////////////////////////////////////
36 
37 
DR_Get_Tree_Coord(t_tree * tree)38 void DR_Get_Tree_Coord(t_tree *tree)
39 {
40   DR_Init_Tdraw_Struct(tree->ps_tree);
41   DR_Get_Tree_Box_Width(tree->ps_tree,tree);
42   if(!tree->n_root)
43     {
44       PhyML_Printf("\n. Adding root before rendering the tree.");
45       Add_Root(tree->a_edges[0],tree);
46     }
47   Dist_To_Root(tree);
48   tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree);
49   DR_Get_X_Coord(NO,tree->ps_tree,tree);
50   DR_Get_Y_Coord(NO,tree->ps_tree,tree);
51 }
52 
53 //////////////////////////////////////////////////////////////
54 //////////////////////////////////////////////////////////////
55 
56 
DR_Print_Postscript_Header(int n_pages,FILE * fp)57 void DR_Print_Postscript_Header(int n_pages, FILE *fp)
58 {
59   if(!fp)
60     {
61       PhyML_Printf("\n== Failed to open the postscript file.");
62       PhyML_Printf("\n== Did you forget the '--ps' option ?.");
63       Exit("\n");
64     }
65 
66   PhyML_Fprintf(fp,"%%!PS-Adobe-3.0\n");
67   PhyML_Fprintf(fp,"%%%%BoundingBox: 0 0 595.28 841.89\n");
68   PhyML_Fprintf(fp,"%%%%DocumentFonts: Times-Roman Times-Roman\n");
69   PhyML_Fprintf(fp,"%%%%Creator: Stephane Guindon\n");
70   PhyML_Fprintf(fp,"%%%%Title: tree\n");
71   PhyML_Fprintf(fp,"%%%%EndComments\n");
72   PhyML_Fprintf(fp,"%%%%Pages: %d\n",n_pages);
73 
74   PhyML_Fprintf(fp,"/lt {lineto} bind def\n");
75   PhyML_Fprintf(fp,"/mt {moveto} bind def\n");
76   PhyML_Fprintf(fp,"/sc {setrgbcolor} bind def\n");
77   PhyML_Fprintf(fp,"/ct {curveto} bind def\n");
78   PhyML_Fprintf(fp,"/np {newpath} bind def\n");
79   PhyML_Fprintf(fp,"/cp {closepath} bind def\n");
80   PhyML_Fprintf(fp,"/gs {gsave} bind def\n");
81   PhyML_Fprintf(fp,"/gr {grestore} bind def\n");
82 
83   PhyML_Fprintf(fp,"/Times-Roman findfont\n");
84   PhyML_Fprintf(fp,"12 scalefont\n");
85   PhyML_Fprintf(fp,"setfont\n");
86 
87   PhyML_Fprintf(fp,"/clipbox\n");
88   PhyML_Fprintf(fp,"{\n");
89   PhyML_Fprintf(fp,"newpath\n");
90   PhyML_Fprintf(fp,"20 20 mt\n");
91   PhyML_Fprintf(fp,"580 20 lt\n");
92   PhyML_Fprintf(fp,"580 820 lt\n");
93   PhyML_Fprintf(fp,"20 820 lt\n");
94   PhyML_Fprintf(fp,"20 20 lt\n");
95   PhyML_Fprintf(fp,"closepath\n");
96   PhyML_Fprintf(fp,"clip\n");
97   PhyML_Fprintf(fp,"} bind def\n");
98 
99 
100   /* PhyML_Fprintf(fp,"gs\n"); */
101   /* PhyML_Fprintf(fp,"newpath\n"); */
102   /* PhyML_Fprintf(fp,"20 20 mt\n"); */
103   /* PhyML_Fprintf(fp,"580 20 lt\n"); */
104   /* PhyML_Fprintf(fp,"580 820 lt\n"); */
105   /* PhyML_Fprintf(fp,"20 820 lt\n"); */
106   /* PhyML_Fprintf(fp,"20 20 lt\n"); */
107   /* PhyML_Fprintf(fp,"closepath\n"); */
108   /* PhyML_Fprintf(fp,"stroke\n"); */
109   /* PhyML_Fprintf(fp,"gr\n"); */
110   /* PhyML_Fprintf(fp,"0 0 0 sc\n"); */
111 
112 
113 }
114 
115 //////////////////////////////////////////////////////////////
116 //////////////////////////////////////////////////////////////
117 
118 
DR_Print_Postscript_EOF(FILE * fp)119 void DR_Print_Postscript_EOF(FILE *fp)
120 {
121   PhyML_Fprintf(fp,"%%%%Trailer\n");
122   PhyML_Fprintf(fp,"%%%%EOF\n");
123 }
124 
125 //////////////////////////////////////////////////////////////
126 //////////////////////////////////////////////////////////////
127 
128 
DR_Print_Tree_Postscript(int page_num,int render_name,FILE * fp,t_tree * tree)129 void DR_Print_Tree_Postscript(int page_num, int render_name, FILE *fp, t_tree *tree)
130 {
131   tdraw *draw;
132   t_node *n_root;
133 
134   draw = tree->ps_tree;
135 /*   DR_Get_Tree_Coord(tree); */
136   n_root = tree->n_root;
137 
138 /*   PhyML_Fprintf(fp,"%%%%Page: %d %d\n",page_num,page_num); */
139   /* PhyML_Fprintf(fp,"0.001 setlinewidth\n"); */
140 /*   PhyML_Fprintf(fp,"0.5 0.5 0.4 sc\n"); */
141   /* PhyML_Fprintf(fp,"0 0 0 sc\n"); */
142 /*   PhyML_Fprintf(fp,"clipbox\n"); */
143 /*   PhyML_Fprintf(fp,"stroke\n"); */
144   PhyML_Fprintf(fp,"20 20 translate\n");
145   PhyML_Fprintf(fp,"newpath\n");
146 
147 
148   draw->ycoord[n_root->num] = (draw->ycoord[n_root->v[2]->num] + draw->ycoord[n_root->v[1]->num])/2. + 20;
149   draw->xcoord[n_root->num] = 0.0;
150   DR_Print_Tree_Postscript_Pre(n_root,n_root->v[2],n_root->b[2],render_name,fp,draw,tree);
151   DR_Print_Tree_Postscript_Pre(n_root,n_root->v[1],n_root->b[1],render_name,fp,draw,tree);
152 
153 
154   PhyML_Fprintf(fp,"closepath\n");
155   PhyML_Fprintf(fp,"0 0 translate\n");
156   PhyML_Fprintf(fp,"stroke\n");
157   PhyML_Fprintf(fp,"showpage\n");
158 }
159 
160 //////////////////////////////////////////////////////////////
161 //////////////////////////////////////////////////////////////
162 
163 
DR_Print_Tree_Postscript_Pre(t_node * a,t_node * d,t_edge * b,int render_name,FILE * fp,tdraw * w,t_tree * tree)164 void DR_Print_Tree_Postscript_Pre(t_node *a, t_node *d, t_edge *b, int render_name, FILE *fp, tdraw *w, t_tree *tree)
165 {
166   int i;
167   phydbl R, G, B;
168 
169   R = G = B = 0.0;
170 
171   PhyML_Fprintf(fp,"gs\n");
172 
173   PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[a->num],w->ycoord[a->num]);
174 
175 /*   PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[a->num],w->ycoord[d->num]); */
176 /*   PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[d->num],w->ycoord[d->num]); */
177 
178   phydbl min,max,step,val;
179 
180   min = 0.0;
181   max = 5.;
182 
183   step = (max-min)/13.;
184 
185   /* val = tree->rates->mean_r[d->num] / (phydbl)(tree->mcmc->run/tree->mcmc->sample_interval+1.); */
186   /* val = tree->rates->mean_r[d->num]; */
187   /* val = tree->times->has_survived[d->num]; */
188   /* if(val > 0.5) {R=1.; G=.0; B=0.;} */
189   /* val = tree->geo->ldscape[tree->geo->idx_loc[d->num]*tree->geo->n_dim+0] + 2.5; */
190   val = tree->geo->coord_loc[tree->geo->idx_loc[d->num]]->lonlat[0] + 2.5;
191   /* val = 0.; */
192 
193   if(val <= min+1.*step)
194     {R=.0; G=1.; B=1.;}
195   else if(val > min+1.*step && val <= min+2.*step)
196     {R=.0; G=1.; B=.8;}
197   else if(val > min+2.*step && val <= min+3.*step)
198     {R=.0; G=1.; B=.5;}
199   else if(val > min+3.*step && val <= min+4.*step)
200     {R=.0; G=1.; B=.3;}
201   else if(val > min+4.*step && val <= min+5.*step)
202     {R=.0; G=1.; B=.0;}
203   else if(val > min+5.*step && val <= min+6.*step)
204     {R=.25; G=1.; B=0.;}
205   else if(val > min+6.*step && val <= min+7.*step)
206     {R=.5; G=1.; B=0.;}
207   else if(val > min+7.*step && val <= min+8.*step)
208     {R=.75; G=1.; B=.0;}
209   else if(val > min+8.*step && val <= min+9.*step)
210     {R=1.; G=1.; B=.0;}
211   else if(val > min+9.*step && val <= min+10.*step)
212     {R=1.; G=.75; B=.0;}
213   else if(val > min+10.*step && val <= min+11.*step)
214     {R=1.; G=.5; B=.0;}
215   else if(val > min+11.*step && val <= min+12.*step)
216     {R=1.; G=.25; B=.0;}
217   else if(val > min+12.*step)
218     {R=1.; G=.0; B=0.;}
219 
220 
221   /* R = 0.; G = 0.; B = 0.; */
222 
223   PhyML_Fprintf(fp,"2 setlinewidth\n");
224   /* PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[a->num],w->ycoord[d->num]); */
225   /* PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[d->num],w->ycoord[d->num]); */
226 
227   phydbl xa = w->xcoord[a->num];
228   phydbl xd = MIN(w->xcoord[a->num] + 5,w->xcoord[d->num]);
229   phydbl ya = w->ycoord[a->num];
230   phydbl yd = w->ycoord[d->num];
231 
232   PhyML_Fprintf(fp,"%.1f %.1f %.1f %.1f %.1f %.1f ct\n",
233                 xa + (xd-xa)/2.,(ya+yd)/2.,
234                 xd - (xd-xa)/5.,yd,
235                 xd,yd);
236 
237   PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[d->num],w->ycoord[d->num]);
238 
239   /* PhyML_Fprintf(fp,"%.1f %.1f %.1f %.1f %.1f %.1f ct\n", */
240   /* 		w->xcoord[a->num], */
241   /* 		w->ycoord[d->num], */
242   /* 		w->xcoord[d->num], */
243   /* 		w->ycoord[d->num], */
244   /* 		w->xcoord[d->num], */
245   /* 		w->ycoord[d->num]); */
246 
247 
248   if(tree->rates && tree->times->has_survived[d->num] == YES)
249     {
250       PhyML_Fprintf(fp," /Helvetica findfont 16 scalefont\n");
251       PhyML_Fprintf(fp,"setfont\n");
252       PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num]-5,w->ycoord[d->num]);
253       PhyML_Fprintf(fp,"0 0 0 sc\n");
254       PhyML_Fprintf(fp,"(*) show \n");
255     }
256 
257   PhyML_Fprintf(fp,"%f %f %f sc\n",R,G,B);
258 
259   if(d->tax)
260     {
261       PhyML_Fprintf(fp,"stroke\n");
262       PhyML_Fprintf(fp,"0 setgray\n");
263       PhyML_Fprintf(fp,"2 setlinewidth\n");
264       PhyML_Fprintf(fp,"np %.1f %.1f 1 0 360 arc cp\n",w->xcoord[d->num],w->ycoord[d->num]);
265       PhyML_Fprintf(fp,"%.1f %.1f %.1f sc fill\n",R,G,B);
266 /*       PhyML_Fprintf(fp,"%f setgray fill\n",greylevel); */
267       PhyML_Fprintf(fp,"0 0 0 sc\n");
268 
269 
270       PhyML_Fprintf(fp," /Helvetica findfont 10 scalefont\n");
271       PhyML_Fprintf(fp,"setfont\n");
272       PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num]+2,w->ycoord[d->num]-6);
273       /* PhyML_Fprintf(fp,"(%d) show \n",d->num); */
274       /* PhyML_Fprintf(fp,"(%s) show \n",d->name); */
275       PhyML_Fprintf(fp," /Helvetica findfont 14 scalefont\n");
276       PhyML_Fprintf(fp,"setfont\n");
277 
278 
279       PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num] - (w->xcoord[d->num] - w->xcoord[a->num])/2.,w->ycoord[d->num]);
280       PhyML_Fprintf(fp," /Helvetica findfont 10 scalefont\n");
281       PhyML_Fprintf(fp,"setfont\n");
282 
283 #if (defined GEO)
284       /* PhyML_Fprintf(fp,"([%4.4f,%4.4f]) show \n", */
285       /*               tree->geo->ldscape[tree->geo->loc[d->num]*tree->geo->n_dim+0], */
286       /*               tree->geo->ldscape[tree->geo->loc[d->num]*tree->geo->n_dim+1]); */
287 #endif
288 
289 
290       /* PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num]+5,w->ycoord[d->num]); */
291       /* PhyML_Fprintf(fp,"(%.10s) show \n",d->name); */
292 
293 
294 /*       if(render_name) */
295 /* 	{ */
296 /* 	  if(tree->io->long_tax_names) */
297 /* 	    PhyML_Fprintf(fp,"(%s) show \n",tree->io->long_tax_names[d->num]); */
298 /* 	  else */
299 /* 	    PhyML_Fprintf(fp,"(%s) show \n",d->name); */
300 /* 	} */
301 
302       PhyML_Fprintf(fp,"stroke\n");
303       PhyML_Fprintf(fp,"gr\n");
304       PhyML_Fprintf(fp,"0 0 0 sc\n");
305       return;
306     }
307   else
308     {
309       PhyML_Fprintf(fp,"stroke\n");
310       PhyML_Fprintf(fp,"0 setgray\n");
311       PhyML_Fprintf(fp,"2 setlinewidth\n");
312       PhyML_Fprintf(fp,"np %.1f %.1f 1 0 360 arc cp\n",w->xcoord[d->num],w->ycoord[d->num]);
313       PhyML_Fprintf(fp,"%.1f %.1f %.1f sc fill\n",R,G,B);
314 /*       PhyML_Fprintf(fp,"%f setgray fill\n",greylevel); */
315       PhyML_Fprintf(fp,"0 0 0 sc\n");
316 
317       PhyML_Fprintf(fp," /Helvetica findfont 10 scalefont\n");
318       PhyML_Fprintf(fp,"setfont\n");
319       PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num]+2,w->ycoord[d->num]);
320 
321       /* PhyML_Fprintf(fp,"(%d) show \n",b->num); */
322 
323       PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num],w->ycoord[d->num]);
324       PhyML_Fprintf(fp," /Helvetica findfont 14 scalefont\n");
325       PhyML_Fprintf(fp,"setfont\n");
326 
327 
328       PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num] - (w->xcoord[d->num] - w->xcoord[a->num])/2.,w->ycoord[d->num]);
329       PhyML_Fprintf(fp," /Helvetica findfont 10 scalefont\n");
330       PhyML_Fprintf(fp,"setfont\n");
331 
332 #if (defined GEO)
333       /* PhyML_Fprintf(fp,"([%4.4f,%4.4f]) show \n", */
334       /*               tree->geo->ldscape[tree->geo->loc[d->num]*tree->geo->n_dim+0], */
335       /*               tree->geo->ldscape[tree->geo->loc[d->num]*tree->geo->n_dim+1]); */
336 #endif
337 
338 
339       PhyML_Fprintf(fp,"stroke\n");
340       PhyML_Fprintf(fp,"gr\n");
341       PhyML_Fprintf(fp,"0 0 0 sc\n");
342       for(i=0;i<3;i++)
343 	if(d->v[i] != a && d->b[i] != tree->e_root) DR_Print_Tree_Postscript_Pre(d,d->v[i],d->b[i],render_name,fp,w,tree);
344     }
345 
346 
347 
348 
349   return;
350 }
351 
352 //////////////////////////////////////////////////////////////
353 //////////////////////////////////////////////////////////////
354 
355 
DR_Get_X_Coord_Pre(t_node * a,t_node * d,t_edge * b,tdraw * w,int fixed_tips,t_tree * tree)356 void DR_Get_X_Coord_Pre(t_node *a, t_node *d, t_edge *b, tdraw *w, int fixed_tips, t_tree *tree)
357 {
358   int i;
359 
360   if(!(d->tax && fixed_tips == YES)) w->xcoord[d->num] =  d->dist_to_root * (phydbl)w->tree_box_width/w->max_dist_to_root;
361 
362   if(d->tax) return;
363   else
364     {
365       for(i=0;i<3;i++)
366 	if((d->v[i] != a) && (d->b[i] != tree->e_root))
367 	  DR_Get_X_Coord_Pre(d,d->v[i],d->b[i],w,fixed_tips,tree);
368     }
369 }
370 
371 //////////////////////////////////////////////////////////////
372 //////////////////////////////////////////////////////////////
373 
374 
DR_Get_X_Coord(int fixed_tips,tdraw * w,t_tree * tree)375 void DR_Get_X_Coord(int fixed_tips, tdraw *w, t_tree *tree)
376 {
377   if(!(tree->n_root->v[2]->tax && fixed_tips == YES)) w->xcoord[tree->n_root->v[2]->num] = tree->n_root->v[2]->dist_to_root * (phydbl)w->tree_box_width/w->max_dist_to_root;
378   if(!(tree->n_root->v[1]->tax && fixed_tips == YES)) w->xcoord[tree->n_root->v[1]->num] = tree->n_root->v[1]->dist_to_root * (phydbl)w->tree_box_width/w->max_dist_to_root;
379   DR_Get_X_Coord_Pre(tree->n_root,tree->n_root->v[2],NULL,w,fixed_tips,tree);
380   DR_Get_X_Coord_Pre(tree->n_root,tree->n_root->v[1],NULL,w,fixed_tips,tree);
381   w->xcoord[tree->n_root->num] = 0;
382 }
383 
384 
385 //////////////////////////////////////////////////////////////
386 //////////////////////////////////////////////////////////////
387 
388 
DR_Get_Y_Coord(int fixed_tips,tdraw * w,t_tree * tree)389 void DR_Get_Y_Coord(int fixed_tips, tdraw *w, t_tree *tree)
390 {
391   int next_y_slot;
392   next_y_slot = 0;
393   DR_Get_Y_Coord_Post(tree->n_root,tree->n_root->v[2],NULL,&next_y_slot,fixed_tips,w,tree);
394   DR_Get_Y_Coord_Post(tree->n_root,tree->n_root->v[1],NULL,&next_y_slot,fixed_tips,w,tree);
395   w->ycoord[tree->n_root->num] = (int)((w->ycoord[tree->n_root->v[2]->num] + w->ycoord[tree->n_root->v[2]->num]) / 2.) + 20;
396 }
397 
398 //////////////////////////////////////////////////////////////
399 //////////////////////////////////////////////////////////////
400 
401 
DR_Get_Y_Coord_Post(t_node * a,t_node * d,t_edge * b,int * next_y_slot,int fixed_tips,tdraw * w,t_tree * tree)402 void DR_Get_Y_Coord_Post(t_node *a, t_node *d, t_edge *b, int *next_y_slot, int fixed_tips, tdraw *w, t_tree *tree)
403 {
404   int i;
405 
406   if(d->tax)
407     {
408       if(!fixed_tips)
409 	{
410 /* 	  w->ycoord[d->num] = *next_y_slot + (int)(w->page_height / (2.*tree->n_otu)); */
411 	  w->ycoord[d->num] = *next_y_slot + 20;
412 	  (*next_y_slot) += (int)(w->page_height / (tree->n_otu-1));
413           printf("\n. %s %f",d->name,w->ycoord[d->num]);
414 	}
415     }
416   else
417     {
418       int d1, d2;
419 
420       d1 = d2 = -1;
421       for(i=0;i<3;i++)
422 	{
423 	  if(d->v[i] != a && d->b[i] != tree->e_root)
424 	    {
425 	      DR_Get_Y_Coord_Post(d,d->v[i],d->b[i],next_y_slot,fixed_tips,w,tree);
426 	      if(d1<0) d1 = i;
427 	      else     d2 = i;
428 	    }
429 	}
430       w->ycoord[d->num] = (w->ycoord[d->v[d1]->num] + w->ycoord[d->v[d2]->num])/2.;
431     }
432 }
433 
434 //////////////////////////////////////////////////////////////
435 //////////////////////////////////////////////////////////////
436 
437 
DR_Make_Tdraw_Struct(t_tree * tree)438 tdraw *DR_Make_Tdraw_Struct(t_tree *tree)
439 {
440   tdraw *w;
441 
442   w = (tdraw *)mCalloc(1,sizeof(tdraw));
443   w->xcoord = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl));
444   w->ycoord = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl));
445   w->xcoord_s = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl));
446   w->ycoord_s = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl));
447   w->cdf_mat  = (int *)mCalloc((2*tree->n_otu-2)*(2*tree->n_otu-2),sizeof(int));
448   w->cdf_mat_x  = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl));
449   w->cdf_mat_y  = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl));
450 
451   return w;
452 }
453 
454 //////////////////////////////////////////////////////////////
455 //////////////////////////////////////////////////////////////
456 
457 
DR_Init_Tdraw_Struct(tdraw * w)458 void DR_Init_Tdraw_Struct(tdraw *w)
459 {
460   w->page_width  = 580-20;
461   w->page_height = 820-20;
462 }
463 
464 //////////////////////////////////////////////////////////////
465 //////////////////////////////////////////////////////////////
466 
467 
DR_Get_Tree_Box_Width(tdraw * w,t_tree * tree)468 void DR_Get_Tree_Box_Width(tdraw *w, t_tree *tree)
469 {
470   int i;
471   int max_name_len, curr_len;
472 
473   max_name_len = curr_len = 0;
474   for(i=0;i<tree->n_otu;i++)
475     {
476       curr_len = (int)strlen(tree->a_nodes[i]->name);
477       if(curr_len > max_name_len) max_name_len = curr_len;
478     }
479 
480   w->tree_box_width = w->page_width - max_name_len * 8.66667;
481   /* w->tree_box_width = w->page_width - max_name_len * 10.; */
482 }
483 
484 //////////////////////////////////////////////////////////////
485 //////////////////////////////////////////////////////////////
486 
487 
DR_Get_Max_Dist_To_Root(t_tree * tree)488 phydbl DR_Get_Max_Dist_To_Root(t_tree *tree)
489 {
490   phydbl mx;
491   int i;
492 
493   mx = .0;
494   for(i=0;i<tree->n_otu;i++)
495     {
496       if(tree->a_nodes[i]->dist_to_root > mx)
497 	{
498 	  mx = tree->a_nodes[i]->dist_to_root;
499 	}
500     }
501 
502   return mx;
503 }
504 
505 //////////////////////////////////////////////////////////////
506 //////////////////////////////////////////////////////////////
507 
DR_Get_Tree_Coord_Scaled(tdraw * w,t_tree * tree)508 void DR_Get_Tree_Coord_Scaled(tdraw *w, t_tree *tree)
509 {
510   int i;
511   int max_x,min_x;
512   int max_y,min_y;
513 
514   max_x = -INT_MAX;
515   min_x =  INT_MAX;
516 
517   For(i,2*tree->n_otu-1)
518     {
519       if(w->xcoord[i] > max_x) max_x = w->xcoord[i];
520       if(w->xcoord[i] < min_x) min_x = w->xcoord[i];
521     }
522 
523   max_y = -INT_MAX;
524   min_y =  INT_MAX;
525 
526   For(i,2*tree->n_otu-1)
527     {
528       if(w->ycoord[i] > max_y) max_y = w->ycoord[i];
529       if(w->ycoord[i] < min_y) min_y = w->ycoord[i];
530     }
531 
532 
533   For(i,2*tree->n_otu-1)
534     {
535       w->xcoord_s[i] = (phydbl)(w->xcoord[i] - min_x) / (max_x - min_x);
536       w->ycoord_s[i] = (phydbl)(w->ycoord[i] - min_y) / (max_y - min_y);
537     }
538 }
539 
540 //////////////////////////////////////////////////////////////
541 //////////////////////////////////////////////////////////////
542 
DR_Get_Cdf_Mat(t_tree * tree)543 void DR_Get_Cdf_Mat(t_tree *tree)
544 {
545   int i,j,k;
546   phydbl min_x,max_x,y;
547   phydbl x_mat,y_mat;
548   t_node *d, *a;
549   phydbl eps;
550 
551   eps = 1.E-6;
552 
553   For(i,2*tree->n_otu-1)  tree->ps_tree->cdf_mat_x[i] = tree->ps_tree->xcoord_s[i];
554   For(i,2*tree->n_otu-1)  tree->ps_tree->cdf_mat_y[i] = tree->ps_tree->ycoord_s[i];
555 
556   Qksort(tree->ps_tree->cdf_mat_x,NULL,0,2*tree->n_otu-2);
557   Qksort(tree->ps_tree->cdf_mat_y,NULL,0,2*tree->n_otu-2);
558 
559   For(i,2*tree->n_otu-2) /* x coordinates */
560     {
561       For(j,2*tree->n_otu-2) /* y coordinates */
562 	{
563 	  For(k,2*tree->n_otu-2) /* all nodes in the tree */
564 	    {
565 	      d = tree->a_nodes[k];
566 	      a = tree->a_nodes[k]->anc;
567 
568 	      min_x = tree->ps_tree->xcoord_s[a->num];
569 	      max_x = tree->ps_tree->xcoord_s[d->num];
570 
571 	      y = tree->ps_tree->ycoord_s[d->num];
572 
573 	      x_mat = tree->ps_tree->cdf_mat_x[i];
574 	      y_mat = tree->ps_tree->cdf_mat_y[j];
575 
576 /* 	      printf("\n. x_mat=%.1f ymat=%.1f min=%.1f max=%.1f y=%.1f", */
577 /* 		     x_mat,y_mat,min_x,max_x,y); */
578 
579 	      if((min_x < x_mat + eps) && (max_x > x_mat) && (y > y_mat))
580 		{
581 		  tree->ps_tree->cdf_mat[j*(2*tree->n_otu-2)+i] += 1;
582 /* 		  PhyML_Printf("\n. Add 1 to [%.1f,%.1f]", */
583 /* 			       tree->ps_tree->cdf_mat_x[i], */
584 /* 			       tree->ps_tree->cdf_mat_y[j]); */
585 		}
586 	    }
587 	}
588     }
589 }
590 
591 //////////////////////////////////////////////////////////////
592 //////////////////////////////////////////////////////////////
593 
594 //////////////////////////////////////////////////////////////
595 //////////////////////////////////////////////////////////////
596 
597 //////////////////////////////////////////////////////////////
598 //////////////////////////////////////////////////////////////
599 
600 //////////////////////////////////////////////////////////////
601 //////////////////////////////////////////////////////////////
602 
603 //////////////////////////////////////////////////////////////
604 //////////////////////////////////////////////////////////////
605 
606 //////////////////////////////////////////////////////////////
607 //////////////////////////////////////////////////////////////
608 
609 //////////////////////////////////////////////////////////////
610 //////////////////////////////////////////////////////////////
611 
612 //////////////////////////////////////////////////////////////
613 //////////////////////////////////////////////////////////////
614 
615 //////////////////////////////////////////////////////////////
616 //////////////////////////////////////////////////////////////
617 
618 //////////////////////////////////////////////////////////////
619 //////////////////////////////////////////////////////////////
620 
621