source: trunk/GDE/PHYLIP/dnacomp.c

Last change on this file was 19480, checked in by westram, 15 months ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.0 KB
Line 
1
2#include "phylip.h"
3#include "seq.h"
4
5/* version 3.6. (c) Copyright 1993-2002 by the University of Washington.
6   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, and Andrew Keeffe.
7   Permission is granted to copy and use this program provided no fee is
8   charged for it and provided that this copyright notice is not removed. */
9
10#define maxtrees        100   /* maximum number of tied trees stored     */
11
12typedef boolean *boolptr;
13
14#ifndef OLDC
15/* function prototypes */
16void   getoptions(void);
17void   allocrest(void);
18void   doinit(void);
19void   initdnacompnode(node **, node **, node *, long, long, long *,
20               long *, initops, pointarray, pointarray, Char *, Char *, FILE *);
21void   makeweights(void);
22void   doinput(void);
23void   mincomp(long );
24void   evaluate(node *);
25void   localsavetree(void);
26
27void   tryadd(node *, node *, node *);
28void   addpreorder(node *, node *, node *);
29void   tryrearr(node *, boolean *);
30void   repreorder(node *, boolean *);
31void   rearrange(node **);
32void   describe(void);
33void   initboolnames(node *, boolean *);
34void   maketree(void);
35void   freerest(void);
36void   standev3(long, long, long, double, double *, long **, longer);
37void   reallocchars(void);
38/* function prototypes */
39#endif
40
41
42extern sequence y;
43Char infilename[FNMLNGTH], outfilename[FNMLNGTH], intreename[FNMLNGTH], outtreename[FNMLNGTH], weightfilename[FNMLNGTH];
44node *root;
45long chars, col, ith, njumble, jumb, msets;
46long inseed, inseed0;
47boolean jumble, usertree, trout, weights,
48               progress, stepbox, ancseq, firstset, mulsets, justwts;
49steptr oldweight, necsteps;
50pointarray treenode;   /* pointers to all nodes in tree */
51long *enterorder;
52Char basechar[32]="ACMGRSVTWYHKDBNO???????????????";
53bestelm *bestrees;
54boolean dummy;
55longer seed;
56gbases *garbage;
57Char global_ch;
58Char progname[20];
59long *zeros;
60
61/* Local variables for maketree, propogated globally for C version: */
62  long global_maxwhich;
63  double like, global_maxsteps, bestyet, bestlike, bstlike2;
64  boolean lastrearr, recompute;
65  double global_nsteps[maxuser];
66  long **global_fsteps;
67  node *there;
68  long *place;
69  boolptr in_tree;
70  baseptr nothing;
71  node *global_temp, *global_temp1;
72  node *grbg;
73
74void getoptions()
75{
76  /* interactively set options */
77  long loopcount, loopcount2;
78  Char ch, ch2;
79
80  fprintf(outfile, "\nDNA compatibility algorithm, version %s\n\n",VERSION);
81  putchar('\n');
82  jumble = false;
83  njumble = 1;
84  outgrno = 1;
85  outgropt = false;
86  trout = true;
87  usertree = false;
88  weights = false;
89  justwts = false;
90  printdata = false;
91  progress = true;
92  treeprint = true;
93  stepbox = false;
94  ancseq = false;
95  interleaved = true;
96  loopcount = 0;
97  for (;;) {
98    cleerhome();
99    printf("\nDNA compatibility algorithm, version %s\n\n",VERSION);
100    printf("Settings for this run:\n");
101    printf("  U                 Search for best tree?  %s\n",
102           (usertree ? "No, use user trees in input file" : "Yes"));
103    if (!usertree) {
104      printf("  J   Randomize input order of sequences?");
105      if (jumble) {
106        printf(
107         "  Yes (seed =%8ld,%3ld times)\n", inseed0, njumble);
108      }
109      else
110        printf("  No. Use input order\n");
111    }
112    printf("  O                        Outgroup root?");
113    if (outgropt)
114      printf("  Yes, at sequence number%3ld\n", outgrno);
115    else
116      printf("  No, use as outgroup species%3ld\n", outgrno);
117    printf("  W                       Sites weighted?  %s\n",
118           (weights ? "Yes" : "No"));
119    printf("  M           Analyze multiple data sets?");
120    if (mulsets)
121      printf("  Yes, %2ld %s\n", msets,
122               (justwts ? "sets of weights" : "data sets"));
123    else
124      printf("  No\n");
125    printf("  I          Input sequences interleaved?  %s\n",
126           (interleaved ? "Yes" : "No, sequential"));
127    printf("  0   Terminal type (IBM PC, ANSI, none)?  %s\n",
128           ibmpc ? "IBM PC" : ansi  ? "ANSI"   : "(none)");
129    printf("  1    Print out the data at start of run  %s\n",
130           (printdata ? "Yes" : "No"));
131    printf("  2  Print indications of progress of run  %s\n",
132           (progress ? "Yes" : "No"));
133    printf("  3                        Print out tree  %s\n",
134           (treeprint ? "Yes" : "No"));
135    printf("  4  Print steps & compatibility at sites  %s\n",
136           (stepbox ? "Yes" : "No"));
137    printf("  5  Print sequences at all nodes of tree  %s\n",
138           (ancseq ? "Yes" : "No"));
139    printf("  6       Write out trees onto tree file?  %s\n",
140           (trout ? "Yes" : "No"));
141    if(weights && justwts){
142      printf(
143         "WARNING:  W option and Multiple Weights options are both on.  ");
144      printf(
145         "The W menu option is unnecessary and has no additional effect. \n");
146    }
147    printf("\nAre these settings correct? (type Y or the letter for one to change)\n");
148#ifdef WIN32
149    phyFillScreenColor();
150#endif
151    scanf("%c%*[^\n]", &ch);
152    getchar();
153    uppercase(&ch);
154    if (ch == 'Y')
155      break;
156    if (strchr("WJOTUMI1234560",ch) != NULL){
157      switch (ch) {
158
159      case 'J':
160        jumble = !jumble;
161        if (jumble)
162          initjumble(&inseed, &inseed0, seed, &njumble);
163        else njumble = 1;
164        break;
165
166      case 'O':
167        outgropt = !outgropt;
168        if (outgropt)
169          initoutgroup(&outgrno, spp);
170        break;
171
172      case 'U':
173        usertree = !usertree;
174        break;
175
176      case 'M':
177        mulsets = !mulsets;
178        if (mulsets){
179          printf("Multiple data sets or multiple weights?");
180          loopcount2 = 0;
181          do {
182            printf(" (type D or W)\n");
183#ifdef WIN32
184            phyFillScreenColor();
185#endif
186            scanf("%c%*[^\n]", &ch2);
187            getchar();
188            if (ch2 == '\n')
189              ch2 = ' ';
190            uppercase(&ch2);
191            countup(&loopcount2, 10);
192          } while ((ch2 != 'W') && (ch2 != 'D'));
193          justwts = (ch2 == 'W');
194          if (justwts)
195            justweights(&msets);
196          else
197            initdatasets(&msets);
198          if (!jumble) {
199            jumble = true;
200            initjumble(&inseed, &inseed0, seed, &njumble);
201          }
202        }
203        break;
204
205      case 'I':
206        interleaved = !interleaved;
207        break;
208
209      case 'W':
210        weights = !weights;
211        break;
212
213      case '0':
214        initterminal(&ibmpc, &ansi);
215        break;
216
217      case '1':
218        printdata = !printdata;
219        break;
220
221      case '2':
222        progress = !progress;
223        break;
224
225      case '3':
226        treeprint = !treeprint;
227        break;
228
229      case '4':
230        stepbox = !stepbox;
231        break;
232
233      case '5':
234        ancseq = !ancseq;
235        break;
236
237      case '6':
238        trout = !trout;
239        break;
240      }
241    } else
242      printf("Not a possible option!\n");
243    countup(&loopcount, 100);
244  }
245}  /* getoptions */
246
247
248void reallocchars(void) 
249{/* The amount of chars can change between runs
250     this function reallocates all the variables
251     whose size depends on the amount of chars */
252  long i;
253
254  for (i = 0; i < spp; i++) {
255    free(y[i]);
256    y[i] = (Char *)Malloc(chars*sizeof(Char));
257  }
258  free(weight);
259  free(oldweight);
260  free(enterorder);
261  free(necsteps);
262  free(alias);
263  free(ally);
264  free(location);
265  free(in_tree);
266
267  weight = (steptr)Malloc(chars*sizeof(long));
268  oldweight = (steptr)Malloc(chars*sizeof(long));
269  enterorder = (long *)Malloc(spp*sizeof(long));
270  necsteps = (steptr)Malloc(chars*sizeof(long));
271  alias = (steptr)Malloc(chars*sizeof(long));
272  ally = (steptr)Malloc(chars*sizeof(long));
273  location = (steptr)Malloc(chars*sizeof(long));
274  in_tree = (boolptr)Malloc(chars*sizeof(boolean));
275}
276
277
278void allocrest()
279{
280  long i;
281
282  y = (Char **)Malloc(spp*sizeof(Char *));
283  for (i = 0; i < spp; i++)
284    y[i] = (Char *)Malloc(chars*sizeof(Char));
285  bestrees = (bestelm *) Malloc(maxtrees*sizeof(bestelm));
286  for (i = 1; i <= maxtrees; i++)
287    bestrees[i - 1].btree = (long *)Malloc(nonodes*sizeof(long));
288  nayme = (naym *)Malloc(spp*sizeof(naym));
289  weight = (steptr)Malloc(chars*sizeof(long));
290  oldweight = (steptr)Malloc(chars*sizeof(long));
291  enterorder = (long *)Malloc(spp*sizeof(long));
292  necsteps = (steptr)Malloc(chars*sizeof(long));
293  alias = (steptr)Malloc(chars*sizeof(long));
294  ally = (steptr)Malloc(chars*sizeof(long));
295  location = (steptr)Malloc(chars*sizeof(long));
296  place = (long *)Malloc((2*spp-1)*sizeof(long));
297  in_tree = (boolptr)Malloc(chars*sizeof(boolean));
298}  /* allocrest */
299
300
301void doinit()
302{
303  /* initializes variables */
304
305  inputnumbers(&spp, &chars, &nonodes, 1);
306  getoptions();
307  if (printdata)
308    fprintf(outfile, "%2ld species, %3ld  sites\n", spp, chars);
309  alloctree(&treenode, nonodes, usertree);
310  allocrest();
311}  /* doinit */
312
313
314void initdnacompnode(node **p, node **local_grbg, node *UNUSED_q, long UNUSED_len, long nodei,
315                     long *UNUSED_ntips, long *parens, initops whichinit,
316                     pointarray local_treenode, pointarray UNUSED_nodep, Char *str, Char *ch,
317                     FILE *fp_intree)
318{
319    (void)UNUSED_q;
320    (void)UNUSED_len;
321    (void)UNUSED_ntips;
322    (void)UNUSED_nodep;
323
324  /* initializes a node */
325  boolean minusread;
326  double valyew, divisor;
327
328
329  switch (whichinit) {
330  case bottom:
331    gnutreenode(local_grbg, p, nodei, endsite, zeros);
332    local_treenode[nodei - 1] = *p;
333    break;
334  case nonbottom:
335    gnutreenode(local_grbg, p, nodei, endsite, zeros);
336    break;
337  case tip:
338    match_names_to_data (str, local_treenode, p, spp);
339    break;
340  case length:
341    processlength(&valyew, &divisor, ch, &minusread, fp_intree, parens);
342    /* process and discard lengths */
343  default:
344    break;
345  }
346} /* initdnacompnode */
347
348
349void makeweights()
350{
351  /* make up weights vector to avoid duplicate computations */
352  long i;
353
354  for (i = 1; i <= chars; i++) {
355    alias[i - 1] = i;
356    oldweight[i - 1] = weight[i - 1];
357    ally[i - 1] = i;
358  }
359  sitesort(chars, weight);
360  sitecombine(chars);
361  sitescrunch(chars);
362  endsite = 0;
363  for (i = 1; i <= chars; i++) {
364    if (ally[i - 1] == i)
365      endsite++;
366  }
367  for (i = 1; i <= endsite; i++)
368    location[alias[i - 1] - 1] = i;
369  zeros = (long *)Malloc(endsite*sizeof(long));
370  for (i = 0; i < endsite; i++)
371    zeros[i] = 0;
372}  /* makeweights */
373
374
375void doinput()
376{
377  /* reads the input data */
378
379  long i;
380
381  if (justwts) {
382    if (firstset)
383      inputdata(chars);
384    for (i = 0; i < chars; i++)
385      weight[i] = 1;
386    inputweights(chars, weight, &weights);
387    if (justwts) {
388      fprintf(outfile, "\n\nWeights set # %ld:\n\n", ith);
389      if (progress)
390        printf("\nWeights set # %ld:\n\n", ith);
391    }
392    if (printdata)
393      printweights(outfile, 0, chars, weight, "Sites");
394  } else {
395    if (!firstset){
396      samenumsp(&chars, ith);
397      reallocchars();
398    }
399    inputdata(chars);
400    for (i = 0; i < chars; i++)
401      weight[i] = 1;
402    if (weights) {
403      inputweights(chars, weight, &weights);
404      if (printdata)
405        printweights(outfile, 0, chars, weight, "Sites");
406    }
407  }
408  makeweights();
409  makevalues(treenode, zeros, usertree);
410  allocnode(&global_temp, zeros, endsite);
411  allocnode(&global_temp1, zeros, endsite);
412}  /* doinput */
413
414
415void mincomp(long n)
416{
417  /* computes for each site the minimum number of steps
418    necessary to accomodate those species already
419    in the analysis, adding in species n */
420  long i, j, k, l, m;
421  bases b;
422  long s;
423  boolean allowable, deleted;
424
425  in_tree[n - 1] = true;
426  for (i = 0; i < endsite; i++)
427    necsteps[i] = 3;
428  for (m = 0; m <= 31; m++) {
429    s = 0;
430    l = -1;
431    k = m;
432    for (b = A; (long)b <= (long)O; b = (bases)((long)b + 1)) {
433      if ((k & 1) == 1) {
434        s |= 1L << ((long)b);
435        l++;
436      }
437      k /= 2;
438    }
439    for (j = 0; j < endsite; j++) {
440      allowable = true;
441      i = 1;
442      while (allowable && i <= spp) {
443        if (in_tree[i - 1] && treenode[i - 1]->base[j] != 0) {
444          if ((treenode[i - 1]->base[j] & s) == 0)
445            allowable = false;
446        }
447        i++;
448      }
449      if (allowable) {
450        if (l < necsteps[j])
451          necsteps[j] = l;
452      }
453    }
454  }
455  for (j = 0; j < endsite; j++) {
456    deleted = false;
457    for (i = 0; i < spp; i++) {
458      if (in_tree[i] && treenode[i]->base[j] == 0)
459        deleted = true;
460    }
461    if (deleted)
462      necsteps[j]++;
463  }
464  for (i = 0; i < endsite; i++)
465    necsteps[i] *= weight[i];
466}  /* mincomp */
467
468
469void evaluate(node *r)
470{
471  /* determines the number of steps needed for a tree. this is
472    the minimum number of steps needed to evolve sequences on
473    this tree */
474  long i, term;
475  double sum;
476
477   sum = 0.0;
478   for (i = 0; i < endsite; i++) {
479    if (r->numsteps[i] == necsteps[i])
480      term = weight[i];
481    else
482      term = 0;
483    sum += term;
484    if (usertree && which <= maxuser)
485      global_fsteps[which - 1][i] = term;
486  }
487  if (usertree && which <= maxuser) {
488    global_nsteps[which - 1] = sum;
489    if (which == 1) {
490      global_maxwhich = 1;
491      global_maxsteps = sum;
492    } else if (sum > global_maxsteps) {
493      global_maxwhich = which;
494      global_maxsteps = sum;
495    }
496  }
497  like = sum;
498}  /* evaluate */
499
500
501void localsavetree()
502{
503  /* record in place where each species has to be
504    added to reconstruct this tree */
505  long i, j;
506  node *p;
507  boolean done;
508
509  reroot(treenode[outgrno - 1], root);
510  savetraverse(root);
511  for (i = 0; i < nonodes; i++)
512    place[i] = 0;
513  place[root->index - 1] = 1;
514  for (i = 1; i <= spp; i++) {
515    p = treenode[i - 1];
516    while (place[p->index - 1] == 0) {
517      place[p->index - 1] = i;
518      while (!p->bottom)
519        p = p->next;
520      p = p->back;
521    }
522    if (i > 1) {
523      place[i - 1] = place[p->index - 1];
524      j = place[p->index - 1];
525      done = false;
526      while (!done) {
527        place[p->index - 1] = spp + i - 1;
528        while (!p->bottom)
529          p = p->next;
530        p = p->back;
531        done = (p == NULL);
532        if (!done)
533          done = (place[p->index - 1] != j);
534      }
535    }
536  }
537}  /* localsavetree */
538
539
540void tryadd(node *p, node *item, node *nufork)
541{
542  /* temporarily adds one fork and one tip to the tree.
543    if the location where they are added yields greater
544    "likelihood" than other locations tested up to that
545    time, then keeps that location as there */
546  long pos;
547  boolean found;
548  node *rute, *q;
549
550  if (p == root)
551    fillin(global_temp, item, p);
552  else {
553    fillin(global_temp1, item, p);
554    fillin(global_temp, global_temp1, p->back);
555  }
556  evaluate(global_temp);
557  if (lastrearr) {
558    if (like < bestlike) {
559      if (item == nufork->next->next->back) {
560        q = nufork->next;
561        nufork->next = nufork->next->next;
562        nufork->next->next = q;
563        q->next = nufork;
564      }
565    } else if (like >= bstlike2) {
566      recompute = false;
567      add(p, item, nufork, &root, recompute, treenode, &grbg, zeros);
568      rute = root->next->back;
569      localsavetree();
570      reroot(rute, root);
571      if (like > bstlike2) {
572        bestlike = bstlike2 = like;
573        pos = 1;
574        nextree = 1;
575        addtree(pos, &nextree, dummy, place, bestrees);
576      } else {
577        pos = 0;
578        findtree(&found, &pos, nextree, place, bestrees);
579        if (!found) {
580          if (nextree <= maxtrees)
581            addtree(pos, &nextree, dummy, place, bestrees);
582        }
583      }
584      re_move(item, &nufork, &root, recompute, treenode, &grbg, zeros);
585      recompute = true;
586    }
587  }
588  if (like > bestyet) {
589    bestyet = like;
590    there = p;
591  }
592}  /* tryadd */
593
594
595void addpreorder(node *p, node *item, node *nufork)
596{
597  /* traverses a binary tree, calling PROCEDURE tryadd
598    at a node before calling tryadd at its descendants */
599
600  if (p == NULL)
601    return;
602  tryadd(p, item, nufork);
603  if (!p->tip) {
604    addpreorder(p->next->back, item, nufork);
605    addpreorder(p->next->next->back, item, nufork);
606  }
607}  /* addpreorder */
608
609
610void tryrearr(node *p, boolean *success)
611{
612  /* evaluates one rearrangement of the tree.
613    if the new tree has greater "likelihood" than the old
614    one sets success := TRUE and keeps the new tree.
615    otherwise, restores the old tree */
616  node *frombelow, *whereto, *forknode, *q;
617  double oldlike;
618
619  if (p->back == NULL)
620    return;
621  forknode = treenode[p->back->index - 1];
622  if (forknode->back == NULL)
623    return;
624  oldlike = bestyet;
625  if (p->back->next->next == forknode)
626    frombelow = forknode->next->next->back;
627  else
628    frombelow = forknode->next->back;
629  whereto = treenode[forknode->back->index - 1];
630  if (whereto->next->back == forknode)
631    q = whereto->next->next->back;
632  else
633    q = whereto->next->back;
634  fillin(global_temp1, frombelow, q);
635  fillin(global_temp, global_temp1, p);
636  fillin(global_temp1, global_temp, whereto->back);
637  evaluate(global_temp1);
638  if (like <= oldlike) {
639    if (p != forknode->next->next->back)
640      return;
641    q = forknode->next;
642    forknode->next = forknode->next->next;
643    forknode->next->next = q;
644    q->next = forknode;
645    return;
646  }
647  recompute = false;
648  re_move(p, &forknode, &root, recompute, treenode, &grbg, zeros);
649  fillin(whereto, whereto->next->back, whereto->next->next->back);
650  recompute = true;
651  add(whereto, p, forknode, &root, recompute, treenode, &grbg, zeros);
652  *success = true;
653  bestyet = like;
654}  /* tryrearr */
655
656
657void repreorder(node *p, boolean *success)
658{
659  /* traverses a binary tree, calling PROCEDURE tryrearr
660    at a node before calling tryrearr at its descendants */
661  if (p == NULL)
662    return;
663  tryrearr(p,success);
664  if (!p->tip) {
665    repreorder(p->next->back,success);
666    repreorder(p->next->next->back,success);
667  }
668}  /* repreorder */
669
670
671void rearrange(node **r)
672{
673  /* traverses the tree (preorder), finding any local
674    rearrangement which decreases the number of steps.
675    if traversal succeeds in increasing the tree's
676    "likelihood", PROCEDURE rearrange runs traversal again */
677  boolean success=true;
678
679  while (success) {
680    success = false;
681    repreorder(*r,&success);
682  }
683}  /* rearrange */
684
685
686void describe()
687{
688  /* prints ancestors, steps and table of numbers of steps in
689    each site and table of compatibilities */
690  long i, j, k;
691
692  if (treeprint) {
693    fprintf(outfile, "\ntotal number of compatible sites is ");
694    fprintf(outfile, "%10.1f\n", like);
695  }
696  if (stepbox) {
697    writesteps(chars, weights, oldweight, root);
698    fprintf(outfile,
699            "\n compatibility (Y or N) of each site with this tree:\n\n");
700    fprintf(outfile, "      ");
701    for (i = 0; i <= 9; i++)
702      fprintf(outfile, "%ld", i);
703    fprintf(outfile, "\n     *----------\n");
704    for (i = 0; i <= (chars / 10); i++) {
705      putc(' ', outfile);
706      fprintf(outfile, "%3ld !", i * 10);
707      for (j = 0; j <= 9; j++) {
708        k = i * 10 + j;
709        if (k > 0 && k <= chars) {
710          if (root->numsteps[location[ally[k - 1] - 1] - 1] ==
711              necsteps[location[ally[k - 1] - 1] - 1]) {
712            if (oldweight[k - 1] > 0)
713              putc('Y', outfile);
714            else
715              putc('y', outfile);
716          } else {
717            if (oldweight[k - 1] > 0)
718              putc('N', outfile);
719            else
720              putc('n', outfile);
721          }
722        } else
723          putc(' ', outfile);
724      }
725      putc('\n', outfile);
726    }
727  }
728  if (ancseq) {
729    hypstates(chars, root, treenode, &garbage, basechar);
730    putc('\n', outfile);
731  }
732  putc('\n', outfile);
733  if (trout) {
734    col = 0;
735    treeout(root, nextree, &col, root);
736  }
737}  /* describe */
738
739
740void initboolnames(node *p, boolean *names)
741{
742  /* sets BOOLEANs that indicate tips */
743  node *q;
744
745  if (p->tip) {
746    names[p->index - 1] = true;
747    return;
748  }
749  q = p->next;
750  while (q != p) {
751    initboolnames(q->back, names);
752    q = q->next;
753  }
754}  /* initboolnames */
755
756
757void standev3(long local_chars, long numtrees, long maxwhich, double maxsteps,
758              double *nsteps, long **fsteps, longer local_seed)
759{  /* compute and write standard deviation of user trees */
760  long i, j, k;
761  double wt, sumw, sum, sum2, sd;
762  double temp;
763  double **covar, *P, *f;
764
765#define SAMPLES 1000
766#define MAXSHIMOTREES 1000
767/* ????? if numtrees too big for Shimo, truncate */
768  if (numtrees == 2) {
769    fprintf(outfile, "Kishino-Hasegawa-Templeton test\n\n");
770    fprintf(outfile, "Tree    Compatible  Difference  Its S.D.");
771    fprintf(outfile, "   Significantly worse?\n\n");
772    which = 1;
773    while (which <= numtrees) {
774      fprintf(outfile, "%3ld  %11.1f", which, nsteps[which - 1]);
775      if (maxwhich == which)
776        fprintf(outfile, "  <------ best\n");
777      else {
778        sumw = 0.0;
779        sum = 0.0;
780        sum2 = 0.0;
781        for (i = 0; i < local_chars; i++) {
782          if (weight[i] > 0) {
783            wt = weight[i];
784            sumw += wt;
785            temp = (fsteps[which - 1][i] - fsteps[maxwhich - 1][i]);
786            sum += temp;
787            sum2 += temp * temp / wt;
788          }
789        }
790        temp = sum / sumw;
791        sd = sqrt(sumw / (sumw - 1.0) * (sum2 - temp * temp));
792        fprintf(outfile, " %10.1f %11.4f",
793                (maxsteps-nsteps[which - 1]), sd);
794        if (sum > 1.95996 * sd)
795          fprintf(outfile, "           Yes\n");
796        else
797          fprintf(outfile, "           No\n");
798      }
799      which++;
800    }
801    fprintf(outfile, "\n\n");
802  } else {           /* Shimodaira-Hasegawa test using normal approximation */
803    fprintf(outfile, "Shimodaira-Hasegawa test\n\n");
804    covar = (double **)Malloc(numtrees*sizeof(double *)); 
805    sumw = 0.0;
806    for (i = 0; i < local_chars; i++)
807      sumw += weight[i];
808    for (i = 0; i < numtrees; i++)
809      covar[i] = (double *)Malloc(numtrees*sizeof(double)); 
810    for (i = 0; i < numtrees; i++) {        /* compute covariances of trees */
811      sum = nsteps[i]/sumw;
812      for (j = 0; j <=i; j++) {
813        sum2 = nsteps[j]/sumw;
814        temp = 0.0;
815        for (k = 0; k < local_chars; k++) {
816          if (weight[k] > 0) {
817            wt = weight[k];
818            temp = temp + wt*(fsteps[i][k]/wt-sum)
819                            *(fsteps[j][k]/wt-sum2);
820          }
821        }
822        covar[i][j] = temp;
823        if (i != j)
824          covar[j][i] = temp;
825      }
826    }
827    for (i = 0; i < numtrees; i++) { /* in-place Cholesky decomposition
828                                        of trees x trees covariance matrix */
829      sum = 0.0;
830      for (j = 0; j <= i-1; j++)
831        sum = sum + covar[i][j] * covar[i][j];
832      temp = sqrt(covar[i][i] - sum);
833      covar[i][i] = temp;
834      for (j = i+1; j < numtrees; j++) {
835        sum = 0.0;
836        for (k = 0; k < i; k++)
837          sum = sum + covar[i][k] * covar[j][k];
838        if (fabs(temp) < 1.0E-12)
839          covar[j][i] = 0.0;
840        else
841          covar[j][i] = (covar[j][i] - sum)/temp;
842      }
843    }
844    f = (double *)Malloc(numtrees*sizeof(double)); /* vector of P's of trees */
845    P = (double *)Malloc(numtrees*sizeof(double)); /* vector of P's of trees */
846    for (i = 0; i < numtrees; i++)
847      P[i] = 0.0;
848    sum2 = nsteps[0];             /* sum2 will be largest # of compat. sites */
849    for (i = 1; i < numtrees; i++)
850      if (sum2 < nsteps[i])
851        sum2 = nsteps[i];
852    for (i = 1; i < SAMPLES; i++) {           /* loop over resampled trees */
853      for (j = 0; j < numtrees; j++) {        /* draw vectors */
854        sum = 0.0;
855        for (k = 0; k <= j; k++)
856          sum += normrand(local_seed)*covar[j][k];
857        f[j] = sum;
858      }
859      sum = f[1];
860      for (j = 1; j < numtrees; j++)          /* get max of vector */
861        if (f[j] > sum)
862          sum = f[j];
863      for (j = 0; j < numtrees; j++)          /* accumulate P's */
864        if (sum2-nsteps[j] < sum-f[j])
865          P[j] += 1.0/SAMPLES;
866    }
867    fprintf(outfile, "Tree   Compatible  Difference   P value");
868    fprintf(outfile, "   Significantly worse?\n\n");
869    for (i = 0; i < numtrees; i++) {
870      fprintf(outfile, "%3ld  %10.1f", i+1, nsteps[i]);
871      if ((maxwhich-1) == i)
872        fprintf(outfile, "  <------ best\n");
873      else {
874        fprintf(outfile, " %10.1f  %10.3f", sum2-nsteps[i], P[i]);
875        if (P[i] < 0.05)
876          fprintf(outfile, "           Yes\n");
877        else
878          fprintf(outfile, "           No\n");
879      }
880    }
881  fprintf(outfile, "\n");
882  free(P);             /* free the variables we Malloc'ed */
883  free(f);
884  for (i = 0; i < numtrees; i++)
885    free(covar[i]);
886  free(covar);
887  }
888}  /* standev */
889
890
891void maketree()
892{
893  /* constructs a binary tree from the pointers in treenode.
894    adds each node at location which yields highest "likelihood"
895    then rearranges the tree for greatest "likelihood" */
896  long i, j, numtrees, nextnode;
897  boolean firsttree, goteof, haslengths;
898  double gotlike;
899  node *item, *nufork, *local_dummy;
900  pointarray nodep;
901  boolean *names;
902
903  if (!usertree) {
904    recompute = true;
905    for (i = 0; i < spp; i++)
906      in_tree[i] = false;
907    for (i = 1; i <= spp; i++)
908      enterorder[i - 1] = i;
909    if (jumble)
910      randumize(seed, enterorder);
911    root = treenode[enterorder[0] - 1];
912    add(treenode[enterorder[0] - 1], treenode[enterorder[1] - 1],
913        treenode[spp], &root, recompute, treenode, &grbg, zeros);
914    if (progress) {
915      printf("Adding species:\n");
916      writename(0, 2, enterorder);
917#ifdef WIN32
918      phyFillScreenColor();
919#endif
920    }
921    in_tree[0] = true;
922    in_tree[1] = true;
923    lastrearr = false;
924    for (i = 3; i <= spp; i++) {
925      mincomp(i);
926      bestyet = -350.0 * spp * chars;
927      item = treenode[enterorder[i - 1] - 1];
928      nufork = treenode[spp + i - 2];
929      there = root;
930      addpreorder(root, item, nufork);
931      add(there, item, nufork, &root, recompute, treenode, &grbg, zeros);
932      like = bestyet;
933      rearrange(&root);
934      if (progress) {
935        writename(i - 1, 1, enterorder);
936#ifdef WIN32
937        phyFillScreenColor();
938#endif
939      }
940      lastrearr = (i == spp);
941      if (lastrearr) {
942        if (progress) {
943          printf("\nDoing global rearrangements\n");
944          printf("  !");
945          for (j = 1; j <= nonodes; j++)
946            putchar('-');
947          printf("!\n");
948#ifdef WIN32
949          phyFillScreenColor();
950#endif
951        }
952        bestlike = bestyet;
953        if (jumb == 1) {
954          bstlike2 = bestlike;
955          nextree = 1;
956        }
957        do {
958          if (progress)
959            printf("   ");
960          gotlike = bestlike;
961          for (j = 0; j < nonodes; j++) {
962            bestyet = -10.0 * spp * chars;
963            item = treenode[j];
964            there = root;
965            if (item != root) {
966              re_move(item, &nufork, &root, recompute, treenode, &grbg, zeros);
967              there = root;
968              addpreorder(root, item, nufork);
969              add(there, item, nufork, &root, recompute, treenode, &grbg, zeros);
970            }
971            if (progress) {
972              putchar('.');
973              fflush(stdout);
974            }
975          }
976          if (progress)
977            putchar('\n');
978        } while (bestlike > gotlike);
979      }
980    }
981    if (progress)
982      putchar('\n');
983    for (i = spp - 1; i >= 1; i--)
984      re_move(treenode[i], &local_dummy, &root, recompute, treenode, &grbg, zeros);
985    if (jumb == njumble) {
986      if (treeprint) {
987        putc('\n', outfile);
988        if (nextree == 2)
989          fprintf(outfile, "One most parsimonious tree found:\n");
990        else
991          fprintf(outfile, "%6ld trees in all found\n", nextree - 1);
992      }
993      if (nextree > maxtrees + 1) {
994        if (treeprint)
995          fprintf(outfile, "here are the first%4ld of them\n", (long)maxtrees);
996        nextree = maxtrees + 1;
997      }
998      if (treeprint)
999        putc('\n', outfile);
1000      recompute = false;
1001      for (i = 0; i <= (nextree - 2); i++) {
1002        root = treenode[0];
1003        add(treenode[0], treenode[1], treenode[spp], &root, recompute,
1004              treenode, &grbg, zeros);
1005        for (j = 3; j <= spp; j++)
1006          add(treenode[bestrees[i].btree[j - 1] - 1], treenode[j - 1],
1007            treenode[spp + j - 2], &root, recompute, treenode, &grbg, zeros);
1008        reroot(treenode[outgrno - 1], root);
1009        postorder(root);
1010        evaluate(root);
1011        printree(root, 1.0);
1012        describe();
1013        for (j = 1; j < spp; j++)
1014          re_move(treenode[j], &local_dummy, &root, recompute, treenode, &grbg, zeros);
1015      }
1016    }
1017  } else {
1018    openfile(&intree, INTREE, "input tree file", "r", progname, intreename);
1019    numtrees = countsemic(&intree);
1020    if (numtrees > 2)
1021      initseed(&inseed, &inseed0, seed);
1022    if (treeprint) {
1023      fprintf(outfile, "User-defined tree");
1024      if (numtrees > 1)
1025        putc('s', outfile);
1026      fprintf(outfile, ":\n");
1027    }
1028    global_fsteps = (long **)Malloc(maxuser*sizeof(long *));
1029    for (j = 1; j <= maxuser; j++)
1030      global_fsteps[j - 1] = (long *)Malloc(endsite*sizeof(long));
1031    names = (boolean *)Malloc(spp*sizeof(boolean));
1032    nodep = NULL;
1033    global_maxsteps = 0.0;
1034    which = 1;
1035    while (which <= numtrees) {
1036      firsttree = true;
1037      nextnode = 0;
1038      haslengths = true;
1039      treeread(intree, &root, treenode, &goteof, &firsttree,
1040                 nodep, &nextnode, &haslengths, &grbg, initdnacompnode);
1041      for (j = 0; j < spp; j++)
1042        names[j] = false;
1043      initboolnames(root, names);
1044      for (j = 0; j < spp; j++)
1045        in_tree[j] = names[j];
1046      j = 1;
1047      while (!in_tree[j - 1])
1048        j++;
1049      mincomp(j);
1050      if (outgropt)
1051        reroot(treenode[outgrno - 1], root);
1052      postorder(root);
1053      evaluate(root);
1054      printree(root, 1.0);
1055      describe();
1056      which++;
1057    }
1058    FClose(intree);
1059    putc('\n', outfile);
1060    if (numtrees > 1 && chars > 1 ) {
1061      standev3(chars, numtrees, global_maxwhich, global_maxsteps, global_nsteps, global_fsteps, seed);
1062    }
1063    for (j = 1; j <= maxuser; j++)
1064      free(global_fsteps[j - 1]);
1065    free(global_fsteps);
1066    free(names);
1067  }
1068  if (jumb == njumble) {
1069    if (progress) {
1070      printf("Output written to file \"%s\"\n\n", outfilename);
1071      if (trout)
1072        printf("Trees also written onto file \"%s\"\n\n", outtreename);
1073    }
1074  }
1075}  /* maketree */
1076
1077
1078void freerest()
1079{
1080  if (!usertree) {
1081    freenode(&global_temp);
1082    freenode(&global_temp1);
1083  }
1084  freegrbg(&grbg);
1085  if (ancseq)
1086    freegarbage(&garbage);
1087  free(zeros);
1088  freenodes(nonodes, treenode);
1089}  /*  freerest */
1090
1091
1092int main(int argc, Char *argv[])
1093{  /* DNA compatibility by uphill search */
1094  /* reads in spp, chars, and the data. Then calls maketree to
1095    construct the tree */
1096#ifdef MAC
1097  argc = 1;                /* macsetup("Dnacomp","");        */
1098  argv[0]="Dnacomp";
1099#endif
1100  init(argc, argv);
1101  openfile(&infile,INFILE,"input file", "r",argv[0],infilename);
1102  openfile(&outfile,OUTFILE,"output file", "w",argv[0],outfilename);
1103  mulsets = false;
1104  garbage = NULL;
1105  grbg = NULL;
1106  ibmpc = IBMCRT;
1107  ansi = ANSICRT;
1108  msets = 1;
1109  firstset = true;
1110  doinit();
1111  if (weights || justwts)
1112    openfile(&weightfile,WEIGHTFILE,"weights file","r",argv[0],weightfilename);
1113  if (trout)
1114    openfile(&outtree,OUTTREE,"output tree file", "w",argv[0],outtreename);
1115  for (ith = 1; ith <= msets; ith++) {
1116    doinput();
1117    if (ith == 1)
1118      firstset = false;
1119    if (msets > 1 && !justwts) {
1120      fprintf(outfile, "Data set # %ld:\n\n", ith);
1121      if (progress)
1122        printf("Data set # %ld:\n\n", ith);
1123    }
1124    for (jumb = 1; jumb <= njumble; jumb++)
1125      maketree();
1126    freerest();
1127  }
1128  freetree(nonodes, treenode);
1129  FClose(infile);
1130  FClose(outfile);
1131  FClose(outtree);
1132#ifdef MAC
1133  fixmacfile(outfilename);
1134  fixmacfile(outtreename);
1135#endif
1136#ifdef WIN32
1137  phyRestoreConsoleAttributes();
1138#endif
1139  exxit(0);
1140  return 0;
1141}  /* DNA compatibility by uphill search */
1142
1143
Note: See TracBrowser for help on using the repository browser.