source: trunk/GDE/PHYLIP/dollop.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: 26.5 KB
Line 
1
2#include "phylip.h"
3#include "disc.h"
4#include "dollo.h"
5
6/* version 3.6. (c) Copyright 1993-2002 by the University of Washington.
7   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, and Andrew Keeffe.
8   Permission is granted to copy and use this program provided no fee is
9   charged for it and provided that this copyright notice is not removed. */
10
11#define maxtrees        100  /* maximum number of tied trees stored     */
12
13#ifndef OLDC
14/* function prototypes */
15void   getoptions(void);
16void   allocrest(void);
17void   doinit(void);
18void   inputoptions(void);
19void   doinput(void);
20void   dollop_count(node *, steptr, steptr);
21void   preorder(node *, steptr, steptr, long, boolean, long, bitptr, pointptr);
22void   evaluate(node *);
23void   savetree(void);
24void   dollop_addtree(long *);
25
26void   tryadd(node *, node **, node **);
27void   addpreorder(node *, node *, node *);
28void   tryrearr(node *, node **, boolean *);
29void   repreorder(node *, node **, boolean *);
30void   rearrange(node **);
31void   describe(void);
32void   initdollopnode(node **, node **, node *, long, long, long *,
33            long *, initops, pointarray, pointarray, Char *, Char *, FILE *);
34void   maketree(void);
35/* function prototypes */
36#endif
37
38Char infilename[FNMLNGTH], outfilename[FNMLNGTH], intreename[FNMLNGTH], outtreename[FNMLNGTH], weightfilename[FNMLNGTH], ancfilename[FNMLNGTH];
39node *root;
40long col, msets, ith, njumble, jumb;
41long inseed, inseed0;
42boolean jumble, usertree, weights, thresh, ancvar, questions, dollo,
43               trout,  progress, treeprint, stepbox, ancseq, mulsets,
44               firstset, justwts;
45boolean *ancone, *anczero, *ancone0, *anczero0;
46pointptr treenode;   /* pointers to all nodes in tree */
47double threshold;
48double *threshwt;
49longer seed;
50long *enterorder;
51double **fsteps;
52steptr numsteps;
53bestelm *bestrees;
54Char *guess;
55gbit *garbage;
56char *progname;
57
58/* Variables for treeread */
59boolean goteof, firsttree, haslengths, phirst;
60pointarray nodep;
61node *grbg;
62long *zeros;
63
64/* Local variables for maketree, propagated globally for C version: */
65long minwhich;
66double like, bestyet, bestlike, bstlike2, minsteps;
67boolean lastrearr;
68double nsteps[maxuser];
69node *there;
70long fullset;
71bitptr zeroanc, oneanc;
72long *place;
73Char global_ch;
74boolean *names;
75steptr global_numsone, global_numszero;
76bitptr steps;
77
78
79void getoptions()
80{
81  /* interactively set options */
82  long loopcount, loopcount2;
83  Char ch, ch2;
84
85  fprintf(outfile,"\nDollo and polymorphism parsimony algorithm,");
86  fprintf(outfile," version %s\n\n",VERSION);
87  putchar('\n');
88  ancvar = false;
89  dollo = true;
90  jumble = false;
91  njumble = 1;
92  thresh = false;
93  threshold = spp;
94  trout = true;
95  usertree = false;
96  goteof = false;
97  weights = false;
98  justwts = false;
99  printdata = false;
100  progress = true;
101  treeprint = true;
102  stepbox = false;
103  ancseq = false;
104  loopcount = 0;
105  for (;;) {
106    cleerhome();
107    printf("\nDollo and polymorphism parsimony algorithm, version %s\n\n",
108           VERSION);
109    printf("Settings for this run:\n");
110    printf("  U                 Search for best tree?  %s\n",
111           (usertree ? "No, use user trees in input file" : "Yes"));
112    printf("  P                     Parsimony method?  %s\n",
113           dollo ? "Dollo" : "Polymorphism");
114    if (!usertree) {
115      printf("  J     Randomize input order of species?");
116      if (jumble)
117        printf("  Yes (seed =%8ld,%3ld times)\n", inseed0, njumble);
118      else
119        printf("  No. Use input order\n");
120    }
121    printf("  T              Use Threshold parsimony?");
122    if (thresh)
123      printf("  Yes, count steps up to%4.1f per char.\n", threshold);
124    else
125      printf("  No, use ordinary parsimony\n");
126    printf("  A   Use ancestral states in input file?  %s\n",
127           ancvar ? "Yes" : "No");
128    printf("  W                       Sites weighted?  %s\n",
129           (weights ? "Yes" : "No"));
130    printf("  M           Analyze multiple data sets?");
131    if (mulsets)
132    printf("  Yes, %2ld %s\n", msets,
133               (justwts ? "sets of weights" : "data sets"));
134    else
135      printf("  No\n");
136    printf("  0   Terminal type (IBM PC, ANSI, none)?  %s\n",
137           ibmpc ? "IBM PC" : ansi  ? "ANSI" : "(none)");
138    printf("  1    Print out the data at start of run  %s\n",
139           printdata ? "Yes" : "No");
140    printf("  2  Print indications of progress of run  %s\n",
141           progress ? "Yes" : "No");
142    printf("  3                        Print out tree  %s\n",
143           treeprint ? "Yes" : "No");
144    printf("  4     Print out steps in each character  %s\n",
145           stepbox ? "Yes" : "No");
146    printf("  5     Print states at all nodes of tree  %s\n",
147           ancseq ? "Yes" : "No");
148    printf("  6       Write out trees onto tree file?  %s\n",
149           trout ? "Yes" : "No");
150    if(weights && justwts){
151        printf(
152         "WARNING:  W option and Multiple Weights options are both on.  ");
153        printf(
154         "The W menu option is unnecessary and has no additional effect. \n");
155    }
156    printf("\nAre these settings correct? ");
157    printf("(type Y or the letter for one to change)\n");
158#ifdef WIN32
159    phyFillScreenColor();
160#endif
161    scanf("%c%*[^\n]", &ch);
162    getchar();
163    uppercase(&ch);
164    if (ch == 'Y')
165      break;
166    if (strchr("WAPJTUM1234560",ch) != NULL){
167      switch (ch) {
168
169      case 'A':
170        ancvar = !ancvar;
171        break;
172
173      case 'P':
174        dollo = !dollo;
175        break;
176
177      case 'J':
178        jumble = !jumble;
179        if (jumble)
180          initjumble(&inseed, &inseed0, seed, &njumble);
181        else njumble = 1;
182        break;
183
184      case 'W':
185        weights = !weights;
186        break;
187       
188      case 'T':
189        thresh = !thresh;
190        if (thresh)
191          initthreshold(&threshold);
192        break;
193
194      case 'U':
195        usertree = !usertree;
196        break;
197
198      case 'M':
199        mulsets = !mulsets;
200        if (mulsets){
201            printf("Multiple data sets or multiple weights?");
202          loopcount2 = 0;
203          do {
204            printf(" (type D or W)\n");
205#ifdef WIN32
206            phyFillScreenColor();
207#endif
208            scanf("%c%*[^\n]", &ch2);
209            getchar();
210            if (ch2 == '\n')
211              ch2 = ' ';
212            uppercase(&ch2);
213            countup(&loopcount2, 10);
214          } while ((ch2 != 'W') && (ch2 != 'D'));
215          justwts = (ch2 == 'W');
216          if (justwts)
217            justweights(&msets);
218          else
219            initdatasets(&msets);
220          if (!jumble) {
221            jumble = true;
222            initjumble(&inseed, &inseed0, seed, &njumble);
223          }
224        }
225        break;
226
227      case '0':
228        initterminal(&ibmpc, &ansi);
229        break;
230
231      case '1':
232        printdata = !printdata;
233        break;
234
235      case '2':
236        progress = !progress;
237        break;
238
239      case '3':
240        treeprint = !treeprint;
241        break;
242
243      case '4':
244        stepbox = !stepbox;
245        break;
246
247      case '5':
248        ancseq = !ancseq;
249        break;
250
251      case '6':
252        trout = !trout;
253        break;
254      }
255    } else
256      printf("Not a possible option!\n");
257    countup(&loopcount, 100);
258  }
259}  /* getoptions */
260
261
262void allocrest()
263{
264  long i;
265
266  extras = (steptr)Malloc(chars*sizeof(long));
267  weight = (steptr)Malloc(chars*sizeof(long));
268  threshwt = (double *)Malloc(chars*sizeof(double));
269  if (usertree) {
270    fsteps = (double **)Malloc(maxuser*sizeof(double *));
271    for (i = 1; i <= maxuser; i++)
272      fsteps[i - 1] = (double *)Malloc(chars*sizeof(double));
273  }
274  bestrees = (bestelm *) Malloc(maxtrees*sizeof(bestelm));
275  for (i = 1; i <= maxtrees; i++)
276    bestrees[i - 1].btree = (long *)Malloc(nonodes*sizeof(long));
277  numsteps = (steptr)Malloc(chars*sizeof(long));
278  nayme = (naym *)Malloc(spp*sizeof(naym));
279  enterorder = (long *)Malloc(spp*sizeof(long));
280  place = (long *)Malloc(nonodes*sizeof(long));
281  ancone = (boolean *)Malloc(chars*sizeof(boolean));
282  anczero = (boolean *)Malloc(chars*sizeof(boolean));
283  ancone0 = (boolean *)Malloc(chars*sizeof(boolean));
284  anczero0 = (boolean *)Malloc(chars*sizeof(boolean));
285  global_numsone = (steptr)Malloc(chars*sizeof(long));
286  global_numszero = (steptr)Malloc(chars*sizeof(long));
287  guess = (Char *)Malloc(chars*sizeof(Char));
288  zeroanc = (bitptr)Malloc(words*sizeof(long));
289  oneanc = (bitptr)Malloc(words*sizeof(long));
290}  /* allocrest */
291
292
293void doinit()
294{
295  /* initializes variables */
296
297  inputnumbers(&spp, &chars, &nonodes, 1);
298  words = chars / bits + 1;
299  getoptions();
300//  if (printdata)
301//    fprintf(outfile, "%2ld species, %3ld  characters\n\n", spp, chars);
302  alloctree(&treenode);
303  setuptree(treenode);
304  allocrest();
305}  /* doinit */
306
307
308void inputoptions()
309{
310  /* input the information on the options */
311  long i;
312  if(justwts){
313      if(firstset){
314          scan_eoln(infile);
315          if (ancvar) {
316              inputancestorsnew(anczero0, ancone0);
317          }
318      }
319      for (i = 0; i < (chars); i++)
320          weight[i] = 1;
321      inputweights(chars, weight, &weights);     
322  }
323  else {
324      if (!firstset)
325          samenumsp(&chars, ith);
326      scan_eoln(infile);
327      for (i = 0; i < (chars); i++)
328          weight[i] = 1;
329      if (ancvar)
330          inputancestorsnew(anczero0, ancone0);
331      if (weights)
332          inputweights(chars, weight, &weights);
333  }
334  if ((weights || justwts) && printdata)
335      printweights(outfile, 0, chars, weight, "Characters");
336  for (i = 0; i < (chars); i++) {
337      if (!ancvar) {
338          anczero[i] = true;
339          ancone[i] = false;
340      } else {
341          anczero[i] = anczero0[i];
342          ancone[i] = ancone0[i];
343      }
344  }
345  if (ancvar && printdata)
346      printancestors(outfile, anczero, ancone);
347  questions = false;
348  for (i = 0; i < (chars); i++) {
349      questions = (questions || (ancone[i] && anczero[i]));
350      threshwt[i] = threshold * weight[i];
351  }
352}  /* inputoptions */
353
354
355void doinput()
356{
357  /* reads the input data */
358  inputoptions();
359  if(!justwts || firstset)
360      inputdata(treenode, dollo, printdata, outfile);
361}  /* doinput */
362
363
364void dollop_count(node *p, steptr numsone, steptr numszero)
365{
366  /* counts the number of steps in a fork of the tree.
367     The program spends much of its time in this PROCEDURE */
368  long i, j, l;
369
370  if (dollo) {
371    for (i = 0; i < (words); i++)
372      steps[i] = (treenode[p->back->index - 1]->stateone[i] &
373                  p->statezero[i] & zeroanc[i]) |
374          (treenode[p->back->index - 1]->statezero[i] & p->stateone[i] &
375           fullset & (~zeroanc[i]));
376  } else {
377    for (i = 0; i < (words); i++)
378      steps[i] = treenode[p->back->index - 1]->stateone[i] &
379                 treenode[p->back->index - 1]->statezero[i] & p->stateone[i] &
380                 p->statezero[i];
381  }
382  j = 1;
383  l = 0;
384  for (i = 0; i < (chars); i++) {
385    l++;
386    if (l > bits) {
387      l = 1;
388      j++;
389    }
390    if (((1L << l) & steps[j - 1]) != 0) {
391      if (((1L << l) & zeroanc[j - 1]) != 0)
392        numszero[i] += weight[i];
393      else
394        numsone[i] += weight[i];
395    }
396  }
397}  /* dollop_count */
398
399
400void preorder(node *p, steptr numsone, steptr numszero, long local_words,
401                boolean local_dollo, long local_fullset, bitptr local_zeroanc, pointptr local_treenode)
402{
403  /* go back up tree setting up and counting interior node
404     states */
405
406  if (!p->tip) {
407    correct(p, local_fullset, local_dollo, local_zeroanc, local_treenode);
408    preorder(p->next->back, numsone,numszero, local_words, local_dollo, local_fullset,
409               local_zeroanc, local_treenode);
410    preorder(p->next->next->back, numsone,numszero, local_words, local_dollo, local_fullset,
411               local_zeroanc, local_treenode);
412  }
413  if (p->back != NULL)
414    dollop_count(p, numsone,numszero);
415}  /* preorder */
416
417
418void evaluate(node *r)
419{
420  /* Determines the number of losses or polymorphisms needed
421     for a tree. This is the minimum number needed to evolve
422     chars on this tree */
423  long i, stepnum, smaller;
424  double sum, term;
425
426  sum = 0.0;
427  for (i = 0; i < (chars); i++) {
428    global_numszero[i] = 0;
429    global_numsone[i] = 0;
430  }
431  for (i = 0; i < (words); i++)
432    zeroanc[i] = fullset;
433  postorder(r);
434  preorder(r, global_numsone, global_numszero, words, dollo, fullset, zeroanc, treenode);
435  for (i = 0; i < (words); i++)
436    zeroanc[i] = 0;
437  postorder(r);
438  preorder(r, global_numsone, global_numszero, words, dollo, fullset, zeroanc, treenode);
439  for (i = 0; i < (chars); i++) {
440    smaller = spp * weight[i];
441    numsteps[i] = smaller;
442    if (anczero[i]) {
443      numsteps[i] = global_numszero[i];
444      smaller = global_numszero[i];
445    }
446    if (ancone[i] && global_numsone[i] < smaller)
447      numsteps[i] = global_numsone[i];
448    stepnum = numsteps[i] + extras[i];
449    if (stepnum <= threshwt[i])
450      term = stepnum;
451    else
452      term = threshwt[i];
453    sum += term;
454    if (usertree && which <= maxuser)
455      fsteps[which - 1][i] = term;
456    guess[i] = '?';
457    if (!ancone[i] || (anczero[i] && global_numszero[i] < global_numsone[i]))
458      guess[i] = '0';
459    else if (!anczero[i] || (ancone[i] && global_numsone[i] < global_numszero[i]))
460      guess[i] = '1';
461  }
462  if (usertree && which <= maxuser) {
463    nsteps[which - 1] = sum;
464    if (which == 1) {
465      minwhich = 1;
466      minsteps = sum;
467    } else if (sum < minsteps) {
468      minwhich = which;
469      minsteps = sum;
470    }
471  }
472  like = -sum;
473}  /* evaluate */
474
475
476void savetree()
477{
478  /* record in place where each species has to be
479     added to reconstruct this tree */
480  long i, j;
481  node *p;
482  boolean done;
483
484  for (i = 0; i < (nonodes); i++)
485    place[i] = 0;
486  place[root->index - 1] = 1;
487  for (i = 1; i <= (spp); i++) {
488    p = treenode[i - 1];
489    while (place[p->index - 1] == 0) {
490      place[p->index - 1] = i;
491      p = p->back;
492      if (p != NULL)
493        p = treenode[p->index - 1];
494    }
495    if (i > 1) {
496      place[i - 1] = place[p->index - 1];
497      j = place[p->index - 1];
498      done = false;
499      while (!done) {
500        place[p->index - 1] = spp + i - 1;
501        p = treenode[p->index - 1];
502        p = p->back;
503        done = (p == NULL);
504        if (!done)
505          done = (place[p->index - 1] != j);
506      }
507    }
508  }
509}  /* savetree */
510
511
512void dollop_addtree(long *pos)
513{
514  /*puts tree from ARRAY place in its proper position
515    in ARRAY bestrees */
516  long i;
517  for (i =nextree - 1; i >= (*pos); i--) {
518    memcpy(bestrees[i].btree, bestrees[i - 1].btree, spp*sizeof(long));
519    bestrees[i].gloreange = bestrees[i - 1].gloreange;
520    bestrees[i].locreange = bestrees[i - 1].locreange;
521    bestrees[i].collapse = bestrees[i - 1].collapse;
522  }
523  for (i = 0; i < (spp); i++)
524    bestrees[(*pos) - 1].btree[i] = place[i];
525  nextree++;
526}  /* dollop_addtree */
527
528
529void tryadd(node *p, node **item, node **nufork)
530{
531  /* temporarily adds one fork and one tip to the tree.
532     if the location where they are added yields greater
533     "likelihood" than other locations tested up to that
534     time, then keeps that location as there */
535  long pos;
536  boolean found;
537
538  add(p, *item, *nufork, &root, treenode);
539  evaluate(root);
540  if (lastrearr) {
541    if (like >= bstlike2) {
542      savetree();
543      if (like > bstlike2) {
544        bestlike = bstlike2 = like;
545        pos = 1;
546        nextree = 1;
547        dollop_addtree(&pos);
548      } else {
549        pos = 0;
550        findtree(&found, &pos, nextree, place, bestrees);
551                /* findtree calls for a bestelm* but is getting */
552                /* a long**, LM                                 */
553        if (!found) {
554          if (nextree <= maxtrees)
555            dollop_addtree(&pos);
556        }
557      }
558    }
559  }
560  if (like > bestyet) {
561    bestyet = like;
562    there = p;
563  }
564  re_move(item, nufork, &root, treenode);
565}  /* tryadd */
566
567
568void addpreorder(node *p, node *item_, node *nufork_)
569{
570  /* traverses a binary tree, calling PROCEDURE tryadd
571     at a node before calling tryadd at its descendants */
572  node *item= item_;
573  node *nufork = nufork_;
574
575  if (p == NULL)
576    return;
577  tryadd(p, &item,&nufork);
578  if (!p->tip) {
579    addpreorder(p->next->back, item, nufork);
580    addpreorder(p->next->next->back, item, nufork);
581  }
582}  /* addpreorder */
583
584
585void tryrearr(node *p, node **r, boolean *success)
586{
587  /* evaluates one rearrangement of the tree.
588     if the new tree has greater "likelihood" than the old
589     one sets success := TRUE and keeps the new tree.
590     otherwise, restores the old tree */
591  node *frombelow, *whereto, *forknode;
592  double oldlike;
593
594  if (p->back == NULL)
595    return;
596  forknode = treenode[p->back->index - 1];
597  if (forknode->back == NULL)
598    return;
599  oldlike = bestyet;
600  if (p->back->next->next == forknode)
601    frombelow = forknode->next->next->back;
602  else
603    frombelow = forknode->next->back;
604  whereto = forknode->back;
605  re_move(&p, &forknode, &root, treenode);
606  add(whereto, p, forknode, &root, treenode);
607  evaluate(*r);
608  if (like <= oldlike) {
609    re_move(&p, &forknode, &root, treenode);
610    add(frombelow, p, forknode, &root, treenode);
611  } else {
612    (*success) = true;
613    bestyet = like;
614  }
615}  /* tryrearr */
616
617
618void repreorder(node *p, node **r, boolean *success)
619{
620  /* traverses a binary tree, calling PROCEDURE tryrearr
621     at a node before calling tryrearr at its descendants */
622  if (p == NULL)
623    return;
624  tryrearr(p, r,success);
625  if (!p->tip) {
626    repreorder(p->next->back, r,success);
627    repreorder(p->next->next->back, r,success);
628  }
629}  /* repreorder */
630
631
632void rearrange(node **r_)
633{
634  /* traverses the tree (preorder), finding any local
635     rearrangement which decreases the number of steps.
636     if traversal succeeds in increasing the tree's
637     "likelihood", PROCEDURE rearrange runs traversal again */
638  node **r         = r_;
639  boolean success  = true;
640
641  while (success) {
642    success = false;
643    repreorder(*r, r,&success);
644  }
645}  /* rearrange */
646
647
648void describe()
649{
650  /* prints ancestors, steps and table of numbers of steps in
651     each character */
652
653  if (treeprint)
654    fprintf(outfile, "\nrequires a total of %10.3f\n", -like);
655  if (stepbox) {
656    putc('\n', outfile);
657    writesteps(weights, dollo, numsteps);
658  }
659  if (questions)
660    guesstates(guess);
661  if (ancseq) {
662    hypstates(fullset, dollo, guess, treenode, root, garbage, zeroanc, oneanc);
663    putc('\n', outfile);
664  }
665  putc('\n', outfile);
666  if (trout) {
667    col = 0;
668    treeout(root, nextree, &col, root);
669  }
670}  /* describe */
671
672
673void initdollopnode(node **p, node **local_grbg, node *UNUSED_q, long UNUSED_len, long nodei,
674                     long *UNUSED_ntips, long *parens, initops whichinit,
675                     pointarray local_treenode, pointarray UNUSED_nodep, Char *str, Char *ch,
676                     FILE *fp_intree)
677{
678    (void)UNUSED_q;
679    (void)UNUSED_len;
680    (void)UNUSED_ntips;
681    (void)UNUSED_nodep;
682
683  /* initializes a node */
684  /* LM 7/27  I added this function and the commented lines around */
685  /* treeread() to get the program running, but all 4 move programs*/
686  /* are improperly integrated into the v4.0 support files.  As is */
687  /* this is a patchwork function         */
688  boolean minusread;
689  double valyew, divisor;
690
691  switch (whichinit) {
692  case bottom:
693    gnutreenode(local_grbg, p, nodei, chars, zeros);
694    local_treenode[nodei - 1] = *p;
695    break;
696  case nonbottom:
697    gnutreenode(local_grbg, p, nodei, chars, zeros);
698    break;
699  case tip:
700    match_names_to_data (str, local_treenode, p, spp);
701    break;
702  case length:         /* if there is a length, read it and discard value */
703    processlength(&valyew, &divisor, ch, &minusread, fp_intree, parens);
704    break;
705  default:      /*cases hslength,hsnolength,treewt,unittrwt,iter,*/
706    break;
707  }
708} /* initdollopnode */
709
710
711void maketree()
712{
713  /* constructs a binary tree from the pointers in treenode.
714     adds each node at location which yields highest "likelihood"
715     then rearranges the tree for greatest "likelihood" */
716  long i, j, numtrees, nextnode;
717  double gotlike;
718  node *item, *nufork, *dummy, *p;
719
720  steps = (bitptr)Malloc(words*sizeof(long));
721  fullset = (1L << (bits + 1)) - (1L << 1);
722  if (!usertree) {
723    for (i = 1; i <= (spp); i++)
724      enterorder[i - 1] = i;
725    if (jumble)
726      randumize(seed, enterorder);
727    root = treenode[enterorder[0] - 1];
728    add(treenode[enterorder[0] - 1], treenode[enterorder[1] - 1],
729        treenode[spp], &root, treenode);
730    if (progress) {
731      printf("Adding species:\n");
732      writename(0, 2, enterorder);
733#ifdef WIN32
734      phyFillScreenColor();
735#endif
736    }
737    lastrearr = false;
738    for (i = 3; i <= (spp); i++) {
739      bestyet = -350.0 * spp * chars;
740      item = treenode[enterorder[i - 1] - 1];
741      nufork = treenode[spp + i - 2];
742      addpreorder(root, item, nufork);
743      add(there, item, nufork, &root, treenode);
744      like = bestyet;
745      rearrange(&root);
746      if (progress) {
747        writename(i - 1, 1, enterorder);
748#ifdef WIN32
749        phyFillScreenColor();
750#endif
751      }
752      lastrearr = (i == spp);
753      if (lastrearr) {
754        if (progress) {
755          printf("\nDoing global rearrangements\n");
756          printf("  !");
757          for (j = 1; j <= (nonodes); j++)
758            putchar('-');
759          printf("!\n");
760#ifdef WIN32
761          phyFillScreenColor();
762#endif
763        }
764        bestlike = bestyet;
765        if (jumb == 1) {
766          bstlike2 = bestlike;
767          nextree = 1;
768        }
769        do {
770          if (progress)
771            printf("   ");
772          gotlike = bestlike;
773          for (j = 0; j < (nonodes); j++) {
774            bestyet = - 350.0 * spp * chars;
775            item = treenode[j];
776            if (item != root) {
777              nufork = treenode[j]->back;
778              re_move(&item, &nufork, &root, treenode);
779              there = root;
780              addpreorder(root, item, nufork);
781              add(there, item, nufork, &root, treenode);
782            }
783            if (progress) {
784              putchar('.');
785              fflush(stdout);
786            }
787          }
788          if (progress) {
789            putchar('\n');
790#ifdef WIN32
791            phyFillScreenColor();
792#endif
793
794          }
795        } while (bestlike > gotlike);
796      }
797    }
798    if (progress)
799      putchar('\n');
800    for (i = spp - 1; i >= 1; i--)
801      re_move(&treenode[i], &dummy, &root, treenode);
802    if (jumb == njumble) {
803      if (treeprint) {
804        putc('\n', outfile);
805        if (nextree == 2)
806          fprintf(outfile, "One most parsimonious tree found:\n");
807        else
808          fprintf(outfile, "%6ld trees in all found\n", nextree - 1);
809      }
810      if (nextree > maxtrees + 1) {
811        if (treeprint)
812          fprintf(outfile, "here are the first%4ld of them\n", (long)maxtrees);
813        nextree = maxtrees + 1;
814      }
815      if (treeprint)
816        putc('\n', outfile);
817      for (i = 0; i <= (nextree - 2); i++) {
818        root = treenode[0];
819        add(treenode[0], treenode[1], treenode[spp], &root, treenode);
820        for (j = 3; j <= spp; j++) {
821          add(treenode[bestrees[i].btree[j - 1] - 1], treenode[j - 1],
822              treenode[spp + j - 2], &root, treenode);}
823        evaluate(root);
824        printree(1.0, treeprint, root);
825        describe();
826        for (j = 1; j < (spp); j++)
827          re_move(&treenode[j], &dummy, &root, treenode);
828      }
829    }
830  } else {
831    openfile(&intree,INTREE,"input tree file", "r",progname,intreename);
832    fscanf(intree, "%ld%*[^\n]", &numtrees);
833    getc(intree);
834    if (numtrees > 2) {
835      initseed(&inseed, &inseed0, seed);
836      printf("\n");
837    }
838    if (treeprint) {
839      fprintf(outfile, "User-defined tree");
840      if (numtrees > 1)
841        putc('s', outfile);
842      fprintf(outfile, ":\n");
843    }
844    names = (boolean *)Malloc(spp*sizeof(boolean));
845    which = 1;
846    firsttree = true;                       /**/
847    nodep = NULL;                           /**/
848    nextnode = 0;                           /**/
849    haslengths = 0;                         /**/
850    phirst = 0;                             /**/
851    zeros = (long *)Malloc(chars*sizeof(long));         /**/
852    for (i = 0; i < chars; i++)             /**/
853      zeros[i] = 0;                         /**/
854    while (which <= numtrees) {
855      treeread(intree, &root, treenode, &goteof, &firsttree,
856                nodep, &nextnode, &haslengths,
857                &grbg, initdollopnode); /*debug*/
858      for (i = spp; i < (nonodes); i++) {
859        p = treenode[i];
860        for (j = 1; j <= 3; j++) {
861          p->stateone = (bitptr)Malloc(words*sizeof(long));
862          p->statezero = (bitptr)Malloc(words*sizeof(long));
863          p = p->next;
864        }
865      } /* debug: see comment at initdollopnode() */
866      if (treeprint)
867        fprintf(outfile, "\n\n");
868      evaluate(root);
869      printree(1.0, treeprint, root);
870      describe();
871      which++;
872    }
873    FClose(intree);
874    fprintf(outfile, "\n\n");
875    if (numtrees > 1 && chars > 1)
876      standev(numtrees, minwhich, minsteps, nsteps, fsteps, seed);
877    free(names);
878  }
879  if (jumb == njumble) {
880    if (progress) {
881      printf("Output written to file \"%s\"\n\n", outfilename);
882      if (trout)
883        printf("Trees also written onto file \"%s\"\n\n", outtreename);
884    }
885    free(steps);
886    if (ancseq)
887      freegarbage(&garbage);
888  }
889}  /* maketree */
890
891
892int main(int argc, Char *argv[])
893{  /* Dollo or polymorphism parsimony by uphill search */
894#ifdef MAC
895  argc = 1;           /* macsetup("Dollop","");  */
896  argv[0] = "Dollop";
897#endif
898  init(argc, argv);
899  /* reads in spp, chars, and the data. Then calls maketree to
900     construct the tree */
901  progname = argv[0];
902  openfile(&infile,INFILE,"input file", "r",argv[0],infilename);
903  openfile(&outfile,OUTFILE,"output file", "w",argv[0],outfilename);
904
905  ibmpc = IBMCRT;
906  ansi = ANSICRT;
907  garbage = NULL;
908  mulsets = false;
909  msets = 1;
910  firstset = true;
911  bits = 8*sizeof(long) - 1;
912  doinit();
913  if (weights || justwts)
914    openfile(&weightfile,WEIGHTFILE,"weights file","r",argv[0],weightfilename);
915  if (trout)
916    openfile(&outtree,OUTTREE,"output tree file", "w",argv[0],outtreename);
917  if(ancvar)
918      openfile(&ancfile,ANCFILE,"ancestors file", "r",argv[0],ancfilename);
919
920  if (dollo)
921      fprintf(outfile, "Dollo");
922  else
923      fprintf(outfile, "Polymorphism");
924  fprintf(outfile, " parsimony method\n\n");
925  if (printdata && justwts)
926      fprintf(outfile, "%2ld species, %3ld  characters\n\n", spp, chars);
927
928  for (ith = 1; ith <= (msets); ith++) {
929    if (msets > 1 && !justwts) {
930      fprintf(outfile, "Data set # %ld:\n\n",ith);
931      if (progress)
932        printf("\nData set # %ld:\n",ith);
933    }
934    if (justwts){
935        fprintf(outfile, "Weights set # %ld:\n\n", ith);
936        if (progress)
937            printf("\nWeights set # %ld:\n\n", ith);
938    }
939    if (printdata && !justwts)
940        fprintf(outfile, "%2ld species, %3ld  characters\n\n", spp, chars);
941    doinput();
942    if (ith == 1)
943      firstset = false;
944    for (jumb = 1; jumb <= njumble; jumb++)
945      maketree();
946  }
947  FClose(infile);
948  FClose(outfile);
949  FClose(outtree);
950#ifdef MAC
951  fixmacfile(outfilename);
952  fixmacfile(outtreename);
953#endif
954#ifdef WIN32
955  phyRestoreConsoleAttributes();
956#endif
957  return 0;
958}  /* Dollo or polymorphism parsimony by uphill search */
959
Note: See TracBrowser for help on using the repository browser.