initial commit
[jalview.git] / forester / archive / RIO / others / phylip_mod / src / consense.c
1 #include "phylip.h"
2 #include "cons.h"
3
4 /* version 3.6. (c) Copyright 1993-2004 by the University of Washington.
5    Written by Joseph Felsenstein, Hisashi Horino,
6    Akiko Fuseki, Dan Fineman, Sean Lamont, and Andrew Keeffe.
7    Permission is granted
8    to copy and use this program provided no fee is charged for it and
9    provided that this copyright notice is not removed. */
10
11
12 /* The following extern's refer to things declared in cons.c */
13
14 extern int tree_pairing;
15
16 extern Char outfilename[FNMLNGTH], intreename[FNMLNGTH], intree2name[FNMLNGTH], outtreename[FNMLNGTH];
17 extern node *root;
18
19 extern long numopts, outgrno, col;
20 extern long maxgrp;               /* max. no. of groups in all trees found  */
21
22 extern boolean trout, firsttree, noroot, outgropt, didreroot, prntsets,
23           progress, treeprint, goteof, strict, mr, mre, ml;
24 extern pointarray nodep;                 /* pointers to all nodes in tree */
25 extern group_type **grouping, **grping2, **group2;/* to store groups found  */
26 extern long **order, **order2, lasti;
27 extern group_type *fullset;
28 extern long tipy;
29
30 extern double trweight, ntrees, mlfrac;
31
32 #ifndef OLDC
33 /* function prototypes */
34 void   getoptions(void);
35 void   count_siblings(node **p);
36 void   treeout(node *);
37 /* function prototypes */
38 #endif
39
40
41 void getoptions()
42 {
43   /* interactively set options */
44   long loopcount, loopcount2;
45   Char ch;
46   boolean done, done1;
47
48   /* Initial settings */
49   ibmpc          = IBMCRT;
50   ansi           = ANSICRT;
51   didreroot      = false;
52   firsttree      = true;
53   spp            = 0 ;
54   col            = 0 ;
55
56   /* This is needed so functions in cons.c work */
57   tree_pairing   = NO_PAIRING ;  
58
59   fprintf(outfile, "\nConsensus tree");
60   fprintf(outfile, " program, version %s\n\n", VERSION);
61   putchar('\n');
62   strict = false;
63   mr = false;
64   mre = true;
65   ml = false;
66   mlfrac = 0.5;
67   noroot = true;
68   numopts = 0;
69   outgrno = 1;
70   outgropt = false;
71   trout = true;
72   prntsets = true;
73   progress = true;
74   treeprint = true;
75   loopcount = 0;
76   do {
77     cleerhome();
78     printf("\nConsensus tree");
79     printf(" program, version %s\n\n", VERSION);
80     printf("Settings for this run:\n");
81     printf(" C         Consensus type (MRe, strict, MR, Ml):");
82     if (strict)
83       printf("  strict\n");
84     else if (mr)
85         printf("  Majority rule\n");
86       else if (mre)
87           printf("  Majority rule (extended)\n");
88         else if (ml)
89             printf("  Ml\n");
90           else printf("  Adams\n");
91     if (noroot) {
92       printf(" O                                Outgroup root:");
93       if (outgropt)
94         printf("  Yes, at species number%3ld\n", outgrno);
95       else
96         printf("  No, use as outgroup species%3ld\n", outgrno);
97       }
98     printf(" R                Trees to be treated as Rooted:");
99     if (noroot)
100       printf("  No\n");
101     else
102       printf("  Yes\n");
103     printf(" T           Terminal type (IBM PC, ANSI, none):");
104     if (ibmpc)
105       printf("  IBM PC\n");
106     if (ansi)
107       printf("  ANSI\n");
108     if (!(ibmpc || ansi))
109       printf("  (none)\n");
110     printf(" 1                Print out the sets of species:");
111     if (prntsets)
112       printf("  Yes\n");
113     else
114       printf("  No\n");
115     printf(" 2         Print indications of progress of run:  %s\n",
116            (progress ? "Yes" : "No"));
117     printf(" 3                               Print out tree:");
118     if (treeprint)
119       printf("  Yes\n");
120     else
121       printf("  No\n");
122     printf(" 4               Write out trees onto tree file:");
123     if (trout)
124       printf("  Yes\n");
125     else
126       printf("  No\n");
127
128     printf("\nAre these settings correct? (type Y or the letter for one to change)\n");
129 #ifdef WIN32
130     phyFillScreenColor();
131 #endif
132     scanf("%c%*[^\n]", &ch);
133     getchar();
134     uppercase(&ch);
135     done = (ch == 'Y');
136     if (!done) {
137       if ((noroot && (ch == 'O')) || strchr("CRT1234",ch) != NULL) {
138         switch (ch) {
139
140         case 'C':
141           if (strict) {
142             strict = false;
143             mr = true;
144           } else {
145             if (ml) {
146               ml = false;
147               mre = true;
148             } else {
149               if (mre) {
150                 mre = false;
151                 strict = true;
152               } else {
153                 if (mr) {
154                   mr = false;
155                   ml = true;
156                 }
157               }
158             }
159           }
160           break;
161
162         case 'O':
163           outgropt = !outgropt;
164           if (outgropt) {
165             numopts++;
166             loopcount2 = 0;
167             do {
168               printf("Type number of the outgroup:\n");
169 #ifdef WIN32
170               phyFillScreenColor();
171 #endif
172               scanf("%ld%*[^\n]", &outgrno);
173               getchar();
174               done1 = (outgrno >= 1);
175               if (!done1) {
176                 printf("ERROR: Bad outgroup number: %ld\n", outgrno);
177                 printf("  Must be greater than zero\n");
178               }
179             countup(&loopcount2, 10);
180             } while (done1 != true);
181           }
182           break;
183
184         case 'R':
185           noroot = !noroot;
186           break;
187
188         case 'T':
189           initterminal(&ibmpc, &ansi);
190           break;
191
192         case '1':
193           prntsets = !prntsets;
194           break;
195
196         case '2':
197           progress = !progress;
198           break;
199         
200         case '3':
201           treeprint = !treeprint;
202           break;
203
204         case '4':
205           trout = !trout;
206           break;
207
208         }
209       } else
210         printf("Not a possible option!\n");
211     }
212     countup(&loopcount, 100);
213   } while (!done);
214   if (ml) {
215     do {
216       printf("\nFraction (l) of times a branch must appear\n");
217       scanf("%lf%*[^\n]", &mlfrac);
218       getchar();
219     } while ((mlfrac < 0.5) || (mlfrac > 1.0));
220   }
221 }  /* getoptions */
222
223
224 void count_siblings(node **p)
225 {
226   node *tmp_node;
227   int i;
228
229   if (!(*p)) {
230     /* This is a leaf, */
231     return;
232   } else {
233     tmp_node = (*p)->next;
234   }
235
236   for (i = 0 ; i < 1000; i++) {
237     if (tmp_node == (*p)) {
238       /* When we've gone through all the siblings, */
239       break;
240     } else if (tmp_node) {
241       tmp_node = tmp_node->next;
242     } else  {
243       /* Should this be executed? */
244       return ;
245     }
246   }
247 } /* count_siblings */
248
249
250 void treeout(node *p)
251 {
252   /* write out file with representation of final tree */
253   long i, n = 0;
254   Char c;
255   node *q;
256   double x;
257
258   count_siblings (&p);  
259
260   if (p->tip) {
261     /* If we're at a node which is a leaf, figure out how long the
262        name is and print it out. */
263     for (i = 1; i <= MAXNCH; i++) {
264       if (p->nayme[i - 1] != '\0')
265         n = i;
266     }
267     for (i = 0; i < n; i++) {
268       c = p->nayme[i];
269       if (c == ' ')
270         c = '_';
271       putc(c, outtree);
272     }
273     col += n;
274   } else {
275     /* If we're at a furcation, print out the proper formatting, loop
276        through all the children, calling the procedure recursively. */
277     putc('(', outtree);
278     col++;
279     q = p->next;
280     while (q != p) {
281       /* This should terminate when we've gone through all the
282          siblings, */
283       treeout(q->back);
284       q = q->next;
285       if (q == p)
286         break;
287       putc(',', outtree);
288       col++;
289       if (col > 60) {
290         putc('\n', outtree);
291         col = 0;
292       }
293     }
294     putc(')', outtree);
295     col++;
296   }
297
298   if (p->tip)
299     x = ntrees;
300   else
301     x = (double)p->deltav;
302
303   if (p == root) {
304     /* When we're all done with this tree, */
305     fprintf(outtree, ";\n");
306     return;
307   }
308
309   /* Figure out how many characters the branch length requires: */
310   else {
311     if (!strict) {
312       if (x >= 100.0) { 
313         fprintf(outtree, ":%5.1f", x);
314         col += 4;
315       } else if (x >= 10.0) {
316           fprintf(outtree, ":%4.1f", x); 
317           col += 3;
318         } else if (x >= 0.99) {
319             fprintf(outtree, ":%3.1f", x);
320             col += 2;
321           } else {
322             fprintf(outtree, ":%4.2f", x); 
323             col += 3;
324           }
325     }
326   }
327 }  /* treeout */
328
329
330 int main(int argc, Char *argv[])
331 {  
332   /* Local variables added by Dan F. */
333   pattern_elm  ***pattern_array;
334   double *timesseen_changes = NULL;
335   long trees_in = 0;
336   long i, j;
337   node *p, *q;
338
339 #ifdef MAC
340   argc = 1;                /* macsetup("Consense", "");        */
341   argv[0] = "Consense";
342 #endif
343   init(argc, argv);
344   openfile(&intree, INTREE, "input tree file", "r", argv[0], intreename);
345   openfile(&outfile, OUTFILE, "output file", "w", argv[0], outfilename);
346
347   /* Initialize option-based variables, then ask for changes regarding
348      their values. */
349   getoptions();
350
351   ntrees = 0.0;
352   maxgrp = 32767;   /* initial size of set hash table */
353   lasti  = -1;
354
355   if (trout) 
356     openfile(&outtree, OUTTREE, "output tree file", "w", argv[0], outtreename);
357   if (prntsets)
358     fprintf(outfile, "Species in order: \n\n");
359
360   trees_in = countsemic(&intree);
361
362   /* Read the tree file and put together grouping, order, and timesseen */
363   read_groups (&pattern_array, timesseen_changes, trees_in, trees_in, intree);
364   /* Compute the consensus tree. */
365   putc('\n', outfile);
366   nodep      = (pointarray)Malloc(2*(1+spp)*sizeof(node *));
367   for (i = 0; i < spp; i++) {
368     nodep[i] = (node *)Malloc(sizeof(node));
369     for (j = 0; j < MAXNCH; j++)
370       nodep[i]->nayme[j] = '\0';
371     strncpy(nodep[i]->nayme, nayme[i], MAXNCH);
372   }
373   for (i = spp; i < 2*(1+spp); i++)
374     nodep[i] = NULL;
375   consensus(pattern_array, trees_in);
376   printf("\n");
377   if (trout) {
378     treeout(root);
379     if (progress)
380       printf("Consensus tree written to file \"%s\"\n\n", outtreename);
381   }
382   if (progress)
383     printf("Output written to file \"%s\"\n\n", outfilename);
384   for (i = 0; i < spp; i++)
385     free(nodep[i]);
386   for (i = spp; i < 2*(1 + spp); i++) {
387     if (nodep[i] != NULL) {
388       p = nodep[i]->next;
389       do {
390         q = p->next;
391         free(p);
392         p = q;
393       } while (p != nodep[i]);
394       free(p);
395     }
396   }
397   free(nodep);
398   FClose(outtree);
399   FClose(intree);
400   FClose(outfile);
401
402 #ifdef MAC
403   fixmacfile(outfilename);
404   fixmacfile(outtreename);
405 #endif
406 printf("Done.\n\n");
407
408 #ifdef WIN32
409   phyRestoreConsoleAttributes();
410 #endif
411
412 return 0;
413 }  /* main */
414