source: branches/profile/GDE/PHYLIP/dnacomp.c

Last change on this file was 2175, checked in by westram, 20 years ago

upgrade to PHYLIP 3.6

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.5 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, *p;
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 ch;
58Char progname[20];
59long *zeros;
60
61/* Local variables for maketree, propogated globally for C version: */
62  long maxwhich;
63  double like, maxsteps, bestyet, bestlike, bstlike2;
64  boolean lastrearr, recompute;
65  double nsteps[maxuser];
66  long **fsteps;
67  node *there;
68  long *place;
69  boolptr in_tree;
70  baseptr nothing;
71  node *temp, *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 **grbg, node *q, long len, long nodei,
315                     long *ntips, long *parens, initops whichinit,
316                     pointarray treenode, pointarray nodep, Char *str, Char *ch,
317                     FILE *intree)
318{
319  /* initializes a node */
320  boolean minusread;
321  double valyew, divisor;
322
323
324  switch (whichinit) {
325  case bottom:
326    gnutreenode(grbg, p, nodei, endsite, zeros);
327    treenode[nodei - 1] = *p;
328    break;
329  case nonbottom:
330    gnutreenode(grbg, p, nodei, endsite, zeros);
331    break;
332  case tip:
333    match_names_to_data (str, treenode, p, spp);
334    break;
335  case length:
336    processlength(&valyew, &divisor, ch, &minusread, intree, parens);
337    /* process and discard lengths */
338  default:
339    break;
340  }
341} /* initdnacompnode */
342
343
344void makeweights()
345{
346  /* make up weights vector to avoid duplicate computations */
347  long i;
348
349  for (i = 1; i <= chars; i++) {
350    alias[i - 1] = i;
351    oldweight[i - 1] = weight[i - 1];
352    ally[i - 1] = i;
353  }
354  sitesort(chars, weight);
355  sitecombine(chars);
356  sitescrunch(chars);
357  endsite = 0;
358  for (i = 1; i <= chars; i++) {
359    if (ally[i - 1] == i)
360      endsite++;
361  }
362  for (i = 1; i <= endsite; i++)
363    location[alias[i - 1] - 1] = i;
364  zeros = (long *)Malloc(endsite*sizeof(long));
365  for (i = 0; i < endsite; i++)
366    zeros[i] = 0;
367}  /* makeweights */
368
369
370void doinput()
371{
372  /* reads the input data */
373
374  long i;
375
376  if (justwts) {
377    if (firstset)
378      inputdata(chars);
379    for (i = 0; i < chars; i++)
380      weight[i] = 1;
381    inputweights(chars, weight, &weights);
382    if (justwts) {
383      fprintf(outfile, "\n\nWeights set # %ld:\n\n", ith);
384      if (progress)
385        printf("\nWeights set # %ld:\n\n", ith);
386    }
387    if (printdata)
388      printweights(outfile, 0, chars, weight, "Sites");
389  } else {
390    if (!firstset){
391      samenumsp(&chars, ith);
392      reallocchars();
393    }
394    inputdata(chars);
395    for (i = 0; i < chars; i++)
396      weight[i] = 1;
397    if (weights) {
398      inputweights(chars, weight, &weights);
399      if (printdata)
400        printweights(outfile, 0, chars, weight, "Sites");
401    }
402  }
403  makeweights();
404  makevalues(treenode, zeros, usertree);
405  allocnode(&temp, zeros, endsite);
406  allocnode(&temp1, zeros, endsite);
407}  /* doinput */
408
409
410void mincomp(long n)
411{
412  /* computes for each site the minimum number of steps
413    necessary to accomodate those species already
414    in the analysis, adding in species n */
415  long i, j, k, l, m;
416  bases b;
417  long s;
418  boolean allowable, deleted;
419
420  in_tree[n - 1] = true;
421  for (i = 0; i < endsite; i++)
422    necsteps[i] = 3;
423  for (m = 0; m <= 31; m++) {
424    s = 0;
425    l = -1;
426    k = m;
427    for (b = A; (long)b <= (long)O; b = (bases)((long)b + 1)) {
428      if ((k & 1) == 1) {
429        s |= 1L << ((long)b);
430        l++;
431      }
432      k /= 2;
433    }
434    for (j = 0; j < endsite; j++) {
435      allowable = true;
436      i = 1;
437      while (allowable && i <= spp) {
438        if (in_tree[i - 1] && treenode[i - 1]->base[j] != 0) {
439          if ((treenode[i - 1]->base[j] & s) == 0)
440            allowable = false;
441        }
442        i++;
443      }
444      if (allowable) {
445        if (l < necsteps[j])
446          necsteps[j] = l;
447      }
448    }
449  }
450  for (j = 0; j < endsite; j++) {
451    deleted = false;
452    for (i = 0; i < spp; i++) {
453      if (in_tree[i] && treenode[i]->base[j] == 0)
454        deleted = true;
455    }
456    if (deleted)
457      necsteps[j]++;
458  }
459  for (i = 0; i < endsite; i++)
460    necsteps[i] *= weight[i];
461}  /* mincomp */
462
463
464void evaluate(node *r)
465{
466  /* determines the number of steps needed for a tree. this is
467    the minimum number of steps needed to evolve sequences on
468    this tree */
469  long i, term;
470  double sum;
471
472   sum = 0.0;
473   for (i = 0; i < endsite; i++) {
474    if (r->numsteps[i] == necsteps[i])
475      term = weight[i];
476    else
477      term = 0;
478    sum += term;
479    if (usertree && which <= maxuser)
480      fsteps[which - 1][i] = term;
481  }
482  if (usertree && which <= maxuser) {
483    nsteps[which - 1] = sum;
484    if (which == 1) {
485      maxwhich = 1;
486      maxsteps = sum;
487    } else if (sum > maxsteps) {
488      maxwhich = which;
489      maxsteps = sum;
490    }
491  }
492  like = sum;
493}  /* evaluate */
494
495
496void localsavetree()
497{
498  /* record in place where each species has to be
499    added to reconstruct this tree */
500  long i, j;
501  node *p;
502  boolean done;
503
504  reroot(treenode[outgrno - 1], root);
505  savetraverse(root);
506  for (i = 0; i < nonodes; i++)
507    place[i] = 0;
508  place[root->index - 1] = 1;
509  for (i = 1; i <= spp; i++) {
510    p = treenode[i - 1];
511    while (place[p->index - 1] == 0) {
512      place[p->index - 1] = i;
513      while (!p->bottom)
514        p = p->next;
515      p = p->back;
516    }
517    if (i > 1) {
518      place[i - 1] = place[p->index - 1];
519      j = place[p->index - 1];
520      done = false;
521      while (!done) {
522        place[p->index - 1] = spp + i - 1;
523        while (!p->bottom)
524          p = p->next;
525        p = p->back;
526        done = (p == NULL);
527        if (!done)
528          done = (place[p->index - 1] != j);
529      }
530    }
531  }
532}  /* localsavetree */
533
534
535void tryadd(node *p, node *item, node *nufork)
536{
537  /* temporarily adds one fork and one tip to the tree.
538    if the location where they are added yields greater
539    "likelihood" than other locations tested up to that
540    time, then keeps that location as there */
541  long pos;
542  boolean found;
543  node *rute, *q;
544
545  if (p == root)
546    fillin(temp, item, p);
547  else {
548    fillin(temp1, item, p);
549    fillin(temp, temp1, p->back);
550  }
551  evaluate(temp);
552  if (lastrearr) {
553    if (like < bestlike) {
554      if (item == nufork->next->next->back) {
555        q = nufork->next;
556        nufork->next = nufork->next->next;
557        nufork->next->next = q;
558        q->next = nufork;
559      }
560    } else if (like >= bstlike2) {
561      recompute = false;
562      add(p, item, nufork, &root, recompute, treenode, &grbg, zeros);
563      rute = root->next->back;
564      localsavetree();
565      reroot(rute, root);
566      if (like > bstlike2) {
567        bestlike = bstlike2 = like;
568        pos = 1;
569        nextree = 1;
570        addtree(pos, &nextree, dummy, place, bestrees);
571      } else {
572        pos = 0;
573        findtree(&found, &pos, nextree, place, bestrees);
574        if (!found) {
575          if (nextree <= maxtrees)
576            addtree(pos, &nextree, dummy, place, bestrees);
577        }
578      }
579      re_move(item, &nufork, &root, recompute, treenode, &grbg, zeros);
580      recompute = true;
581    }
582  }
583  if (like > bestyet) {
584    bestyet = like;
585    there = p;
586  }
587}  /* tryadd */
588
589
590void addpreorder(node *p, node *item, node *nufork)
591{
592  /* traverses a binary tree, calling PROCEDURE tryadd
593    at a node before calling tryadd at its descendants */
594
595  if (p == NULL)
596    return;
597  tryadd(p, item, nufork);
598  if (!p->tip) {
599    addpreorder(p->next->back, item, nufork);
600    addpreorder(p->next->next->back, item, nufork);
601  }
602}  /* addpreorder */
603
604
605void tryrearr(node *p, boolean *success)
606{
607  /* evaluates one rearrangement of the tree.
608    if the new tree has greater "likelihood" than the old
609    one sets success := TRUE and keeps the new tree.
610    otherwise, restores the old tree */
611  node *frombelow, *whereto, *forknode, *q;
612  double oldlike;
613
614  if (p->back == NULL)
615    return;
616  forknode = treenode[p->back->index - 1];
617  if (forknode->back == NULL)
618    return;
619  oldlike = bestyet;
620  if (p->back->next->next == forknode)
621    frombelow = forknode->next->next->back;
622  else
623    frombelow = forknode->next->back;
624  whereto = treenode[forknode->back->index - 1];
625  if (whereto->next->back == forknode)
626    q = whereto->next->next->back;
627  else
628    q = whereto->next->back;
629  fillin(temp1, frombelow, q);
630  fillin(temp, temp1, p);
631  fillin(temp1, temp, whereto->back);
632  evaluate(temp1);
633  if (like <= oldlike) {
634    if (p != forknode->next->next->back)
635      return;
636    q = forknode->next;
637    forknode->next = forknode->next->next;
638    forknode->next->next = q;
639    q->next = forknode;
640    return;
641  }
642  recompute = false;
643  re_move(p, &forknode, &root, recompute, treenode, &grbg, zeros);
644  fillin(whereto, whereto->next->back, whereto->next->next->back);
645  recompute = true;
646  add(whereto, p, forknode, &root, recompute, treenode, &grbg, zeros);
647  *success = true;
648  bestyet = like;
649}  /* tryrearr */
650
651
652void repreorder(node *p, boolean *success)
653{
654  /* traverses a binary tree, calling PROCEDURE tryrearr
655    at a node before calling tryrearr at its descendants */
656  if (p == NULL)
657    return;
658  tryrearr(p,success);
659  if (!p->tip) {
660    repreorder(p->next->back,success);
661    repreorder(p->next->next->back,success);
662  }
663}  /* repreorder */
664
665
666void rearrange(node **r)
667{
668  /* traverses the tree (preorder), finding any local
669    rearrangement which decreases the number of steps.
670    if traversal succeeds in increasing the tree's
671    "likelihood", PROCEDURE rearrange runs traversal again */
672  boolean success=true;
673
674  while (success) {
675    success = false;
676    repreorder(*r,&success);
677  }
678}  /* rearrange */
679
680
681void describe()
682{
683  /* prints ancestors, steps and table of numbers of steps in
684    each site and table of compatibilities */
685  long i, j, k;
686
687  if (treeprint) {
688    fprintf(outfile, "\ntotal number of compatible sites is ");
689    fprintf(outfile, "%10.1f\n", like);
690  }
691  if (stepbox) {
692    writesteps(chars, weights, oldweight, root);
693    fprintf(outfile,
694            "\n compatibility (Y or N) of each site with this tree:\n\n");
695    fprintf(outfile, "      ");
696    for (i = 0; i <= 9; i++)
697      fprintf(outfile, "%ld", i);
698    fprintf(outfile, "\n     *----------\n");
699    for (i = 0; i <= (chars / 10); i++) {
700      putc(' ', outfile);
701      fprintf(outfile, "%3ld !", i * 10);
702      for (j = 0; j <= 9; j++) {
703        k = i * 10 + j;
704        if (k > 0 && k <= chars) {
705          if (root->numsteps[location[ally[k - 1] - 1] - 1] ==
706              necsteps[location[ally[k - 1] - 1] - 1]) {
707            if (oldweight[k - 1] > 0)
708              putc('Y', outfile);
709            else
710              putc('y', outfile);
711          } else {
712            if (oldweight[k - 1] > 0)
713              putc('N', outfile);
714            else
715              putc('n', outfile);
716          }
717        } else
718          putc(' ', outfile);
719      }
720      putc('\n', outfile);
721    }
722  }
723  if (ancseq) {
724    hypstates(chars, root, treenode, &garbage, basechar);
725    putc('\n', outfile);
726  }
727  putc('\n', outfile);
728  if (trout) {
729    col = 0;
730    treeout(root, nextree, &col, root);
731  }
732}  /* describe */
733
734
735void initboolnames(node *p, boolean *names)
736{
737  /* sets BOOLEANs that indicate tips */
738  node *q;
739
740  if (p->tip) {
741    names[p->index - 1] = true;
742    return;
743  }
744  q = p->next;
745  while (q != p) {
746    initboolnames(q->back, names);
747    q = q->next;
748  }
749}  /* initboolnames */
750
751
752void standev3(long chars, long numtrees, long maxwhich, double maxsteps,
753              double *nsteps, long **fsteps, longer seed)
754{  /* compute and write standard deviation of user trees */
755  long i, j, k;
756  double wt, sumw, sum, sum2, sd;
757  double temp;
758  double **covar, *P, *f;
759
760#define SAMPLES 1000
761#define MAXSHIMOTREES 1000
762/* ????? if numtrees too big for Shimo, truncate */
763  if (numtrees == 2) {
764    fprintf(outfile, "Kishino-Hasegawa-Templeton test\n\n");
765    fprintf(outfile, "Tree    Compatible  Difference  Its S.D.");
766    fprintf(outfile, "   Significantly worse?\n\n");
767    which = 1;
768    while (which <= numtrees) {
769      fprintf(outfile, "%3ld  %11.1f", which, nsteps[which - 1]);
770      if (maxwhich == which)
771        fprintf(outfile, "  <------ best\n");
772      else {
773        sumw = 0.0;
774        sum = 0.0;
775        sum2 = 0.0;
776        for (i = 0; i < chars; i++) {
777          if (weight[i] > 0) {
778            wt = weight[i];
779            sumw += wt;
780            temp = (fsteps[which - 1][i] - fsteps[maxwhich - 1][i]);
781            sum += temp;
782            sum2 += temp * temp / wt;
783          }
784        }
785        temp = sum / sumw;
786        sd = sqrt(sumw / (sumw - 1.0) * (sum2 - temp * temp));
787        fprintf(outfile, " %10.1f %11.4f",
788                (maxsteps-nsteps[which - 1]), sd);
789        if (sum > 1.95996 * sd)
790          fprintf(outfile, "           Yes\n");
791        else
792          fprintf(outfile, "           No\n");
793      }
794      which++;
795    }
796    fprintf(outfile, "\n\n");
797  } else {           /* Shimodaira-Hasegawa test using normal approximation */
798    fprintf(outfile, "Shimodaira-Hasegawa test\n\n");
799    covar = (double **)Malloc(numtrees*sizeof(double *)); 
800    sumw = 0.0;
801    for (i = 0; i < chars; i++)
802      sumw += weight[i];
803    for (i = 0; i < numtrees; i++)
804      covar[i] = (double *)Malloc(numtrees*sizeof(double)); 
805    for (i = 0; i < numtrees; i++) {        /* compute covariances of trees */
806      sum = nsteps[i]/sumw;
807      for (j = 0; j <=i; j++) {
808        sum2 = nsteps[j]/sumw;
809        temp = 0.0;
810        for (k = 0; k < chars; k++) {
811          if (weight[k] > 0) {
812            wt = weight[k];
813            temp = temp + wt*(fsteps[i][k]/wt-sum)
814                            *(fsteps[j][k]/wt-sum2);
815          }
816        }
817        covar[i][j] = temp;
818        if (i != j)
819          covar[j][i] = temp;
820      }
821    }
822    for (i = 0; i < numtrees; i++) { /* in-place Cholesky decomposition
823                                        of trees x trees covariance matrix */
824      sum = 0.0;
825      for (j = 0; j <= i-1; j++)
826        sum = sum + covar[i][j] * covar[i][j];
827      temp = sqrt(covar[i][i] - sum);
828      covar[i][i] = temp;
829      for (j = i+1; j < numtrees; j++) {
830        sum = 0.0;
831        for (k = 0; k < i; k++)
832          sum = sum + covar[i][k] * covar[j][k];
833        if (fabs(temp) < 1.0E-12)
834          covar[j][i] = 0.0;
835        else
836          covar[j][i] = (covar[j][i] - sum)/temp;
837      }
838    }
839    f = (double *)Malloc(numtrees*sizeof(double)); /* vector of P's of trees */
840    P = (double *)Malloc(numtrees*sizeof(double)); /* vector of P's of trees */
841    for (i = 0; i < numtrees; i++)
842      P[i] = 0.0;
843    sum2 = nsteps[0];             /* sum2 will be largest # of compat. sites */
844    for (i = 1; i < numtrees; i++)
845      if (sum2 < nsteps[i])
846        sum2 = nsteps[i];
847    for (i = 1; i < SAMPLES; i++) {           /* loop over resampled trees */
848      for (j = 0; j < numtrees; j++) {        /* draw vectors */
849        sum = 0.0;
850        for (k = 0; k <= j; k++)
851          sum += normrand(seed)*covar[j][k];
852        f[j] = sum;
853      }
854      sum = f[1];
855      for (j = 1; j < numtrees; j++)          /* get max of vector */
856        if (f[j] > sum)
857          sum = f[j];
858      for (j = 0; j < numtrees; j++)          /* accumulate P's */
859        if (sum2-nsteps[j] < sum-f[j])
860          P[j] += 1.0/SAMPLES;
861    }
862    fprintf(outfile, "Tree   Compatible  Difference   P value");
863    fprintf(outfile, "   Significantly worse?\n\n");
864    for (i = 0; i < numtrees; i++) {
865      fprintf(outfile, "%3ld  %10.1f", i+1, nsteps[i]);
866      if ((maxwhich-1) == i)
867        fprintf(outfile, "  <------ best\n");
868      else {
869        fprintf(outfile, " %10.1f  %10.3f", sum2-nsteps[i], P[i]);
870        if (P[i] < 0.05)
871          fprintf(outfile, "           Yes\n");
872        else
873          fprintf(outfile, "           No\n");
874      }
875    }
876  fprintf(outfile, "\n");
877  free(P);             /* free the variables we Malloc'ed */
878  free(f);
879  for (i = 0; i < numtrees; i++)
880    free(covar[i]);
881  free(covar);
882  }
883}  /* standev */
884
885
886void maketree()
887{
888  /* constructs a binary tree from the pointers in treenode.
889    adds each node at location which yields highest "likelihood"
890    then rearranges the tree for greatest "likelihood" */
891  long i, j, numtrees, nextnode;
892  boolean firsttree, goteof, haslengths;
893  double gotlike;
894  node *item, *nufork, *dummy;
895  pointarray nodep;
896  boolean *names;
897
898  if (!usertree) {
899    recompute = true;
900    for (i = 0; i < spp; i++)
901      in_tree[i] = false;
902    for (i = 1; i <= spp; i++)
903      enterorder[i - 1] = i;
904    if (jumble)
905      randumize(seed, enterorder);
906    root = treenode[enterorder[0] - 1];
907    add(treenode[enterorder[0] - 1], treenode[enterorder[1] - 1],
908        treenode[spp], &root, recompute, treenode, &grbg, zeros);
909    if (progress) {
910      printf("Adding species:\n");
911      writename(0, 2, enterorder);
912#ifdef WIN32
913      phyFillScreenColor();
914#endif
915    }
916    in_tree[0] = true;
917    in_tree[1] = true;
918    lastrearr = false;
919    for (i = 3; i <= spp; i++) {
920      mincomp(i);
921      bestyet = -350.0 * spp * chars;
922      item = treenode[enterorder[i - 1] - 1];
923      nufork = treenode[spp + i - 2];
924      there = root;
925      addpreorder(root, item, nufork);
926      add(there, item, nufork, &root, recompute, treenode, &grbg, zeros);
927      like = bestyet;
928      rearrange(&root);
929      if (progress) {
930        writename(i - 1, 1, enterorder);
931#ifdef WIN32
932        phyFillScreenColor();
933#endif
934      }
935      lastrearr = (i == spp);
936      if (lastrearr) {
937        if (progress) {
938          printf("\nDoing global rearrangements\n");
939          printf("  !");
940          for (j = 1; j <= nonodes; j++)
941            putchar('-');
942          printf("!\n");
943#ifdef WIN32
944          phyFillScreenColor();
945#endif
946        }
947        bestlike = bestyet;
948        if (jumb == 1) {
949          bstlike2 = bestlike;
950          nextree = 1;
951        }
952        do {
953          if (progress)
954            printf("   ");
955          gotlike = bestlike;
956          for (j = 0; j < nonodes; j++) {
957            bestyet = -10.0 * spp * chars;
958            item = treenode[j];
959            there = root;
960            if (item != root) {
961              re_move(item, &nufork, &root, recompute, treenode, &grbg, zeros);
962              there = root;
963              addpreorder(root, item, nufork);
964              add(there, item, nufork, &root, recompute, treenode, &grbg, zeros);
965            }
966            if (progress) {
967              putchar('.');
968              fflush(stdout);
969            }
970          }
971          if (progress)
972            putchar('\n');
973        } while (bestlike > gotlike);
974      }
975    }
976    if (progress)
977      putchar('\n');
978    for (i = spp - 1; i >= 1; i--)
979      re_move(treenode[i], &dummy, &root, recompute, treenode, &grbg, zeros);
980    if (jumb == njumble) {
981      if (treeprint) {
982        putc('\n', outfile);
983        if (nextree == 2)
984          fprintf(outfile, "One most parsimonious tree found:\n");
985        else
986          fprintf(outfile, "%6ld trees in all found\n", nextree - 1);
987      }
988      if (nextree > maxtrees + 1) {
989        if (treeprint)
990          fprintf(outfile, "here are the first%4ld of them\n", (long)maxtrees);
991        nextree = maxtrees + 1;
992      }
993      if (treeprint)
994        putc('\n', outfile);
995      recompute = false;
996      for (i = 0; i <= (nextree - 2); i++) {
997        root = treenode[0];
998        add(treenode[0], treenode[1], treenode[spp], &root, recompute,
999              treenode, &grbg, zeros);
1000        for (j = 3; j <= spp; j++)
1001          add(treenode[bestrees[i].btree[j - 1] - 1], treenode[j - 1],
1002            treenode[spp + j - 2], &root, recompute, treenode, &grbg, zeros);
1003        reroot(treenode[outgrno - 1], root);
1004        postorder(root);
1005        evaluate(root);
1006        printree(root, 1.0);
1007        describe();
1008        for (j = 1; j < spp; j++)
1009          re_move(treenode[j], &dummy, &root, recompute, treenode, &grbg, zeros);
1010      }
1011    }
1012  } else {
1013    openfile(&intree, INTREE, "input tree file", "r", progname, intreename);
1014    numtrees = countsemic(&intree);
1015    if (numtrees > 2)
1016      initseed(&inseed, &inseed0, seed);
1017    if (treeprint) {
1018      fprintf(outfile, "User-defined tree");
1019      if (numtrees > 1)
1020        putc('s', outfile);
1021      fprintf(outfile, ":\n");
1022    }
1023    fsteps = (long **)Malloc(maxuser*sizeof(long *));
1024    for (j = 1; j <= maxuser; j++)
1025      fsteps[j - 1] = (long *)Malloc(endsite*sizeof(long));
1026    names = (boolean *)Malloc(spp*sizeof(boolean));
1027    nodep = NULL;
1028    maxsteps = 0.0;
1029    which = 1;
1030    while (which <= numtrees) {
1031      firsttree = true;
1032      nextnode = 0;
1033      haslengths = true;
1034      treeread(intree, &root, treenode, &goteof, &firsttree,
1035                 nodep, &nextnode, &haslengths, &grbg, initdnacompnode);
1036      for (j = 0; j < spp; j++)
1037        names[j] = false;
1038      initboolnames(root, names);
1039      for (j = 0; j < spp; j++)
1040        in_tree[j] = names[j];
1041      j = 1;
1042      while (!in_tree[j - 1])
1043        j++;
1044      mincomp(j);
1045      if (outgropt)
1046        reroot(treenode[outgrno - 1], root);
1047      postorder(root);
1048      evaluate(root);
1049      printree(root, 1.0);
1050      describe();
1051      which++;
1052    }
1053    FClose(intree);
1054    putc('\n', outfile);
1055    if (numtrees > 1 && chars > 1 ) {
1056      standev3(chars, numtrees, maxwhich, maxsteps, nsteps, fsteps, seed);
1057    }
1058    for (j = 1; j <= maxuser; j++)
1059      free(fsteps[j - 1]);
1060    free(fsteps);
1061    free(names);
1062  }
1063  if (jumb == njumble) {
1064    if (progress) {
1065      printf("Output written to file \"%s\"\n\n", outfilename);
1066      if (trout)
1067        printf("Trees also written onto file \"%s\"\n\n", outtreename);
1068    }
1069  }
1070}  /* maketree */
1071
1072
1073void freerest()
1074{
1075  if (!usertree) {
1076    freenode(&temp);
1077    freenode(&temp1);
1078  }
1079  freegrbg(&grbg);
1080  if (ancseq)
1081    freegarbage(&garbage);
1082  free(zeros);
1083  freenodes(nonodes, treenode);
1084}  /*  freerest */
1085
1086
1087int main(int argc, Char *argv[])
1088{  /* DNA compatibility by uphill search */
1089  /* reads in spp, chars, and the data. Then calls maketree to
1090    construct the tree */
1091#ifdef MAC
1092  argc = 1;                /* macsetup("Dnacomp","");        */
1093  argv[0]="Dnacomp";
1094#endif
1095  init(argc, argv);
1096  openfile(&infile,INFILE,"input file", "r",argv[0],infilename);
1097  openfile(&outfile,OUTFILE,"output file", "w",argv[0],outfilename);
1098  mulsets = false;
1099  garbage = NULL;
1100  grbg = NULL;
1101  ibmpc = IBMCRT;
1102  ansi = ANSICRT;
1103  msets = 1;
1104  firstset = true;
1105  doinit();
1106  if (weights || justwts)
1107    openfile(&weightfile,WEIGHTFILE,"weights file","r",argv[0],weightfilename);
1108  if (trout)
1109    openfile(&outtree,OUTTREE,"output tree file", "w",argv[0],outtreename);
1110  for (ith = 1; ith <= msets; ith++) {
1111    doinput();
1112    if (ith == 1)
1113      firstset = false;
1114    if (msets > 1 && !justwts) {
1115      fprintf(outfile, "Data set # %ld:\n\n", ith);
1116      if (progress)
1117        printf("Data set # %ld:\n\n", ith);
1118    }
1119    for (jumb = 1; jumb <= njumble; jumb++)
1120      maketree();
1121    freerest();
1122  }
1123  freetree(nonodes, treenode);
1124  FClose(infile);
1125  FClose(outfile);
1126  FClose(outtree);
1127#ifdef MAC
1128  fixmacfile(outfilename);
1129  fixmacfile(outtreename);
1130#endif
1131#ifdef WIN32
1132  phyRestoreConsoleAttributes();
1133#endif
1134  exxit(0);
1135  return 0;
1136}  /* DNA compatibility by uphill search */
1137
1138
Note: See TracBrowser for help on using the repository browser.