source: tags/initial/GDE/PHYLIP/mix.c

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.9 KB
Line 
1#include "phylip.h"
2
3/* version 3.52c. (c) Copyright 1993 by Joseph Felsenstein.
4   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, and Andrew Keeffe.
5   Permission is granted to copy and use this program provided no fee is
6   charged for it and provided that this copyright notice is not removed. */
7
8#define nmlngth         10   /* number of characters in species name    */
9#define maxtrees        100  /* maximum number of tied trees stored     */
10#define maxuser         10   /* maximum number of user-defined trees    */
11
12#define ibmpc0          false
13#define ansi0           true
14#define vt520           false
15#define down            2
16
17typedef long *bitptr;
18/* nodes will form a binary tree */
19
20typedef struct node {           /* describes a tip species or an ancestor */
21  struct node *next, *back;     /* pointers to nodes                      */
22  long index;                   /* number of the node                     */
23  boolean tip, bottom,visited;  /* present species are tips of tree       */
24  bitptr fulstte1, fulstte0;  /* see in PROCEDURE fillin                */
25  bitptr empstte1, empstte0;  /* see in PROCEDURE fillin                */
26  bitptr fulsteps,empsteps;
27  long xcoord, ycoord, ymin;    /* used by printree                       */
28  long ymax;
29} node;
30
31typedef long *steptr;
32typedef node **pointptr;
33typedef long longer[6];
34typedef long *placeptr;
35char ch;
36
37typedef struct gbit {
38  bitptr bits_;
39  struct gbit *next;
40} gbit;
41
42
43node *root;
44FILE *infile, *outfile, *treefile;
45long spp, nonodes, chars, words, inseed, outgrno,  datasets, ith,
46            j, l, jumb, njumble;
47/* spp = number of species
48  nonodes = number of nodes in tree
49  chars = number of binary characters
50  words = number of words needed to represent characters of one organism
51  outgrno indicates outgroup */
52boolean jumble, usertree, weights, thresh, ancvar, questions, allsokal,
53               allwagner, mixture, trout, noroot, outgropt, didreroot,
54                printdata, progress, treeprint, stepbox, ancseq,
55               mulsets, firstset, ibmpc, vt52, ansi;
56steptr extras, weight;
57boolean *ancone, *anczero, *ancone0, *anczero0;
58pointptr treenode;   /* pointers to all nodes in tree */
59char **nayme;   /* names of species */
60double threshold;
61double *threshwt;
62bitptr wagner, wagner0;
63longer seed;
64long *enterorder;
65double **fsteps;
66char *guess;
67long **bestrees;
68steptr numsteps, numsone, numszero;
69gbit *garbage;
70long bits =  (8*sizeof(long) - 1);
71
72void openfile(fp,filename,mode,application,perm)
73FILE **fp;
74char *filename;
75char *mode;
76char *application;
77char *perm;
78{
79  FILE *of;
80  char file[100];
81  strcpy(file,filename);
82  while (1){
83    of = fopen(file,mode);
84    if (of)
85      break;
86    else {
87      switch (*mode){
88      case 'r':
89        printf("%s:  can't read %s\n",application,file);
90        file[0] = '\0';
91        while (file[0] =='\0'){
92          printf("Please enter a new filename>");
93          gets(file);}
94        break;
95      case 'w':
96        printf("%s: can't write %s\n",application,file);
97        file[0] = '\0';
98        while (file[0] =='\0'){
99          printf("Please enter a new filename>");
100          gets(file);}
101        break;
102      }
103    }
104  }
105  *fp=of;
106  if (perm != NULL)
107    strcpy(perm,file);
108}
109
110void gnu(p)
111gbit **p;
112{
113  /* this and the following are do-it-yourself garbage collectors.
114     Make a new node or pull one off the garbage list */
115  if (garbage != NULL) {
116    *p = garbage;
117    garbage = garbage->next;
118  } else {
119    *p = (gbit *)Malloc(sizeof(gbit));
120    (*p)->bits_ = (bitptr)Malloc(words*sizeof(long));
121  }
122  (*p)->next = NULL;
123}  /* gnu */
124
125
126void chuck(p)
127gbit *p;
128{
129  /* collect garbage on p -- put it on front of garbage list */
130  p->next = garbage;
131  garbage = p;
132}  /* chuck */
133
134
135double randum(seed)
136long *seed;
137{
138  /* random number generator -- slow but machine independent */
139  long i, j, k, sum;
140  longer mult, newseed;
141  double x;
142
143  mult[0] = 13;
144  mult[1] = 24;
145  mult[2] = 22;
146  mult[3] = 6;
147  for (i = 0; i <= 5; i++)
148    newseed[i] = 0;
149  for (i = 0; i <= 5; i++) {
150    sum = newseed[i];
151    k = i;
152    if (i > 3)
153      k = 3;
154    for (j = 0; j <= k; j++)
155      sum += mult[j] * seed[i - j];
156    newseed[i] = sum;
157    for (j = i; j <= 4; j++) {
158      newseed[j + 1] += newseed[j] / 64;
159      newseed[j] &= 63;
160    }
161  }
162  memcpy(seed, newseed, sizeof(longer));
163  seed[5] &= 3;
164  x = 0.0;
165  for (i = 0; i <= 5; i++)
166    x = x / 64.0 + seed[i];
167  x /= 4.0;
168  return x;
169}  /* randum */
170
171
172void uppercase(ch)
173Char *ch;
174{  /* convert a character to upper case -- either ASCII or EBCDIC */
175     *ch = (islower (*ch) ? toupper(*ch) : (*ch));
176}  /* uppercase */
177
178void newline(i, j, k)
179long i, j, k;
180{
181  /* go to new line if i is a multiple of j, indent k spaces */
182  long m;
183
184  if ((i - 1) % j != 0 || i <= 1)
185    return;
186  putc('\n', outfile);
187  for (m = 1; m <= k; m++)
188    putc(' ', outfile);
189}  /* newline */
190
191
192void getoptions()
193{
194  /* interactively set options */
195  long i, inseed0;
196  Char ch;
197  boolean  done1;
198
199  fprintf(outfile, "\nMixed parsimony algorithm, version %s\n\n",VERSION);
200  putchar('\n');
201  jumble = false;
202  njumble = 1;
203  outgrno = 1;
204  outgropt = false;
205  thresh = false;
206  threshold = spp;
207  trout = true;
208  usertree = false;
209  weights = false;
210  ancvar = false;
211  allsokal = false;
212  allwagner = true;
213  mixture = false;
214  printdata = false;
215  progress = true;
216  treeprint = true;
217  stepbox = false;
218  ancseq = false;
219  for (;;) {
220    printf(ansi ?  "\033[2J\033[H" :
221           vt52 ?  "\033E\033H"    : "\n");
222    printf("\nMixed parsimony algorithm, version %s\n\n",VERSION);
223    printf("Settings for this run:\n");
224    printf("  U                 Search for best tree?  %s\n",
225           (usertree ? "No, use user trees in input file" : "Yes"));
226    printf("  X                     Use Mixed method?  %s\n",
227           (mixture ? "Yes" : "No"));
228    printf("  P                     Parsimony method?");
229    if (!mixture) {
230      printf("  %s\n",(allwagner ? "Wagner" : "Camin-Sokal"));
231    } else
232      printf("  (methods in mixture)\n");
233    if (!usertree) {
234      printf("  J     Randomize input order of species?");
235      if (jumble)
236        printf("  Yes (seed =%8ld,%3ld times)\n", inseed0, njumble);
237      else
238        printf("  No. Use input order\n");
239    }
240    printf("  O                        Outgroup root?");
241    if (outgropt)
242      printf("  Yes, at species number%3ld\n", outgrno);
243    else
244      printf("  No, use as outgroup species%3ld\n", outgrno);
245    printf("  T              Use Threshold parsimony?");
246    if (thresh)
247      printf("  Yes, count steps up to%4.1f per char.\n", threshold);
248    else
249      printf("  No, use ordinary parsimony\n");
250    printf("  A   Use ancestral states in input file?  %s\n",
251    (ancvar ? "Yes" : "No"));
252    printf("  M           Analyze multiple data sets?");
253    if (mulsets)
254      printf("  Yes, %2ld sets\n", datasets);
255    else
256      printf("  No\n");
257    printf("  0   Terminal type (IBM PC, VT52, ANSI)?  %s\n",
258           (ibmpc ? "IBM PC" :
259            ansi  ? "ANSI"   :
260            vt52  ? "VT52"   : "(none)"));
261
262    printf("  1    Print out the data at start of run  %s\n",
263           (printdata ? "Yes" : "No"));
264    printf("  2  Print indications of progress of run  %s\n",
265           (progress ? "Yes" : "No"));
266    printf("  3                        Print out tree  %s\n",
267          (treeprint ? "Yes" : "No"));
268    printf("  4     Print out steps in each character  %s\n",
269           (stepbox ? "Yes" : "No"));
270    printf("  5     Print states at all nodes of tree  %s\n",
271           (ancseq ? "Yes" : "No"));
272    printf("  6       Write out trees onto tree file?  %s\n",
273           (trout ? "Yes" : "No"));
274    printf("\nAre these settings correct? ");
275    printf("(type Y or the letter for one to change)\n");
276    scanf("%c%*[^\n]", &ch);
277    getchar();
278    if (ch == '\n')
279      ch = ' ';
280    uppercase(&ch);
281    if (ch == 'Y')
282      break;
283    if (strchr("JOTUMPAX1234560",ch)){
284      switch (ch) {
285       
286      case 'U':
287        usertree = !usertree;
288        break;
289       
290      case 'X':
291        mixture = !mixture;
292        break;
293       
294      case 'P':
295        allwagner = !allwagner;
296        break;
297       
298      case 'A':
299        ancvar = !ancvar;
300        break;
301       
302      case 'J':
303        jumble = !jumble;
304        if (jumble) {
305          do {
306            printf("Random number seed (must be odd)?\n");
307            scanf("%ld%*[^\n]", &inseed);
308            getchar();
309          } while (!(inseed & 1));
310          inseed0 = inseed;
311          for (i = 0; i <= 5; i++)
312            seed[i] = 0;
313          i = 0;
314          do {
315            seed[i] = inseed & 63;
316            inseed /= 64;
317            i++;
318          } while (inseed != 0);
319          printf("Number of times to jumble?\n");
320          scanf("%ld%*[^\n]", &njumble);
321          getchar();
322        }
323        else njumble = 1;
324        break;
325       
326      case 'O':
327        outgropt = !outgropt;
328        if (outgropt) {
329          done1 = true;
330          do {
331            printf("Type number of the outgroup:\n");
332            scanf("%ld%*[^\n]", &outgrno);
333            getchar();
334            done1 = (outgrno >= 1 && outgrno <= spp);
335            if (!done1) {
336              printf("BAD OUTGROUP NUMBER: %4ld\n", outgrno);
337              printf("  Must be in range 1 -%2ld\n", spp);
338            }
339          } while (done1 != true);
340        }
341        break;
342       
343      case 'T':
344        thresh = !thresh;
345        if (thresh) {
346          done1 = false;
347          do {
348            printf("What will be the threshold value?\n");
349            scanf("%lf%*[^\n]", &threshold);
350            getchar();
351            done1 = (threshold >= 1.0);
352            if (!done1)
353              printf("BAD THRESHOLD VALUE:  it must be greater than 1\n");
354            else
355              threshold = (long)(threshold * 10.0 + 0.5) / 10.0;
356          } while (done1 != true);
357        }
358        break;
359       
360      case 'M':
361        mulsets = !mulsets;
362        if (mulsets) {
363          done1 = false;
364          do {
365            printf("How many data sets?\n");
366            scanf("%ld%*[^\n]", &datasets);
367            getchar();
368            done1 = (datasets >= 1);
369            if (!done1)
370              printf("BAD DATA SETS NUMBER:  it must be greater than 1\n");
371          } while (done1 != true);
372        }
373        break;
374       
375      case '0':
376        if (ibmpc) {
377          ibmpc = false;
378          vt52 = true;
379        } else {
380          if (vt52) {
381            vt52 = false;
382            ansi = true;
383          } else if (ansi)
384            ansi = false;
385          else
386            ibmpc = true;
387        }
388        break;
389       
390      case '1':
391        printdata = !printdata;
392        break;
393       
394      case '2':
395        progress = !progress;
396        break;
397       
398      case '3':
399        treeprint = !treeprint;
400        break;
401       
402      case '4':
403        stepbox = !stepbox;
404        break;
405       
406      case '5':
407        ancseq = !ancseq;
408        break;
409       
410      case '6':
411        trout = !trout;
412        break;
413      }
414    } else
415      printf("Not a possible option!\n");
416  }
417  allsokal = (!allwagner && !mixture);
418}  /* getoptions */
419
420void inputnumbers()
421{
422  /* input the numbers of species and of characters */
423  fscanf(infile, "%ld%ld", &spp, &chars);
424  if (printdata)
425    fprintf(outfile, "%2ld species, %3ld  characters\n", spp, chars);
426  if (printdata)
427    putc('\n', outfile);
428  words = chars / bits + 1;
429  nonodes = spp * 2 - 1;
430}  /* inputnumbers */
431
432
433Static Void doinit()
434{
435  /* initializes variables */
436  long i;
437  node *p, *q;
438
439  inputnumbers();
440  getoptions();
441  treenode = (pointptr)Malloc(nonodes*sizeof(node *));
442  for (i = 0; i < (spp); i++) {
443    treenode[i] = (node *)Malloc(sizeof(node));
444    treenode[i]->fulstte1 = (bitptr)Malloc(words*sizeof(long));
445    treenode[i]->fulstte0 = (bitptr)Malloc(words*sizeof(long));
446    treenode[i]->empstte1 = (bitptr)Malloc(words*sizeof(long));
447    treenode[i]->empstte0 = (bitptr)Malloc(words*sizeof(long));
448    treenode[i]->fulsteps = (bitptr)Malloc(words*sizeof(long));
449    treenode[i]->empsteps = (bitptr)Malloc(words*sizeof(long));
450  }
451  for (i = spp; i < (nonodes); i++) {
452    q = NULL;
453    for (j = 1; j <= 3; j++) {
454      p = (node *)Malloc(sizeof(node));
455      p->fulstte1 = (bitptr)Malloc(words*sizeof(long));
456      p->fulstte0 = (bitptr)Malloc(words*sizeof(long));
457      p->empstte1 = (bitptr)Malloc(words*sizeof(long));
458      p->empstte0 = (bitptr)Malloc(words*sizeof(long));
459      p->fulsteps = (bitptr)Malloc(words*sizeof(long));
460      p->empsteps = (bitptr)Malloc(words*sizeof(long));
461      p->next = q;
462      q = p;
463    }
464    p->next->next->next = p;
465    treenode[i] = p;
466  }
467}  /* doinit */
468
469void inputmixture()
470{
471  /* input mixture of methods */
472  long i, j, k;
473  Char ch;
474  boolean wag;
475
476  for (i = 1; i < nmlngth; i++) {
477    ch = getc(infile);
478    if (ch == '\n')
479      ch = ' ';
480  }
481  for (i = 0; i < (words); i++)
482    wagner0[i] = 0;
483  j = 0;
484  k = 1;
485  for (i = 1; i <= (chars); i++) {
486    do {
487      if (eoln(infile)) {
488        fscanf(infile, "%*[^\n]");
489        getc(infile);
490      }
491      ch = getc(infile);
492      if (ch == '\n')
493        ch = ' ';
494    } while (ch == ' ');
495    uppercase(&ch);
496    wag = false;
497    if (ch == 'W' || ch == '?')
498      wag = true;
499    else if (ch == 'S' || ch == 'C')
500      wag = false;
501    else {
502      printf("BAD METHOD: %c\n", ch);
503      exit(-1);
504    }
505    j++;
506    if (j > bits) {
507      j = 1;
508      k++;
509    }
510    if (wag)
511      wagner0[k - 1] = ((long)wagner0[k - 1]) | (1L << ((int)j));
512  }
513  fscanf(infile, "%*[^\n]");
514  getc(infile);
515}  /* inputmixture */
516
517void printmixture()
518{
519  /* print out list of parsimony methods */
520  long i, k, l;
521
522  fprintf(outfile, "Parsimony methods:\n");
523  l = 0;
524  k = 1;
525  for (i = 1; i <= nmlngth + 3; i++)
526    putc(' ', outfile);
527  for (i = 1; i <= (chars); i++) {
528    newline(i, 55L, nmlngth + 3L);
529    l++;
530    if (l > bits) {
531      l = 1;
532      k++;
533    }
534    if ((unsigned long)l < 32 && ((1L << l) & wagner[k - 1]) != 0)
535      putc('W', outfile);
536    else
537      putc('S', outfile);
538    if (i % 5 == 0)
539      putc(' ', outfile);
540  }
541  fprintf(outfile, "\n\n");
542}  /* printmixture */
543
544void inputweights()
545{
546  /* input the character weights, 0-9 and A-Z for weights 0 - 35 */
547  Char ch;
548  long i;
549
550  for (i = 1; i < nmlngth; i++) {
551    ch = getc(infile);
552    if (ch == '\n')
553      ch = ' ';
554  }
555  for (i = 0; i < (chars); i++) {
556    do {
557      if (eoln(infile)) {
558        fscanf(infile, "%*[^\n]");
559        getc(infile);
560      }
561      ch = getc(infile);
562      if (ch == '\n')
563        ch = ' ';
564    } while (ch == ' ');
565    weight[i] = 1;
566    if (isdigit(ch))
567      weight[i] = ch - '0';
568    else if (isalpha(ch)) {
569      uppercase(&ch);
570      if (ch >= 'A' && ch <= 'I')
571        weight[i] = ch - 55;
572      else if (ch >= 'J' && ch <= 'R')
573        weight[i] = ch - 55;
574      else
575        weight[i] = ch - 55;
576    } else {
577      printf("BAD WEIGHT CHARACTER: %c\n", ch);
578      exit(-1);
579    }
580  }
581  fscanf(infile, "%*[^\n]");
582  getc(infile);
583  weights = true;
584}  /* inputweights */
585
586void printweights()
587{
588  /* print out the weights of characters */
589  long i, j, k;
590
591  fprintf(outfile, "Characters are weighted as follows:\n");
592  fprintf(outfile, "       ");
593  for (i = 0; i <= 9; i++)
594    fprintf(outfile, "%3ld", i);
595  fprintf(outfile, "\n      *---------------------------------\n");
596  for (j = 0; j <= (chars / 10); j++) {
597    fprintf(outfile, "%5ld!  ", j * 10);
598    for (i = 0; i <= 9; i++) {
599      k = j * 10 + i;
600      if (k > 0 && k <= chars)
601        fprintf(outfile, "%3ld", weight[k - 1]);
602      else
603        fprintf(outfile, "   ");
604    }
605    putc('\n', outfile);
606  }
607  putc('\n', outfile);
608}  /* printweights */
609
610void inputancestors()
611{
612  /* reads the ancestral states for each character */
613  long i;
614  Char ch;
615
616  for (i = 1; i < nmlngth; i++) {
617    ch = getc(infile);
618    if (ch == '\n')
619      ch = ' ';
620  }
621  for (i = 0; i < (chars); i++) {
622    anczero0[i] = true;
623    ancone0[i] = true;
624    do {
625      if (eoln(infile)) {
626        fscanf(infile, "%*[^\n]");
627        getc(infile);
628      }
629      ch = getc(infile);
630      if (ch == '\n')
631        ch = ' ';
632    } while (ch == ' ');
633    if (ch == 'p')
634      ch = 'P';
635    if (ch == 'b')
636      ch = 'B';
637    if (ch == '0' || ch == '1' || ch == 'P' || ch == 'B' || ch == '?') {
638      switch (ch) {
639
640      case '1':
641        anczero0[i] = false;
642        break;
643
644      case '0':
645        ancone0[i] = false;
646        break;
647
648      case 'P':
649        /* blank case */
650        break;
651
652      case 'B':
653        /* blank case */
654        break;
655
656      case '?':
657        /* blank case */
658        break;
659      }
660    } else {
661      printf("BAD ANCESTOR STATE: %c AT CHARACTER %4ld\n", ch, i + 1);
662      exit(-1);
663    }
664  }
665  fscanf(infile, "%*[^\n]");
666  getc(infile);
667}  /* inputancestors */
668
669void printancestors()
670{
671  /* print out list of ancestral states */
672  long i;
673
674  fprintf(outfile, "Ancestral states:\n");
675  for (i = 1; i <= nmlngth + 3; i++)
676    putc(' ', outfile);
677  for (i = 1; i <= (chars); i++) {
678    newline(i, 55L, nmlngth + 3L);
679    if (ancone[i - 1] && anczero[i - 1])
680      putc('?', outfile);
681    else if (ancone[i - 1])
682      putc('1', outfile);
683    else
684      putc('0', outfile);
685    if (i % 5 == 0)
686      putc(' ', outfile);
687  }
688  fprintf(outfile, "\n\n");
689}  /* printancestor */
690
691void inputoptions()
692{
693  /* input the information on the options */
694  Char ch;
695  long extranum, i, cursp, curchs;
696  boolean avar, mix;
697
698  if (!firstset) {
699    if (eoln(infile)) {
700      fscanf(infile, "%*[^\n]");
701      getc(infile);
702    }
703    fscanf(infile, "%ld%ld", &cursp, &curchs);
704    if (cursp != spp) {
705      printf("\nERROR: INCONSISTENT NUMBER OF SPECIES IN DATA SET %4ld\n",
706             ith);
707      exit(-1);
708    }
709    chars = curchs;
710  }
711  extranum = 0;
712  avar = false;
713  mix = false;
714  while (!eoln(infile)) {
715    ch = getc(infile);
716    if (ch == '\n')
717      ch = ' ';
718    uppercase(&ch);
719    if (ch == 'A' || ch == 'M' || ch == 'W')
720      extranum++;
721    else if (ch != ' ') {
722      printf("BAD OPTION CHARACTER: %c\n", ch);
723      exit(-1);
724    }
725  }
726  fscanf(infile, "%*[^\n]");
727  getc(infile);
728  for (i = 0; i < (chars); i++)
729    weight[i] = 1;
730  for (i = 1; i <= extranum; i++) {
731    ch = getc(infile);
732    if (ch == '\n')
733      ch = ' ';
734    uppercase(&ch);
735    if (ch != 'A' && ch != 'M' && ch != 'W') {
736      printf("ERROR: INCORRECT AUXILIARY OPTIONS LINE");
737      printf(" WHICH STARTS WITH %c\n", ch);
738      exit(-1);
739    }
740    if (ch == 'A') {
741      avar = true;
742      if (!ancvar) {
743        printf("ERROR: ANCESTOR OPTION NOT CHOSEN IN MENU");
744        printf(" WITH OPTION %c IN INPUT\n", ch);
745        exit(-1);
746      } else
747        inputancestors();
748    }
749    if (ch == 'M') {
750      mix = true;
751      if (!mixture) {
752        printf("ERROR: MIXTURE OPTION NOT CHOSEN IN MENU");
753        printf(" WITH OPTION %c IN INPUT\n", ch);
754        exit(-1);
755      } else
756        inputmixture();
757    }
758    if (ch == 'W')
759      inputweights();
760  }
761  if (ancvar && !avar) {
762    printf("ERROR: ANCESTOR OPTION CHOSEN IN MENU");
763    printf(" WITH NO OPTION A IN INPUT\n");
764    exit(-1);
765  }
766  if (mixture && !mix) {
767    printf("ERROR: MIXTURE OPTION CHOSEN IN MENU WITH NO OPTION M IN INPUT\n");
768    exit(-1);
769  }
770  if (weights && printdata)
771    printweights();
772  for (i = 0; i < (words); i++) {
773    if (mixture && mix)
774      wagner[i] = wagner0[i];
775    else if (allsokal)
776      wagner[i] = 0;
777    else
778      wagner[i] = (1L << (bits + 1)) - (1L << 1);
779  }
780  if (allsokal)
781    fprintf(outfile, "Camin-Sokal parsimony method\n\n");
782  if (allwagner)
783    fprintf(outfile, "Wagner parsimony method\n\n");
784  if (mixture && mix && printdata)
785    printmixture();
786  for (i = 0; i < (chars); i++) {
787    if (!ancvar) {
788      anczero[i] = true;
789      ancone[i] = (i % bits >= -1 && i % bits < 31 &&
790                   ((1L << (i % bits + 1)) & wagner[i / bits]) != 0);
791    } else {
792      anczero[i] = anczero0[i];
793      ancone[i] = ancone0[i];
794    }
795  }
796  if (ancvar && avar && printdata)
797    printancestors();
798  noroot = true;
799  questions = false;
800  for (i = 0; i < (chars); i++) {
801    if (weight[i] > 0) {
802      noroot = (noroot && ancone[i] && anczero[i] &&
803          ((i % bits >= -1 && i % bits < 31 &&
804            ((1L << (i % bits + 1)) & wagner[i / bits]) != 0)
805                || threshold <= 2.0));
806    }
807    questions = (questions || (ancone[i] && anczero[i]));
808    threshwt[i] = threshold * weight[i];
809  }
810}  /* inputoptions */
811
812void inputdata()
813{
814  /* input the names and character state data for species */
815  long i, j, l;
816  char k;
817  Char charstate;
818  /* possible states are '0', '1', 'P', 'B', and '?' */
819  node *p;
820
821  putc('\n', outfile);
822  j = nmlngth + (chars + (chars - 1) / 10) / 2 - 4;
823  if (j < nmlngth - 1)
824    j = nmlngth - 1;
825  if (j > 36)
826    j = 36;
827  if (printdata) {
828    fprintf(outfile, "Name");
829    for (i = 1; i <= j; i++)
830      putc(' ', outfile);
831    fprintf(outfile, "Characters\n");
832    fprintf(outfile, "----");
833    for (i = 1; i <= j; i++)
834      putc(' ', outfile);
835    fprintf(outfile, "----------\n\n");
836  }
837  for (i = 0; i < (chars); i++)
838    extras[i] = 0;
839  for (i = 1; i <= (nonodes); i++) {
840    treenode[i - 1]->back = NULL;
841    treenode[i - 1]->tip = (i <= spp);
842    treenode[i - 1]->visited = false;
843    treenode[i - 1]->index = i;
844    if (i > spp) {
845      p = treenode[i - 1]->next;
846      while (p != treenode[i - 1]) {
847        p->back = NULL;
848        p->tip = false;
849        p->visited = false;
850        p->index = i;
851        p = p->next;
852      }
853    } else {
854      for (j = 0; j < nmlngth; j++) {
855        nayme[i - 1][j] = getc(infile);
856        if (nayme[i - 1][j] == '\n')
857          nayme[i - 1][j] = ' ';
858        if ( eof(infile) || eoln(infile)){
859          printf("ERROR: END-OF-LINE OR END-OF-FILE");
860          printf(" IN THE MIDDLE OF A SPECIES NAME\n");
861          exit(-1);}
862      }
863      if (printdata) {
864        for (j = 0; j < nmlngth; j++)
865          putc(nayme[i - 1][j], outfile);
866      }
867      fprintf(outfile, "   ");
868      for (j = 0; j < (words); j++) {
869        treenode[i - 1]->fulstte1[j] = 0;
870        treenode[i - 1]->fulstte0[j] = 0;
871        treenode[i - 1]->empstte1[j] = 0;
872        treenode[i - 1]->empstte0[j] = 0;
873      }
874      for (j = 1; j <= (chars); j++) {
875        k = (j - 1) % bits + 1;
876        l = (j - 1) / bits + 1;
877        do {
878          if (eoln(infile)) {
879            fscanf(infile, "%*[^\n]");
880            getc(infile);
881          }
882/*        anerror |= eof(infile); */
883          charstate = getc(infile);
884          if (charstate == '\n')
885            charstate = ' ';
886        } while (charstate == ' ');
887        if (charstate == 'b')     charstate = 'B';
888        if (charstate == 'p')     charstate = 'P';
889        if (charstate != '0' && charstate != '1' && charstate != '?' &&
890            charstate != 'P' && charstate != 'B') {
891          printf("ERROR: BAD CHARACTER STATE: %c ",charstate);
892          printf("AT CHARACTER %5ld OF SPECIES %3ld\n",j,i);
893          exit(-1);
894        }
895        if (printdata) {
896          newline(j, 55L, nmlngth + 3L);
897          putc(charstate, outfile);
898          if (j % 5 == 0)
899            putc(' ', outfile);
900        }
901        if (charstate == '1') {
902          treenode[i - 1]->fulstte1[l - 1] =
903            ((long)treenode[i - 1]->fulstte1[l - 1]) | (1L << k);
904          treenode[i - 1]->empstte1[l - 1] =
905            treenode[i - 1]->fulstte1[l - 1];
906        }
907        if (charstate == '0') {
908          treenode[i - 1]->fulstte0[l - 1] =
909            ((long)treenode[i - 1]->fulstte0[l - 1]) | (1L << k);
910          treenode[i - 1]->empstte0[l - 1] =
911            treenode[i - 1]->fulstte0[l - 1];
912        }
913        if (charstate == 'P' || charstate == 'B')
914          extras[j - 1] += weight[j - 1];
915      }
916      fscanf(infile, "%*[^\n]");
917      getc(infile);
918      if (printdata)
919        putc('\n', outfile);
920    }
921  }
922  fprintf(outfile, "\n\n");
923}  /* inputdata */
924
925
926void doinput()
927{
928  /* reads the input data */
929  inputoptions();
930  inputdata();
931}  /* doinput */
932
933main(argc, argv)
934int argc;
935Char *argv[];
936{  /* Mixed parsimony by uphill search */
937char infilename[100],outfilename[100],trfilename[100];
938#ifdef MAC
939  macsetup("Mix","");
940#endif
941  openfile(&infile,INFILE,"r",argv[0],infilename);
942  openfile(&outfile,OUTFILE,"w",argv[0],outfilename);
943
944  ibmpc = ibmpc0;
945  ansi = ansi0;
946  vt52 = vt520;
947  mulsets = false;
948  datasets = 1;
949  firstset = true;
950  garbage = NULL;
951  doinit();
952  if (usertree) {
953    fsteps = (double **)Malloc(maxuser*sizeof(double *));
954    for (j = 1; j <= maxuser; j++)
955      fsteps[j - 1] = (double *)Malloc(chars*sizeof(double));
956  }
957  bestrees = (long **)Malloc(maxtrees*sizeof(long *));
958  for (j = 1; j <= maxtrees; j++)
959    bestrees[j - 1] = (long *)Malloc(spp*sizeof(long));
960  extras = (steptr)Malloc(chars*sizeof(long));
961  weight = (steptr)Malloc(chars*sizeof(long));
962  threshwt = (double *)Malloc(chars*sizeof(double));
963  numsteps = (steptr)Malloc(chars*sizeof(long));
964  numszero = (steptr)Malloc(chars*sizeof(long));
965  numsone = (steptr)Malloc(chars*sizeof(long));
966  guess = (Char *)Malloc(chars*sizeof(Char));
967  nayme = (Char **)Malloc(spp*sizeof(Char *));
968  for (j = 1; j <= spp; j++)
969    nayme[j - 1] = (Char *)Malloc(nmlngth*sizeof(Char));
970  enterorder = (long *)Malloc(spp*sizeof(long));
971  ancone = (boolean *)Malloc(chars*sizeof(boolean));
972  anczero = (boolean *)Malloc(chars*sizeof(boolean));
973  ancone0 = (boolean *)Malloc(chars*sizeof(boolean));
974  anczero0 = (boolean *)Malloc(chars*sizeof(boolean));
975  wagner = (bitptr)Malloc(words*sizeof(long));
976  wagner0 = (bitptr)Malloc(words*sizeof(long));
977  if (trout)
978    openfile(&treefile,TREEFILE,"w",argv[0],trfilename);
979  for (ith = 1; ith <= datasets; ith++) {
980    doinput();
981    if (ith == 1)
982      firstset = false;
983    if (datasets > 1) {
984      fprintf(outfile, "Data set # %ld:\n\n",ith);
985      if (progress)
986        printf("\nData set # %ld:\n",ith);
987    }
988    for (jumb = 1; jumb <= njumble; jumb++)
989      maketree();
990  }
991  FClose(outfile);
992  FClose(infile);
993  FClose(treefile);
994#ifdef MAC
995  fixmacfile(trfilename);
996  fixmacfile(outfilename);
997#endif
998  exit(0);
999}  /* Mixed parsimony by uphill search */
1000
1001
1002int eof(f)
1003FILE *f;
1004{
1005    register int ch;
1006
1007    if (feof(f))
1008        return 1;
1009    if (f == stdin)
1010        return 0;
1011    ch = getc(f);
1012    if (ch == EOF)
1013        return 1;
1014    ungetc(ch, f);
1015    return 0;
1016}
1017
1018
1019int eoln(f)
1020FILE *f;
1021{
1022    register int ch;
1023
1024    ch = getc(f);
1025    if (ch == EOF)
1026        return 1;
1027    ungetc(ch, f);
1028    return (ch == '\n');
1029}
1030
1031void memerror()
1032{
1033printf("Error allocating memory\n");
1034exit(-1);
1035}
1036
1037
1038MALLOCRETURN *mymalloc(x)
1039long x;
1040{
1041MALLOCRETURN *mem;
1042mem = (MALLOCRETURN *)malloc((size_t)x);
1043if (!mem)
1044  memerror();
1045else
1046  return (MALLOCRETURN *)mem;
1047}
Note: See TracBrowser for help on using the repository browser.