| 1 | #include "phylip.h" |
|---|
| 2 | #include "cons.h" |
|---|
| 3 | |
|---|
| 4 | /* version 3.6. (c) Copyright 1993-2002 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, setsz; |
|---|
| 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 | /* printf(" C Consensus type (MRe, strict, Adams, MR, Ml):"); debug */ |
|---|
| 83 | if (strict) |
|---|
| 84 | printf(" strict\n"); |
|---|
| 85 | else if (mr) |
|---|
| 86 | printf(" Majority rule\n"); |
|---|
| 87 | else if (mre) |
|---|
| 88 | printf(" Majority rule (extended)\n"); |
|---|
| 89 | else if (ml) |
|---|
| 90 | printf(" Ml\n"); |
|---|
| 91 | else printf(" Adams\n"); |
|---|
| 92 | if (noroot) { |
|---|
| 93 | printf(" O Outgroup root:"); |
|---|
| 94 | if (outgropt) |
|---|
| 95 | printf(" Yes, at species number%3ld\n", outgrno); |
|---|
| 96 | else |
|---|
| 97 | printf(" No, use as outgroup species%3ld\n", outgrno); |
|---|
| 98 | } |
|---|
| 99 | printf(" R Trees to be treated as Rooted:"); |
|---|
| 100 | if (noroot) |
|---|
| 101 | printf(" No\n"); |
|---|
| 102 | else |
|---|
| 103 | printf(" Yes\n"); |
|---|
| 104 | printf(" T Terminal type (IBM PC, ANSI, none):"); |
|---|
| 105 | if (ibmpc) |
|---|
| 106 | printf(" IBM PC\n"); |
|---|
| 107 | if (ansi) |
|---|
| 108 | printf(" ANSI\n"); |
|---|
| 109 | if (!(ibmpc || ansi)) |
|---|
| 110 | printf(" (none)\n"); |
|---|
| 111 | printf(" 1 Print out the sets of species:"); |
|---|
| 112 | if (prntsets) |
|---|
| 113 | printf(" Yes\n"); |
|---|
| 114 | else |
|---|
| 115 | printf(" No\n"); |
|---|
| 116 | printf(" 2 Print indications of progress of run: %s\n", |
|---|
| 117 | (progress ? "Yes" : "No")); |
|---|
| 118 | printf(" 3 Print out tree:"); |
|---|
| 119 | if (treeprint) |
|---|
| 120 | printf(" Yes\n"); |
|---|
| 121 | else |
|---|
| 122 | printf(" No\n"); |
|---|
| 123 | printf(" 4 Write out trees onto tree file:"); |
|---|
| 124 | if (trout) |
|---|
| 125 | printf(" Yes\n"); |
|---|
| 126 | else |
|---|
| 127 | printf(" No\n"); |
|---|
| 128 | |
|---|
| 129 | printf("\nAre these settings correct? (type Y or the letter for one to change)\n"); |
|---|
| 130 | #ifdef WIN32 |
|---|
| 131 | phyFillScreenColor(); |
|---|
| 132 | #endif |
|---|
| 133 | scanf("%c%*[^\n]", &ch); |
|---|
| 134 | getchar(); |
|---|
| 135 | uppercase(&ch); |
|---|
| 136 | done = (ch == 'Y'); |
|---|
| 137 | if (!done) { |
|---|
| 138 | if ((noroot && (ch == 'O')) || strchr("CRT1234",ch) != NULL) { |
|---|
| 139 | switch (ch) { |
|---|
| 140 | |
|---|
| 141 | case 'C': |
|---|
| 142 | if (strict) { |
|---|
| 143 | strict = false; |
|---|
| 144 | mr = true; |
|---|
| 145 | } else { |
|---|
| 146 | if (ml) { |
|---|
| 147 | ml = false; |
|---|
| 148 | mre = true; |
|---|
| 149 | } else { |
|---|
| 150 | if (mre) { |
|---|
| 151 | mre = false; |
|---|
| 152 | strict = true; |
|---|
| 153 | } else { |
|---|
| 154 | if (mr) { |
|---|
| 155 | mr = false; |
|---|
| 156 | ml = true; |
|---|
| 157 | } |
|---|
| 158 | } |
|---|
| 159 | } |
|---|
| 160 | } |
|---|
| 161 | break; |
|---|
| 162 | |
|---|
| 163 | case 'O': |
|---|
| 164 | outgropt = !outgropt; |
|---|
| 165 | if (outgropt) { |
|---|
| 166 | numopts++; |
|---|
| 167 | loopcount2 = 0; |
|---|
| 168 | do { |
|---|
| 169 | printf("Type number of the outgroup:\n"); |
|---|
| 170 | #ifdef WIN32 |
|---|
| 171 | phyFillScreenColor(); |
|---|
| 172 | #endif |
|---|
| 173 | scanf("%ld%*[^\n]", &outgrno); |
|---|
| 174 | getchar(); |
|---|
| 175 | done1 = (outgrno >= 1); |
|---|
| 176 | if (!done1) { |
|---|
| 177 | printf("ERROR: Bad outgroup number: %ld\n", outgrno); |
|---|
| 178 | printf(" Must be greater than zero\n"); |
|---|
| 179 | } |
|---|
| 180 | countup(&loopcount2, 10); |
|---|
| 181 | } while (done1 != true); |
|---|
| 182 | } |
|---|
| 183 | break; |
|---|
| 184 | |
|---|
| 185 | case 'R': |
|---|
| 186 | noroot = !noroot; |
|---|
| 187 | break; |
|---|
| 188 | |
|---|
| 189 | case 'T': |
|---|
| 190 | initterminal(&ibmpc, &ansi); |
|---|
| 191 | break; |
|---|
| 192 | |
|---|
| 193 | case '1': |
|---|
| 194 | prntsets = !prntsets; |
|---|
| 195 | break; |
|---|
| 196 | |
|---|
| 197 | case '2': |
|---|
| 198 | progress = !progress; |
|---|
| 199 | break; |
|---|
| 200 | |
|---|
| 201 | case '3': |
|---|
| 202 | treeprint = !treeprint; |
|---|
| 203 | break; |
|---|
| 204 | |
|---|
| 205 | case '4': |
|---|
| 206 | trout = !trout; |
|---|
| 207 | break; |
|---|
| 208 | |
|---|
| 209 | } |
|---|
| 210 | } else |
|---|
| 211 | printf("Not a possible option!\n"); |
|---|
| 212 | } |
|---|
| 213 | countup(&loopcount, 100); |
|---|
| 214 | } while (!done); |
|---|
| 215 | if (ml) { |
|---|
| 216 | do { |
|---|
| 217 | printf("\nFraction (l) of times a branch must appear\n"); |
|---|
| 218 | scanf("%lf%*[^\n]", &mlfrac); |
|---|
| 219 | getchar(); |
|---|
| 220 | } while ((mlfrac < 0.5) || (mlfrac > 1.0)); |
|---|
| 221 | } |
|---|
| 222 | } /* getoptions */ |
|---|
| 223 | |
|---|
| 224 | |
|---|
| 225 | void count_siblings(node **p) |
|---|
| 226 | { |
|---|
| 227 | node *tmp_node; |
|---|
| 228 | int i; |
|---|
| 229 | |
|---|
| 230 | if (!(*p)) { |
|---|
| 231 | /* This is a leaf, */ |
|---|
| 232 | return; |
|---|
| 233 | } else { |
|---|
| 234 | tmp_node = (*p)->next; |
|---|
| 235 | } |
|---|
| 236 | |
|---|
| 237 | for (i = 0 ; i < 1000; i++) { |
|---|
| 238 | if (tmp_node == (*p)) { |
|---|
| 239 | /* When we've gone through all the siblings, */ |
|---|
| 240 | break; |
|---|
| 241 | } else if (tmp_node) { |
|---|
| 242 | tmp_node = tmp_node->next; |
|---|
| 243 | } else { |
|---|
| 244 | /* Should this be executed? */ |
|---|
| 245 | return ; |
|---|
| 246 | } |
|---|
| 247 | } |
|---|
| 248 | } /* count_siblings */ |
|---|
| 249 | |
|---|
| 250 | |
|---|
| 251 | void treeout(node *p) |
|---|
| 252 | { |
|---|
| 253 | /* write out file with representation of final tree */ |
|---|
| 254 | long i, n = 0; |
|---|
| 255 | Char c; |
|---|
| 256 | node *q; |
|---|
| 257 | double x; |
|---|
| 258 | |
|---|
| 259 | count_siblings (&p); |
|---|
| 260 | |
|---|
| 261 | if (p->tip) { |
|---|
| 262 | /* If we're at a node which is a leaf, figure out how long the |
|---|
| 263 | name is and print it out. */ |
|---|
| 264 | for (i = 1; i <= MAXNCH; i++) { |
|---|
| 265 | if (p->nayme[i - 1] != '\0') |
|---|
| 266 | n = i; |
|---|
| 267 | } |
|---|
| 268 | for (i = 0; i < n; i++) { |
|---|
| 269 | c = p->nayme[i]; |
|---|
| 270 | if (c == ' ') |
|---|
| 271 | c = '_'; |
|---|
| 272 | putc(c, outtree); |
|---|
| 273 | } |
|---|
| 274 | col += n; |
|---|
| 275 | } else { |
|---|
| 276 | /* If we're at a furcation, print out the proper formatting, loop |
|---|
| 277 | through all the children, calling the procedure recursively. */ |
|---|
| 278 | putc('(', outtree); |
|---|
| 279 | col++; |
|---|
| 280 | q = p->next; |
|---|
| 281 | while (q != p) { |
|---|
| 282 | /* This should terminate when we've gone through all the |
|---|
| 283 | siblings, */ |
|---|
| 284 | treeout(q->back); |
|---|
| 285 | q = q->next; |
|---|
| 286 | if (q == p) |
|---|
| 287 | break; |
|---|
| 288 | putc(',', outtree); |
|---|
| 289 | col++; |
|---|
| 290 | if (col > 60) { |
|---|
| 291 | putc('\n', outtree); |
|---|
| 292 | col = 0; |
|---|
| 293 | } |
|---|
| 294 | } |
|---|
| 295 | putc(')', outtree); |
|---|
| 296 | col++; |
|---|
| 297 | } |
|---|
| 298 | |
|---|
| 299 | if (p->tip) |
|---|
| 300 | x = ntrees; |
|---|
| 301 | else |
|---|
| 302 | x = (double)p->deltav; |
|---|
| 303 | |
|---|
| 304 | if (p == root) { |
|---|
| 305 | /* When we're all done with this tree, */ |
|---|
| 306 | fprintf(outtree, ";\n"); |
|---|
| 307 | return; |
|---|
| 308 | } |
|---|
| 309 | |
|---|
| 310 | /* Figure out how many characters the branch length requires: */ |
|---|
| 311 | else { |
|---|
| 312 | if (!strict) { |
|---|
| 313 | if (x >= 100.0) { |
|---|
| 314 | fprintf(outtree, ":%5.1f", x); |
|---|
| 315 | col += 4; |
|---|
| 316 | } else if (x >= 10.0) { |
|---|
| 317 | fprintf(outtree, ":%4.1f", x); |
|---|
| 318 | col += 3; |
|---|
| 319 | } else if (x >= 0.99) { |
|---|
| 320 | fprintf(outtree, ":%3.1f", x); |
|---|
| 321 | col += 2; |
|---|
| 322 | } else { |
|---|
| 323 | fprintf(outtree, ":%4.2f", x); |
|---|
| 324 | col += 3; |
|---|
| 325 | } |
|---|
| 326 | } |
|---|
| 327 | } |
|---|
| 328 | } /* treeout */ |
|---|
| 329 | |
|---|
| 330 | |
|---|
| 331 | int main(int argc, Char *argv[]) |
|---|
| 332 | { |
|---|
| 333 | /* Local variables added by Dan F. */ |
|---|
| 334 | pattern_elm ***pattern_array; |
|---|
| 335 | double *timesseen_changes = NULL; |
|---|
| 336 | long trees_in = 0; |
|---|
| 337 | long i, j; |
|---|
| 338 | node *p, *q; |
|---|
| 339 | |
|---|
| 340 | #ifdef MAC |
|---|
| 341 | argc = 1; /* macsetup("Consense", ""); */ |
|---|
| 342 | argv[0] = "Consense"; |
|---|
| 343 | #endif |
|---|
| 344 | init(argc, argv); |
|---|
| 345 | openfile(&intree, INTREE, "input tree file", "r", argv[0], intreename); |
|---|
| 346 | openfile(&outfile, OUTFILE, "output file", "w", argv[0], outfilename); |
|---|
| 347 | |
|---|
| 348 | /* Initialize option-based variables, then ask for changes regarding |
|---|
| 349 | their values. */ |
|---|
| 350 | getoptions(); |
|---|
| 351 | |
|---|
| 352 | ntrees = 0.0; |
|---|
| 353 | maxgrp = 32767; /* initial size of set hash table */ |
|---|
| 354 | lasti = -1; |
|---|
| 355 | |
|---|
| 356 | if (trout) |
|---|
| 357 | openfile(&outtree, OUTTREE, "output tree file", "w", argv[0], outtreename); |
|---|
| 358 | if (prntsets) |
|---|
| 359 | fprintf(outfile, "Species in order: \n\n"); |
|---|
| 360 | |
|---|
| 361 | /* Read the tree file and put together grouping, order, and timesseen */ |
|---|
| 362 | read_groups (&pattern_array, timesseen_changes, &trees_in, intree); |
|---|
| 363 | /* Compute the consensus tree. */ |
|---|
| 364 | putc('\n', outfile); |
|---|
| 365 | nodep = (pointarray)Malloc(2*(1+spp)*sizeof(node *)); |
|---|
| 366 | for (i = 0; i < spp; i++) { |
|---|
| 367 | nodep[i] = (node *)Malloc(sizeof(node)); |
|---|
| 368 | for (j = 0; j < MAXNCH; j++) |
|---|
| 369 | nodep[i]->nayme[j] = '\0'; |
|---|
| 370 | strncpy(nodep[i]->nayme, nayme[i], MAXNCH); |
|---|
| 371 | } |
|---|
| 372 | for (i = spp; i < 2*(1+spp); i++) |
|---|
| 373 | nodep[i] = NULL; |
|---|
| 374 | consensus(); |
|---|
| 375 | printf("\n"); |
|---|
| 376 | if (trout) { |
|---|
| 377 | treeout(root); |
|---|
| 378 | if (progress) |
|---|
| 379 | printf("Consensus tree written to file \"%s\"\n\n", outtreename); |
|---|
| 380 | } |
|---|
| 381 | if (progress) |
|---|
| 382 | printf("Output written to file \"%s\"\n\n", outfilename); |
|---|
| 383 | for (i = 0; i < spp; i++) |
|---|
| 384 | free(nodep[i]); |
|---|
| 385 | for (i = spp; i < 2*(1 + spp); i++) { |
|---|
| 386 | if (nodep[i] != NULL) { |
|---|
| 387 | p = nodep[i]->next; |
|---|
| 388 | do { |
|---|
| 389 | q = p->next; |
|---|
| 390 | free(p); |
|---|
| 391 | p = q; |
|---|
| 392 | } while (p != nodep[i]); |
|---|
| 393 | free(p); |
|---|
| 394 | } |
|---|
| 395 | } |
|---|
| 396 | free(nodep); |
|---|
| 397 | FClose(outtree); |
|---|
| 398 | FClose(intree); |
|---|
| 399 | FClose(outfile); |
|---|
| 400 | |
|---|
| 401 | #ifdef MAC |
|---|
| 402 | fixmacfile(outfilename); |
|---|
| 403 | fixmacfile(outtreename); |
|---|
| 404 | #endif |
|---|
| 405 | printf("Done.\n\n"); |
|---|
| 406 | |
|---|
| 407 | #ifdef WIN32 |
|---|
| 408 | phyRestoreConsoleAttributes(); |
|---|
| 409 | #endif |
|---|
| 410 | |
|---|
| 411 | return 0; |
|---|
| 412 | } /* main */ |
|---|
| 413 | |
|---|