source: branches/profile/GDE/PHYLIP/protpars.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: 49.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 enum {
13  universal, ciliate, mito, vertmito, flymito, yeastmito
14} codetype;
15
16/* nodes will form a binary tree */
17
18typedef struct gseq {
19  seqptr seq;
20  struct gseq *next;
21} gseq;
22
23#ifndef OLDC
24/* function prototypes */
25void   protgnu(gseq **);
26void   protchuck(gseq *);
27void   code(void);
28void   setup(void);
29void   getoptions(void);
30void   protalloctree(void);
31void   allocrest(void);
32void   doinit(void);
33void   protinputdata(void);
34
35void   protmakevalues(void);
36void   doinput(void);
37void   protfillin(node *, node *, node *);
38void   protpreorder(node *);
39void   protadd(node *, node *, node *);
40void   protre_move(node **, node **);
41void   evaluate(node *);
42void   protpostorder(node *);
43void   protreroot(node *);
44void   protsavetraverse(node *, long *, boolean *);
45
46void   protsavetree(long *, boolean *);
47void   tryadd(node *, node **, node **);
48void   addpreorder(node *, node *, node *);
49void   tryrearr(node *, boolean *);
50void   repreorder(node *, boolean *);
51void   rearrange(node **);
52void   protgetch(Char *);
53void   protaddelement(node **, long *, long *, boolean *);
54void   prottreeread(void);
55void   protancestset(long *, long *, long *, long *, long *);
56               
57void   prothyprint(long , long , boolean *, node *, boolean *, boolean *);
58void   prothyptrav(node *, sitearray *, long, long, long *, boolean *,
59                sitearray);
60void   prothypstates(long *);
61void   describe(void);
62void   maketree(void);
63void   reallocnode(node* p);
64void   reallocchars(void);
65/* function prototypes */
66#endif
67
68
69
70Char infilename[FNMLNGTH], outfilename[FNMLNGTH], intreename[FNMLNGTH], outtreename[FNMLNGTH], weightfilename[FNMLNGTH];
71node *root;
72long chars, col, msets, ith, njumble, jumb;
73/*   chars = number of sites in actual sequences */
74long inseed, inseed0;
75boolean jumble, usertree, weights, thresh, trout, progress, stepbox,
76    justwts, ancseq, mulsets, firstset;
77codetype whichcode;
78long fullset, fulldel;
79pointarray treenode;   /* pointers to all nodes in tree */
80double threshold;
81steptr threshwt;
82longer seed;
83long *enterorder;
84sitearray translate[(long)quest - (long)ala + 1];
85aas trans[4][4][4];
86long **fsteps;
87bestelm *bestrees;
88boolean dummy;
89gseq *garbage;
90node *temp, *temp1;
91Char ch;
92aas tmpa;
93char *progname;
94
95/* Local variables for maketree, propagated globally for c version: */
96long minwhich;
97double like, bestyet, bestlike, minsteps, bstlike2;
98boolean lastrearr, recompute;
99node *there;
100double nsteps[maxuser];
101long *place;
102boolean *names;
103
104
105void protgnu(gseq **p)
106{
107  /* this and the following are do-it-yourself garbage collectors.
108     Make a new node or pull one off the garbage list */
109  if (garbage != NULL) {
110    *p = garbage;
111    free((*p)->seq);
112    (*p)->seq = (seqptr)Malloc(chars*sizeof(sitearray));
113    garbage = garbage->next;
114  } else {
115    *p = (gseq *)Malloc(sizeof(gseq));
116    (*p)->seq = (seqptr)Malloc(chars*sizeof(sitearray));
117  }
118  (*p)->next = NULL;
119}  /* protgnu */
120
121
122void protchuck(gseq *p)
123{
124  /* collect garbage on p -- put it on front of garbage list */
125  p->next = garbage;
126  garbage = p;
127}  /* protchuck */
128
129
130void code()
131{
132  /* make up table of the code 1 = u, 2 = c, 3 = a, 4 = g */
133  trans[0][0][0] = phe;
134  trans[0][0][1] = phe;
135  trans[0][0][2] = leu;
136  trans[0][0][3] = leu;
137  trans[0][1][0] = ser;
138  trans[0][1][1] = ser1;
139  trans[0][1][2] = ser1;
140  trans[0][1][3] = ser1;
141  trans[0][2][0] = tyr;
142  trans[0][2][1] = tyr;
143  trans[0][2][2] = stop;
144  trans[0][2][3] = stop;
145  trans[0][3][0] = cys;
146  trans[0][3][1] = cys;
147  trans[0][3][2] = stop;
148  trans[0][3][3] = trp;
149  trans[1][0][0] = leu;
150  trans[1][0][1] = leu;
151  trans[1][0][2] = leu;
152  trans[1][0][3] = leu;
153  trans[1][1][0] = pro;
154  trans[1][1][1] = pro;
155  trans[1][1][2] = pro;
156  trans[1][1][3] = pro;
157  trans[1][2][0] = his;
158  trans[1][2][1] = his;
159  trans[1][2][2] = gln;
160  trans[1][2][3] = gln;
161  trans[1][3][0] = arg;
162  trans[1][3][1] = arg;
163  trans[1][3][2] = arg;
164  trans[1][3][3] = arg;
165  trans[2][0][0] = ileu;
166  trans[2][0][1] = ileu;
167  trans[2][0][2] = ileu;
168  trans[2][0][3] = met;
169  trans[2][1][0] = thr;
170  trans[2][1][1] = thr;
171  trans[2][1][2] = thr;
172  trans[2][1][3] = thr;
173  trans[2][2][0] = asn;
174  trans[2][2][1] = asn;
175  trans[2][2][2] = lys;
176  trans[2][2][3] = lys;
177  trans[2][3][0] = ser2;
178  trans[2][3][1] = ser2;
179  trans[2][3][2] = arg;
180  trans[2][3][3] = arg;
181  trans[3][0][0] = val;
182  trans[3][0][1] = val;
183  trans[3][0][2] = val;
184  trans[3][0][3] = val;
185  trans[3][1][0] = ala;
186  trans[3][1][1] = ala;
187  trans[3][1][2] = ala;
188  trans[3][1][3] = ala;
189  trans[3][2][0] = asp;
190  trans[3][2][1] = asp;
191  trans[3][2][2] = glu;
192  trans[3][2][3] = glu;
193  trans[3][3][0] = gly;
194  trans[3][3][1] = gly;
195  trans[3][3][2] = gly;
196  trans[3][3][3] = gly;
197  if (whichcode == mito)
198    trans[0][3][2] = trp;
199  if (whichcode == vertmito) {
200    trans[0][3][2] = trp;
201    trans[2][3][2] = stop;
202    trans[2][3][3] = stop;
203    trans[2][0][2] = met;
204  }
205  if (whichcode == flymito) {
206    trans[0][3][2] = trp;
207    trans[2][0][2] = met;
208    trans[2][3][2] = ser2;
209  }
210  if (whichcode == yeastmito) {
211    trans[0][3][2] = trp;
212    trans[1][0][2] = thr;
213    trans[2][0][2] = met;
214  }
215} /* code */
216
217
218void setup()
219{
220  /* set up set table to get aasets from aas */
221  aas a, b;
222  long i, j, k, l, s;
223
224  for (a = ala; (long)a <= (long)stop; a = (aas)((long)a + 1)) {
225    translate[(long)a - (long)ala][0] = 1L << ((long)a);
226    translate[(long)a - (long)ala][1] = 1L << ((long)a);
227  }
228  for (i = 0; i <= 3; i++) {
229    for (j = 0; j <= 3; j++) {
230      for (k = 0; k <= 3; k++) {
231        for (l = 0; l <= 3; l++) {
232          translate[(long)trans[i][j][k]][1] |= (1L << (long)trans[l][j][k]);
233          translate[(long)trans[i][j][k]][1] |= (1L << (long)trans[i][l][k]);
234          translate[(long)trans[i][j][k]][1] |= (1L << (long)trans[i][j][l]);
235        }
236      }
237    }
238  }
239  translate[(long)del - (long)ala][1] = 1L << ((long)del);
240  fulldel = (1L << ((long)stop + 1)) - (1L << ((long)ala));
241  fullset = fulldel & (~(1L << ((long)del)));
242  translate[(long)asx - (long)ala][0]
243    = (1L << ((long)asn)) | (1L << ((long)asp));
244  translate[(long)glx - (long)ala][0]
245    = (1L << ((long)gln)) | (1L << ((long)glu));
246  translate[(long)ser - (long)ala][0]
247    = (1L << ((long)ser1)) | (1L << ((long)ser2));
248  translate[(long)unk - (long)ala][0] = fullset;
249  translate[(long)quest - (long)ala][0] = fulldel;
250  translate[(long)asx - (long)ala][1] = translate[(long)asn - (long)ala][1]
251                                       | translate[(long)asp - (long)ala][1];
252  translate[(long)glx - (long)ala][1] = translate[(long)gln - (long)ala][1]
253                                       | translate[(long)glu - (long)ala][1];
254  translate[(long)ser - (long)ala][1] = translate[(long)ser1 - (long)ala][1]
255                                       | translate[(long)ser2 - (long)ala][1];
256  translate[(long)unk - (long)ala][1] = fullset;
257  translate[(long)quest - (long)ala][1] = fulldel;
258  for (a = ala; (long)a <= (long)quest; a = (aas)((long)a + 1)) {
259    s = 0;
260    for (b = ala; (long)b <= (long)stop; b = (aas)((long)b + 1)) {
261      if (((1L << ((long)b)) & translate[(long)a - (long)ala][1]) != 0)
262        s |= translate[(long)b - (long)ala][1];
263    }
264    translate[(long)a - (long)ala][2] = s;
265  }
266}  /* setup */
267
268
269void getoptions()
270{
271  /* interactively set options */
272  long loopcount, loopcount2;
273  Char ch, ch2;
274
275  fprintf(outfile, "\nProtein parsimony algorithm, version %s\n\n",VERSION);
276  putchar('\n');
277  jumble = false;
278  njumble = 1;
279  outgrno = 1;
280  outgropt = false;
281  thresh = false;
282  trout = true;
283  usertree = false;
284  weights = false;
285  whichcode = universal;
286  printdata = false;
287  progress = true;
288  treeprint = true;
289  stepbox = false;
290  ancseq = false;
291  interleaved = true;
292  loopcount = 0;
293  for (;;) {
294    cleerhome();
295    printf("\nProtein parsimony algorithm, version %s\n\n",VERSION);
296    printf("Setting for this run:\n");
297    printf("  U                 Search for best tree?  %s\n",
298           (usertree ? "No, use user trees in input file" : "Yes"));
299    if (!usertree) {
300      printf("  J   Randomize input order of sequences?");
301      if (jumble)
302        printf("  Yes (seed =%8ld,%3ld times)\n", inseed0, njumble);
303      else
304        printf("  No. Use input order\n");
305    }
306    printf("  O                        Outgroup root?");
307    if (outgropt)
308      printf("  Yes, at sequence number%3ld\n", outgrno);
309    else
310      printf("  No, use as outgroup species%3ld\n", outgrno);
311    printf("  T              Use Threshold parsimony?");
312    if (thresh)
313      printf("  Yes, count steps up to%4.1f per site\n", threshold);
314    else
315      printf("  No, use ordinary parsimony\n");
316    printf("  C               Use which genetic code?  %s\n",
317      (whichcode == universal) ? "Universal"                  :
318      (whichcode == ciliate)   ? "Ciliate"                    :
319      (whichcode == mito)      ? "Universal mitochondrial"    :
320      (whichcode == vertmito)  ? "Vertebrate mitochondrial"   :
321      (whichcode == flymito)   ? "Fly mitochondrial"          :
322      (whichcode == yeastmito) ? "Yeast mitochondrial"        : "");
323    printf("  W                       Sites weighted?  %s\n",
324           (weights ? "Yes" : "No"));
325    printf("  M           Analyze multiple data sets?");
326    if (mulsets)
327        printf("  Yes, %2ld %s\n", msets,
328               (justwts ? "sets of weights" : "data sets"));
329    else
330      printf("  No\n");
331    printf("  I          Input sequences interleaved?  %s\n",
332           (interleaved ? "Yes" : "No"));
333    printf("  0   Terminal type (IBM PC, ANSI, none)?  %s\n",
334           (ibmpc ? "IBM PC" : ansi ? "ANSI" : "(none)"));
335    printf("  1    Print out the data at start of run  %s\n",
336           (printdata ? "Yes" : "No"));
337    printf("  2  Print indications of progress of run  %s\n",
338           (progress ? "Yes" : "No"));
339    printf("  3                        Print out tree  %s\n",
340           (treeprint ? "Yes" : "No"));
341    printf("  4          Print out steps in each site  %s\n",
342           (stepbox ? "Yes" : "No"));
343    printf("  5  Print sequences at all nodes of tree  %s\n",
344           (ancseq ? "Yes" : "No"));
345    printf("  6       Write out trees onto tree file?  %s\n",
346           (trout ? "Yes" : "No"));
347    if(weights && justwts){
348        printf(
349         "WARNING:  W option and Multiple Weights options are both on.  ");
350        printf(
351         "The W menu option is unnecessary and has no additional effect. \n");
352    }
353    printf(
354   "\nAre these settings correct? (type Y or the letter for one to change)\n");
355    scanf("%c%*[^\n]", &ch);
356    getchar();
357    uppercase(&ch);
358    if (ch == 'Y')
359      break;
360    if (strchr("WCJOTUMI1234560",ch) != NULL){
361      switch (ch) {
362       
363      case 'J':
364        jumble = !jumble;
365        if (jumble)
366          initjumble(&inseed, &inseed0, seed, &njumble);
367        else njumble = 1;
368        break;
369     
370      case 'W':
371        weights = !weights;
372        break;
373 
374      case 'O':
375        outgropt = !outgropt;
376        if (outgropt)
377          initoutgroup(&outgrno, spp);
378        else outgrno = 1;
379        break;
380       
381      case 'T':
382        thresh = !thresh;
383        if (thresh)
384          initthreshold(&threshold);
385        break;
386
387      case 'C':
388        printf("\nWhich genetic code?\n");
389        printf(" type         for\n\n");
390        printf("   U           Universal\n");
391        printf("   M           Mitochondrial\n");
392        printf("   V           Vertebrate mitochondrial\n");
393        printf("   F           Fly mitochondrial\n");
394        printf("   Y           Yeast mitochondrial\n\n");
395        loopcount2 = 0;
396        do {
397          printf("type U, M, V, F, or Y\n");
398          scanf("%c%*[^\n]", &ch);
399          getchar();
400          if (ch == '\n')
401            ch = ' ';
402          uppercase(&ch);
403          countup(&loopcount2, 10);
404        } while (ch != 'U' && ch != 'M' && ch != 'V'
405                  && ch != 'F' && ch != 'Y');
406        switch (ch) {
407
408        case 'U':
409          whichcode = universal;
410          break;
411
412        case 'M':
413          whichcode = mito;
414          break;
415
416        case 'V':
417          whichcode = vertmito;
418          break;
419
420        case 'F':
421          whichcode = flymito;
422          break;
423
424        case 'Y':
425          whichcode = yeastmito;
426          break;
427        }
428        break;
429
430      case 'M':
431        mulsets = !mulsets;
432        if (mulsets){
433            printf("Multiple data sets or multiple weights?");
434          loopcount2 = 0;
435          do {
436            printf(" (type D or W)\n");
437#ifdef WIN32
438            phyFillScreenColor();
439#endif
440            scanf("%c%*[^\n]", &ch2);
441            getchar();
442            if (ch2 == '\n')
443              ch2 = ' ';
444            uppercase(&ch2);
445            countup(&loopcount2, 10);
446          } while ((ch2 != 'W') && (ch2 != 'D'));
447          justwts = (ch2 == 'W');
448          if (justwts)
449            justweights(&msets);
450          else
451            initdatasets(&msets);
452          if (!jumble) {
453            jumble = true;
454            initjumble(&inseed, &inseed0, seed, &njumble);
455          }
456        }
457        break;
458       
459      case 'I':
460        interleaved = !interleaved;
461        break;
462       
463      case 'U':
464        usertree = !usertree;
465        break;
466       
467      case '0':
468        initterminal(&ibmpc, &ansi);
469        break;
470       
471      case '1':
472        printdata = !printdata;
473        break;
474       
475      case '2':
476        progress = !progress;
477        break;
478       
479      case '3':
480        treeprint = !treeprint;
481        break;
482       
483      case '4':
484        stepbox = !stepbox;
485        break;
486       
487      case '5':
488        ancseq = !ancseq;
489        break;
490       
491      case '6':
492        trout = !trout;
493        break;
494      }
495    } else
496        printf("Not a possible option!\n");
497    countup(&loopcount, 100);
498  }
499}  /* getoptions */
500
501
502void protalloctree()
503{ /* allocate treenode dynamically */
504  long i, j;
505  node *p, *q;
506
507  treenode = (pointarray)Malloc(nonodes*sizeof(node *));
508  for (i = 0; i < (spp); i++) {
509    treenode[i] = (node *)Malloc(sizeof(node));
510    treenode[i]->numsteps = (steptr)Malloc(chars*sizeof(long));
511    treenode[i]->siteset = (seqptr)Malloc(chars*sizeof(sitearray));
512    treenode[i]->seq = (aas *)Malloc(chars*sizeof(aas));
513  }
514  for (i = spp; i < (nonodes); i++) {
515    q = NULL;
516    for (j = 1; j <= 3; j++) {
517      p = (node *)Malloc(sizeof(node));
518      p->numsteps = (steptr)Malloc(chars*sizeof(long));
519      p->siteset = (seqptr)Malloc(chars*sizeof(sitearray));
520      p->seq = (aas *)Malloc(chars*sizeof(aas));
521      p->next = q;
522      q = p;
523    }
524    p->next->next->next = p;
525    treenode[i] = p;
526  }
527}  /* protalloctree */
528
529
530void reallocnode(node* p) 
531{
532  free(p->numsteps);
533  free(p->siteset);
534  free(p->seq);
535  p->numsteps = (steptr)Malloc(chars*sizeof(long));
536  p->siteset = (seqptr)Malloc(chars*sizeof(sitearray));
537  p->seq = (aas *)Malloc(chars*sizeof(aas));
538}
539
540
541void reallocchars(void) 
542{ /* reallocates variables that are dependand on the number of chars
543   * do we need to reallocate the garbage list too? */
544  long i;
545  node *p;
546
547  if (usertree)
548    for (i = 0; i < maxuser; i++) {
549      free(fsteps[i]);
550      fsteps[i] = (long *)Malloc(chars*sizeof(long));
551    }
552 
553  for (i = 0; i < nonodes; i++) {
554    reallocnode(treenode[i]); 
555    if (i >= spp) {
556      p=treenode[i]->next;
557      while (p != treenode[i])  {
558        reallocnode(p); 
559        p = p->next;
560      }
561    }
562  }
563
564  free(weight);
565  free(threshwt);
566  free(temp->numsteps);
567  free(temp->siteset);
568  free(temp->seq);
569  free(temp1->numsteps);
570  free(temp1->siteset); 
571  free(temp1->seq);
572
573  weight = (steptr)Malloc(chars*sizeof(long));
574  threshwt = (steptr)Malloc(chars*sizeof(long));
575  temp->numsteps = (steptr)Malloc(chars*sizeof(long));
576  temp->siteset = (seqptr)Malloc(chars*sizeof(sitearray));
577  temp->seq = (aas *)Malloc(chars*sizeof(aas));
578  temp1->numsteps = (steptr)Malloc(chars*sizeof(long));
579  temp1->siteset = (seqptr)Malloc(chars*sizeof(sitearray));
580  temp1->seq = (aas *)Malloc(chars*sizeof(aas));
581}
582
583
584void allocrest()
585{ /* allocate remaining global arrays and variables dynamically */
586  long i;
587
588  if (usertree) {
589    fsteps = (long **)Malloc(maxuser*sizeof(long *));
590    for (i = 0; i < maxuser; i++)
591      fsteps[i] = (long *)Malloc(chars*sizeof(long));
592  }
593  bestrees = (bestelm *)Malloc(maxtrees*sizeof(bestelm));
594  for (i = 1; i <= maxtrees; i++)
595    bestrees[i - 1].btree = (long *)Malloc(spp*sizeof(long));
596  nayme = (naym *)Malloc(spp*sizeof(naym));
597  enterorder = (long *)Malloc(spp*sizeof(long));
598  place = (long *)Malloc(nonodes*sizeof(long));
599  weight = (steptr)Malloc(chars*sizeof(long));
600  threshwt = (steptr)Malloc(chars*sizeof(long));
601  temp = (node *)Malloc(sizeof(node));
602  temp->numsteps = (steptr)Malloc(chars*sizeof(long));
603  temp->siteset = (seqptr)Malloc(chars*sizeof(sitearray));
604  temp->seq = (aas *)Malloc(chars*sizeof(aas));
605  temp1 = (node *)Malloc(sizeof(node));
606  temp1->numsteps = (steptr)Malloc(chars*sizeof(long));
607  temp1->siteset = (seqptr)Malloc(chars*sizeof(sitearray));
608  temp1->seq = (aas *)Malloc(chars*sizeof(aas));
609}  /* allocrest */
610
611
612void doinit()
613{
614  /* initializes variables */
615
616  inputnumbers(&spp, &chars, &nonodes, 1);
617  getoptions();
618  if (printdata)
619    fprintf(outfile, "%2ld species, %3ld  sites\n\n", spp, chars);
620  protalloctree();
621  allocrest();
622}  /* doinit*/
623
624void protinputdata()
625{
626  /* input the names and sequences for each species */
627  long i, j, k, l, aasread, aasnew = 0;
628  Char charstate;
629  boolean allread, done;
630  aas aa;   /* temporary amino acid for input */
631
632  if (printdata)
633    headings(chars, "Sequences", "---------");
634  aasread = 0;
635  allread = false;
636  while (!(allread)) {
637    allread = true;
638    if (eoln(infile)) {
639      fscanf(infile, "%*[^\n]");
640      gettc(infile);
641    }
642    i = 1;
643    while (i <= spp) {
644      if ((interleaved && aasread == 0) || !interleaved)
645        initname(i - 1);
646      j = interleaved ? aasread : 0;
647      done = false;
648      while (!done && !eoff(infile)) {
649        if (interleaved)
650          done = true;
651        while (j < chars && !(eoln(infile) || eoff(infile))) {
652          charstate = gettc(infile);
653          if (charstate == ' ' || (charstate >= '0' && charstate <= '9'))
654            continue;
655          uppercase(&charstate);
656          if ((!isalpha(charstate) && charstate != '?' &&
657               charstate != '-' && charstate != '*') || charstate == 'J' ||
658              charstate == 'O' || charstate == 'U') {
659            printf("WARNING -- BAD AMINO ACID:%c",charstate);
660            printf(" AT POSITION%5ld OF SPECIES %3ld\n",j,i);
661            exxit(-1);
662          }
663          j++;
664          aa = (charstate == 'A') ?  ala :
665               (charstate == 'B') ?  asx :
666               (charstate == 'C') ?  cys :
667               (charstate == 'D') ?  asp :
668               (charstate == 'E') ?  glu :
669               (charstate == 'F') ?  phe :
670               (charstate == 'G') ?  gly : aa;
671          aa = (charstate == 'H') ?  his :
672               (charstate == 'I') ? ileu :
673               (charstate == 'K') ?  lys :
674               (charstate == 'L') ?  leu :
675               (charstate == 'M') ?  met :
676               (charstate == 'N') ?  asn :
677               (charstate == 'P') ?  pro :
678               (charstate == 'Q') ?  gln :
679               (charstate == 'R') ?  arg : aa;
680          aa = (charstate == 'S') ?  ser :
681               (charstate == 'T') ?  thr :
682               (charstate == 'V') ?  val :
683               (charstate == 'W') ?  trp :
684               (charstate == 'X') ?  unk :
685               (charstate == 'Y') ?  tyr :
686               (charstate == 'Z') ?  glx :
687               (charstate == '*') ? stop :
688               (charstate == '?') ? quest:
689               (charstate == '-') ? del  :  aa;
690
691          treenode[i - 1]->seq[j - 1] = aa;
692          memcpy(treenode[i - 1]->siteset[j - 1],
693                 translate[(long)aa - (long)ala], sizeof(sitearray));
694        }
695        if (interleaved)
696          continue;
697        if (j < chars) 
698          scan_eoln(infile);
699        else if (j == chars)
700          done = true;
701      }
702      if (interleaved && i == 1)
703        aasnew = j;
704      scan_eoln(infile);
705      if ((interleaved && j != aasnew) || ((!interleaved) && j != chars)){
706        printf("ERROR: SEQUENCES OUT OF ALIGNMENT\n");
707        exxit(-1);}
708      i++;
709    }
710    if (interleaved) {
711      aasread = aasnew;
712      allread = (aasread == chars);
713    } else
714      allread = (i > spp);
715  }
716  if (printdata) {
717    for (i = 1; i <= ((chars - 1) / 60 + 1); i++) {
718      for (j = 1; j <= (spp); j++) {
719        for (k = 0; k < nmlngth; k++)
720          putc(nayme[j - 1][k], outfile);
721        fprintf(outfile, "   ");
722        l = i * 60;
723        if (l > chars)
724          l = chars;
725        for (k = (i - 1) * 60 + 1; k <= l; k++) {
726          if (j > 1 && treenode[j - 1]->seq[k - 1] == treenode[0]->seq[k - 1])
727            charstate = '.';
728          else {
729            tmpa = treenode[j-1]->seq[k-1];
730              charstate =  (tmpa == ala) ? 'A' :
731                           (tmpa == asx) ? 'B' :
732                           (tmpa == cys) ? 'C' :
733                           (tmpa == asp) ? 'D' :
734                           (tmpa == glu) ? 'E' :
735                           (tmpa == phe) ? 'F' :
736                           (tmpa == gly) ? 'G' :
737                           (tmpa == his) ? 'H' :
738                           (tmpa ==ileu) ? 'I' :
739                           (tmpa == lys) ? 'K' :
740                           (tmpa == leu) ? 'L' : charstate;
741              charstate =  (tmpa == met) ? 'M' :
742                           (tmpa == asn) ? 'N' :
743                           (tmpa == pro) ? 'P' :
744                           (tmpa == gln) ? 'Q' :
745                           (tmpa == arg) ? 'R' :
746                           (tmpa == ser) ? 'S' :
747                           (tmpa ==ser1) ? 'S' :
748                           (tmpa ==ser2) ? 'S' : charstate;
749              charstate =  (tmpa == thr) ? 'T' :
750                           (tmpa == val) ? 'V' :
751                           (tmpa == trp) ? 'W' :
752                           (tmpa == unk) ? 'X' :
753                           (tmpa == tyr) ? 'Y' :
754                           (tmpa == glx) ? 'Z' :
755                           (tmpa == del) ? '-' :
756                           (tmpa ==stop) ? '*' :
757                           (tmpa==quest) ? '?' : charstate;
758        }
759          putc(charstate, outfile);
760          if (k % 10 == 0 && k % 60 != 0)
761            putc(' ', outfile);
762        }
763        putc('\n', outfile);
764      }
765      putc('\n', outfile);
766    }
767    putc('\n', outfile);
768  }
769  putc('\n', outfile);
770}  /* protinputdata */
771
772
773void protmakevalues()
774{
775  /* set up fractional likelihoods at tips */
776  long i, j;
777  node *p;
778
779  for (i = 1; i <= nonodes; i++) {
780    treenode[i - 1]->back = NULL;
781    treenode[i - 1]->tip = (i <= spp);
782    treenode[i - 1]->index = i;
783    for (j = 0; j < (chars); j++)
784      treenode[i - 1]->numsteps[j] = 0;
785    if (i > spp) {
786      p = treenode[i - 1]->next;
787      while (p != treenode[i - 1]) {
788        p->back = NULL;
789        p->tip = false;
790        p->index = i;
791        for (j = 0; j < (chars); j++)
792          p->numsteps[j] = 0;
793        p = p->next;
794      }
795    }
796  }
797}  /* protmakevalues */
798
799
800void doinput()
801{
802  /* reads the input data */
803  long i;
804
805  if (justwts) {
806    if (firstset)
807      protinputdata();
808    for (i = 0; i < chars; i++)
809      weight[i] = 1;
810    inputweights(chars, weight, &weights);
811    if (justwts) {
812      fprintf(outfile, "\n\nWeights set # %ld:\n\n", ith);
813      if (progress)
814        printf("\nWeights set # %ld:\n\n", ith);
815    }
816    if (printdata)
817      printweights(outfile, 0, chars, weight, "Sites");
818  } else {
819    if (!firstset){
820      samenumsp(&chars, ith);
821      reallocchars();
822    }
823    for (i = 0; i < chars; i++)
824      weight[i] = 1;
825    if (weights) {
826      inputweights(chars, weight, &weights);
827    }
828    if (weights)
829      printweights(outfile, 0, chars, weight, "Sites");
830    protinputdata();
831  }
832  if(!thresh)
833    threshold = spp * 3.0;
834  for(i = 0 ; i < (chars) ; i++){
835    weight[i]*=10;
836    threshwt[i] = (long)(threshold * weight[i] + 0.5);     
837  }
838
839  protmakevalues();
840}  /* doinput */
841
842
843void protfillin(node *p, node *left, node *rt)
844{
845  /* sets up for each node in the tree the aa set for site m
846     at that point and counts the changes.  The program
847     spends much of its time in this function */
848  boolean counted;
849  aas aa;
850  long s = 0;
851  sitearray ls, rs, qs;
852  long i, m, n;
853
854  for (m = 0; m < chars; m++) {
855    if (left != NULL)
856      memcpy(ls, left->siteset[m], sizeof(sitearray));
857    if (rt != NULL)
858      memcpy(rs, rt->siteset[m], sizeof(sitearray));
859    if (left == NULL) {
860      n = rt->numsteps[m];
861      memcpy(qs, rs, sizeof(sitearray));
862    }
863    else if (rt == NULL) {
864      n = left->numsteps[m];
865      memcpy(qs, ls, sizeof(sitearray));
866    }
867    else {
868      n = left->numsteps[m] + rt->numsteps[m];
869      if (ls[0] == rs[0]) {
870        qs[0] = ls[0];
871        qs[1] = ls[1];
872        qs[2] = ls[2];
873      }
874      else {
875        counted = false;
876        for (i = 0; (!counted) && (i <= 3); i++) {
877          switch (i) {
878 
879            case 0:
880              s = ls[0] & rs[0];
881              break;
882
883            case 1:
884              s = (ls[0] & rs[1]) | (ls[1] & rs[0]);
885              break;
886
887            case 2:
888              s = (ls[0] & rs[2]) | (ls[1] & rs[1]) | (ls[2] & rs[0]);
889              break;
890
891            case 3:
892              s = ls[0] | (ls[1] & rs[2]) | (ls[2] & rs[1]) | rs[0];
893              break;
894
895          }
896          if (s != 0) {
897            qs[0] = s;
898            counted = true;
899          } else
900              n += weight[m];
901        }
902        qs[1] = 0;
903        qs[2] = 0;
904        for (i = 0; i <= 1; i++) {
905          for (aa = ala; (long)aa <= (long)stop; aa = (aas)((long)aa + 1)) {
906            if (((1L << ((long)aa)) & qs[i]) != 0)
907              qs[i+1] |= translate[(long)aa - (long)ala][1];
908          }
909        }
910      }
911    }
912    p->numsteps[m] = n;
913    memcpy(p->siteset[m], qs, sizeof(sitearray));
914  }
915}  /* protfillin */
916
917
918void protpreorder(node *p)
919{
920  /* recompute number of steps in preorder taking both ancestoral and
921     descendent steps into account */
922  if (p != NULL && !p->tip) {
923    protfillin (p->next, p->next->next->back, p->back);
924    protfillin (p->next->next, p->back, p->next->back);
925    protpreorder (p->next->back);
926    protpreorder (p->next->next->back);
927  }
928} /* protpreorder */
929
930
931void protadd(node *below, node *newtip, node *newfork)
932{
933  /* inserts the nodes newfork and its left descendant, newtip,
934     to the tree.  below becomes newfork's right descendant */
935
936  if (below != treenode[below->index - 1])
937    below = treenode[below->index - 1];
938  if (below->back != NULL)
939    below->back->back = newfork;
940  newfork->back = below->back;
941  below->back = newfork->next->next;
942  newfork->next->next->back = below;
943  newfork->next->back = newtip;
944  newtip->back = newfork->next;
945  if (root == below)
946    root = newfork;
947  root->back = NULL;
948
949  if (recompute) {
950    protfillin (newfork, newfork->next->back, newfork->next->next->back);
951    protpreorder(newfork);
952    if (newfork != root)
953      protpreorder(newfork->back);
954  }
955}  /* protadd */
956
957
958void protre_move(node **item, node **fork)
959{
960  /* removes nodes item and its ancestor, fork, from the tree.
961     the new descendant of fork's ancestor is made to be
962     fork's second descendant (other than item).  Also
963     returns pointers to the deleted nodes, item and fork */
964  node *p, *q, *other;
965
966  if ((*item)->back == NULL) {
967    *fork = NULL;
968    return;
969  }
970  *fork = treenode[(*item)->back->index - 1];
971  if ((*item) == (*fork)->next->back)
972    other = (*fork)->next->next->back;
973  else other = (*fork)->next->back;
974  if (root == *fork)
975    root = other;
976  p = (*item)->back->next->back;
977  q = (*item)->back->next->next->back;
978  if (p != NULL) p->back = q;
979  if (q != NULL) q->back = p;
980  (*fork)->back = NULL;
981  p = (*fork)->next;
982  do {
983    p->back = NULL;
984    p = p->next;
985  } while (p != (*fork));
986  (*item)->back = NULL;
987  if (recompute) {
988    protpreorder(other);
989    if (other != root) protpreorder(other->back);
990  }
991}  /* protre_move */
992
993
994void evaluate(node *r)
995{
996  /* determines the number of steps needed for a tree. this is the
997     minimum number of steps needed to evolve sequences on this tree */
998  long i, steps, term;
999  double sum;
1000
1001  sum = 0.0;
1002  for (i = 0; i < (chars); i++) {
1003    steps = r->numsteps[i];
1004    if (steps <= threshwt[i])
1005      term = steps;
1006    else
1007      term = threshwt[i];
1008    sum += term;
1009    if (usertree && which <= maxuser)
1010      fsteps[which - 1][i] = term;
1011  }
1012  if (usertree && which <= maxuser) {
1013    nsteps[which - 1] = sum;
1014    if (which == 1) {
1015      minwhich = 1;
1016      minsteps = sum;
1017    } else if (sum < minsteps) {
1018      minwhich = which;
1019      minsteps = sum;
1020    }
1021  }
1022  like = -sum;
1023}  /* evaluate */
1024
1025
1026void protpostorder(node *p)
1027{
1028  /* traverses a binary tree, calling PROCEDURE fillin at a
1029     node's descendants before calling fillin at the node */
1030  if (p->tip)
1031    return;
1032  protpostorder(p->next->back);
1033  protpostorder(p->next->next->back);
1034  protfillin(p, p->next->back, p->next->next->back);
1035}  /* protpostorder */
1036
1037
1038void protreroot(node *outgroup)
1039{
1040  /* reorients tree, putting outgroup in desired position. */
1041  node *p, *q;
1042
1043  if (outgroup->back->index == root->index)
1044    return;
1045  p = root->next;
1046  q = root->next->next;
1047  p->back->back = q->back;
1048  q->back->back = p->back;
1049  p->back = outgroup;
1050  q->back = outgroup->back;
1051  outgroup->back->back = q;
1052  outgroup->back = p;
1053}  /* protreroot */
1054
1055
1056void protsavetraverse(node *p, long *pos, boolean *found)
1057{
1058  /* sets BOOLEANs that indicate which way is down */
1059  p->bottom = true;
1060  if (p->tip)
1061    return;
1062  p->next->bottom = false;
1063  protsavetraverse(p->next->back, pos,found);
1064  p->next->next->bottom = false;
1065  protsavetraverse(p->next->next->back, pos,found);
1066}  /* protsavetraverse */
1067
1068
1069void protsavetree(long *pos, boolean *found)
1070{
1071  /* record in place where each species has to be
1072     added to reconstruct this tree */
1073  long i, j;
1074  node *p;
1075  boolean done;
1076
1077  protreroot(treenode[outgrno - 1]);
1078  protsavetraverse(root, pos,found);
1079  for (i = 0; i < (nonodes); i++)
1080    place[i] = 0;
1081  place[root->index - 1] = 1;
1082  for (i = 1; i <= (spp); i++) {
1083    p = treenode[i - 1];
1084    while (place[p->index - 1] == 0) {
1085      place[p->index - 1] = i;
1086      while (!p->bottom)
1087        p = p->next;
1088      p = p->back;
1089    }
1090    if (i > 1) {
1091      place[i - 1] = place[p->index - 1];
1092      j = place[p->index - 1];
1093      done = false;
1094      while (!done) {
1095        place[p->index - 1] = spp + i - 1;
1096        while (!p->bottom)
1097          p = p->next;
1098        p = p->back;
1099        done = (p == NULL);
1100        if (!done)
1101          done = (place[p->index - 1] != j);
1102      }
1103    }
1104  }
1105}  /* protsavetree */
1106
1107
1108void tryadd(node *p, node **item, node **nufork)
1109{
1110  /* temporarily adds one fork and one tip to the tree.
1111     if the location where they are added yields greater
1112     "likelihood" than other locations tested up to that
1113     time, then keeps that location as there */
1114  long pos;
1115  boolean found;
1116  node *rute, *q;
1117
1118  if (p == root)
1119    protfillin(temp, *item, p);
1120  else {
1121    protfillin(temp1, *item, p);
1122    protfillin(temp, temp1, p->back);
1123  }
1124  evaluate(temp);
1125  if (lastrearr) {
1126    if (like < bestlike) {
1127      if ((*item) == (*nufork)->next->next->back) {
1128        q = (*nufork)->next;
1129        (*nufork)->next = (*nufork)->next->next;
1130        (*nufork)->next->next = q;
1131        q->next = (*nufork);
1132      }
1133    }
1134    else if (like >= bstlike2) {
1135      recompute = false;
1136      protadd(p, (*item), (*nufork));
1137      rute = root->next->back;
1138      protsavetree(&pos,&found);
1139      protreroot(rute);
1140      if (like > bstlike2) {
1141        bestlike = bstlike2 = like;
1142        pos = 1;
1143        nextree = 1;
1144        addtree(pos, &nextree, dummy, place, bestrees);
1145      } else {
1146        pos = 0;
1147        findtree(&found, &pos, nextree, place, bestrees);
1148        if (!found) {
1149          if (nextree <= maxtrees)
1150            addtree(pos, &nextree, dummy, place, bestrees);
1151        }
1152      }
1153      protre_move (item, nufork);
1154      recompute = true;
1155    }
1156  }
1157  if (like > bestyet) {
1158    bestyet = like;
1159    there = p;
1160  }
1161}  /* tryadd */
1162
1163
1164void addpreorder(node *p, node *item, node *nufork)
1165{
1166  /* traverses a binary tree, calling PROCEDURE tryadd
1167     at a node before calling tryadd at its descendants */
1168
1169  if (p == NULL)
1170    return;
1171  tryadd(p, &item,&nufork);
1172  if (!p->tip) {
1173    addpreorder(p->next->back, item, nufork);
1174    addpreorder(p->next->next->back, item, nufork);
1175  }
1176}  /* addpreorder */
1177
1178
1179void tryrearr(node *p, boolean *success)
1180{
1181  /* evaluates one rearrangement of the tree.
1182     if the new tree has greater "likelihood" than the old
1183     one sets success := TRUE and keeps the new tree.
1184     otherwise, restores the old tree */
1185  node *frombelow, *whereto, *forknode, *q;
1186  double oldlike;
1187
1188  if (p->back == NULL)
1189    return;
1190  forknode = treenode[p->back->index - 1];
1191  if (forknode->back == NULL)
1192    return;
1193  oldlike = bestyet;
1194  if (p->back->next->next == forknode)
1195    frombelow = forknode->next->next->back;
1196  else
1197    frombelow = forknode->next->back;
1198  whereto = treenode[forknode->back->index - 1];
1199  if (whereto->next->back == forknode)
1200    q = whereto->next->next->back;
1201  else
1202    q = whereto->next->back;
1203  protfillin(temp1, frombelow, q);
1204  protfillin(temp, temp1, p);
1205  protfillin(temp1, temp, whereto->back);
1206  evaluate(temp1);
1207  if (like <= oldlike) {
1208    if (p == forknode->next->next->back) {
1209      q = forknode->next;
1210      forknode->next = forknode->next->next;
1211      forknode->next->next = q;
1212      q->next = forknode;
1213    }
1214  }
1215  else {
1216    recompute = false;
1217    protre_move(&p, &forknode);
1218    protfillin(whereto, whereto->next->back, whereto->next->next->back);
1219    recompute = true;
1220    protadd(whereto, p, forknode);
1221    *success = true;
1222    bestyet = like;
1223  }
1224}  /* tryrearr */
1225
1226
1227void repreorder(node *p, boolean *success)
1228{
1229  /* traverses a binary tree, calling PROCEDURE tryrearr
1230     at a node before calling tryrearr at its descendants */
1231  if (p == NULL)
1232    return;
1233  tryrearr(p,success);
1234  if (!p->tip) {
1235    repreorder(p->next->back,success);
1236    repreorder(p->next->next->back,success);
1237  }
1238}  /* repreorder */
1239
1240
1241void rearrange(node **r)
1242{
1243  /* traverses the tree (preorder), finding any local
1244     rearrangement which decreases the number of steps.
1245     if traversal succeeds in increasing the tree's
1246     "likelihood", PROCEDURE rearrange runs traversal again */
1247  boolean success = true;
1248  while (success) {
1249    success = false;
1250    repreorder(*r, &success);
1251  }
1252}  /* rearrange */
1253
1254
1255void protgetch(Char *c)
1256{
1257  /* get next nonblank character */
1258  do {
1259    if (eoln(intree))
1260      scan_eoln(intree);
1261    *c = gettc(intree);
1262    if (*c == '\n' || *c == '\t')
1263      *c = ' ';
1264  } while (!(*c != ' ' || eoff(intree)));
1265}  /* protgetch */
1266
1267
1268void protaddelement(node **p,long *nextnode,long *lparens,boolean *names)
1269{
1270  /* recursive procedure adds nodes to user-defined tree */
1271  node *q;
1272  long i, n;
1273  boolean found;
1274  Char str[nmlngth];
1275
1276  protgetch(&ch);
1277 
1278  if (ch == '(' ) {
1279    if ((*lparens) >= spp - 1) {
1280      printf("\nERROR IN USER TREE: TOO MANY LEFT PARENTHESES\n");
1281      exxit(-1);
1282    }
1283    (*nextnode)++;
1284    (*lparens)++;
1285    q = treenode[(*nextnode) - 1];
1286    protaddelement(&q->next->back, nextnode,lparens,names);
1287    q->next->back->back = q->next;
1288    findch(',', &ch, which);
1289    protaddelement(&q->next->next->back, nextnode,lparens,names);
1290    q->next->next->back->back = q->next->next;
1291    findch(')', &ch, which);
1292    *p = q;
1293    return;
1294  }
1295  for (i = 0; i < nmlngth; i++)
1296    str[i] = ' ';
1297  n = 1;
1298  do {
1299    if (ch == '_')
1300      ch = ' ';
1301    str[n - 1] = ch;
1302    if (eoln(intree))
1303      scan_eoln(intree);
1304    ch = gettc(intree);
1305    n++;
1306  } while (ch != ',' && ch != ')' && ch != ':' && n <= nmlngth);
1307  n = 1;
1308  do {
1309    found = true;
1310    for (i = 0; i < nmlngth; i++)
1311      found = (found && ((str[i] == nayme[n - 1][i]) ||
1312                         ((nayme[n - 1][i] == '_') && (str[i] == ' '))));
1313    if (found) {
1314      if (names[n - 1] == false) {
1315        *p = treenode[n - 1];
1316        names[n - 1] = true;
1317      } else {
1318        printf("\nERROR IN USER TREE: DUPLICATE NAME FOUND -- ");
1319        for (i = 0; i < nmlngth; i++)
1320          putchar(nayme[n - 1][i]);
1321        putchar('\n');
1322        exxit(-1);
1323      }
1324    } else
1325      n++;
1326  } while (!(n > spp || found));
1327  if (n <= spp)
1328    return;
1329  printf("CANNOT FIND SPECIES: ");
1330  for (i = 0; i < nmlngth; i++)
1331    putchar(str[i]);
1332  putchar('\n');
1333}  /* protaddelement */
1334
1335
1336void prottreeread()
1337{
1338  /* read in user-defined tree and set it up */
1339  long nextnode, lparens, i;
1340
1341  root = treenode[spp];
1342  nextnode = spp;
1343  root->back = NULL;
1344  names = (boolean *)Malloc(spp*sizeof(boolean));
1345  for (i = 0; i < (spp); i++)
1346    names[i] = false;
1347  lparens = 0;
1348  protaddelement(&root, &nextnode,&lparens,names);
1349  if (ch == '[') {
1350    do
1351      ch = gettc(intree);
1352    while (ch != ']');
1353    ch = gettc(intree);
1354  }
1355  findch(';', &ch, which);
1356  if (progress)
1357    printf("\n\n");
1358  fscanf(intree, "%*[^\n]");
1359  gettc(intree);
1360  free(names);
1361}  /* prottreeread */
1362
1363
1364void protancestset(long *a, long *b, long *c, long *d, long *k)
1365{
1366  /* sets up the aa set array. */
1367  aas aa;
1368  long s, sa, sb;
1369  long i, j, m, n;
1370  boolean counted;
1371
1372  counted = false;
1373  *k = 0;
1374  for (i = 0; i <= 5; i++) {
1375    if (*k < 3) {
1376      s = 0;
1377      if (i > 3)
1378        n = i - 3;
1379      else
1380        n = 0;
1381      for (j = n; j <= (i - n); j++) {
1382        if (j < 3)
1383          sa = a[j];
1384        else
1385          sa = fullset;
1386        for (m = n; m <= (i - j - n); m++) {
1387          if (m < 3)
1388            sb = sa & b[m];
1389          else
1390            sb = sa;
1391          if (i - j - m < 3)
1392            sb &= c[i - j - m];
1393          s |= sb;
1394        }
1395      }
1396      if (counted || s != 0) {
1397        d[*k] = s;
1398        (*k)++;
1399        counted = true;
1400      }
1401    }
1402  }
1403  for (i = 0; i <= 1; i++) {
1404    for (aa = ala; (long)aa <= (long)stop; aa = (aas)((long)aa + 1)) {
1405      if (((1L << ((long)aa)) & d[i]) != 0) {
1406        for (j = i + 1; j <= 2; j++)
1407          d[j] |= translate[(long)aa - (long)ala][j - i];
1408      }
1409    }
1410  }
1411}  /* protancestset */
1412
1413
1414void prothyprint(long b1, long b2, boolean *bottom, node *r,
1415                        boolean *nonzero, boolean *maybe)
1416{
1417  /* print out states in sites b1 through b2 at node */
1418  long i;
1419  boolean dot;
1420  Char ch = 0;
1421  aas aa;
1422
1423  if (*bottom) {
1424    if (!outgropt)
1425      fprintf(outfile, "      ");
1426    else
1427      fprintf(outfile, "root  ");
1428  } else
1429    fprintf(outfile, "%3ld   ", r->back->index - spp);
1430  if (r->tip) {
1431    for (i = 0; i < nmlngth; i++)
1432      putc(nayme[r->index - 1][i], outfile);
1433  } else
1434    fprintf(outfile, "%4ld      ", r->index - spp);
1435  if (*bottom)
1436    fprintf(outfile, "          ");
1437  else if (*nonzero)
1438    fprintf(outfile, "   yes    ");
1439  else if (*maybe)
1440    fprintf(outfile, "  maybe   ");
1441  else
1442    fprintf(outfile, "   no     ");
1443  for (i = b1 - 1; i < b2; i++) {
1444    aa = r->seq[i];
1445    switch (aa) {
1446
1447    case ala:
1448      ch = 'A';
1449      break;
1450
1451    case asx:
1452      ch = 'B';
1453      break;
1454
1455    case cys:
1456      ch = 'C';
1457      break;
1458
1459    case asp:
1460      ch = 'D';
1461      break;
1462
1463    case glu:
1464      ch = 'E';
1465      break;
1466
1467    case phe:
1468      ch = 'F';
1469      break;
1470
1471    case gly:
1472      ch = 'G';
1473      break;
1474
1475    case his:
1476      ch = 'H';
1477      break;
1478
1479    case ileu:
1480      ch = 'I';
1481      break;
1482
1483    case lys:
1484      ch = 'K';
1485      break;
1486
1487    case leu:
1488      ch = 'L';
1489      break;
1490
1491    case met:
1492      ch = 'M';
1493      break;
1494
1495    case asn:
1496      ch = 'N';
1497      break;
1498
1499    case pro:
1500      ch = 'P';
1501      break;
1502
1503    case gln:
1504      ch = 'Q';
1505      break;
1506
1507    case arg:
1508      ch = 'R';
1509      break;
1510
1511    case ser:
1512      ch = 'S';
1513      break;
1514
1515    case ser1:
1516      ch = 'S';
1517      break;
1518
1519    case ser2:
1520      ch = 'S';
1521      break;
1522
1523    case thr:
1524      ch = 'T';
1525      break;
1526
1527    case trp:
1528      ch = 'W';
1529      break;
1530
1531    case tyr:
1532      ch = 'Y';
1533      break;
1534
1535    case val:
1536      ch = 'V';
1537      break;
1538
1539    case glx:
1540      ch = 'Z';
1541      break;
1542
1543    case del:
1544      ch = '-';
1545      break;
1546
1547    case stop:
1548      ch = '*';
1549      break;
1550
1551    case unk:
1552      ch = 'X';
1553      break;
1554
1555    case quest:
1556      ch = '?';
1557      break;
1558    }
1559    if (!(*bottom))
1560      dot = (r->siteset[i] [0] == treenode[r->back->index - 1]->siteset[i][0]
1561             || ((r->siteset[i][0] &
1562                  (~((1L << ((long)ser1)) | (1L << ((long)ser2)) |
1563                                         (1L << ((long)ser))))) == 0 &&
1564                (treenode[r->back->index - 1]->siteset[i] [0] &
1565                  (~((1L << ((long)ser1)) | (1L << ((long)ser2)) |
1566                                         (1L << ((long)ser))))) == 0));
1567    else
1568      dot = false;
1569    if (dot)
1570      putc('.', outfile);
1571    else
1572      putc(ch, outfile);
1573    if ((i + 1) % 10 == 0)
1574      putc(' ', outfile);
1575  }
1576  putc('\n', outfile);
1577}  /* prothyprint */
1578
1579
1580void prothyptrav(node *r, sitearray *hypset, long b1, long b2, long *k,
1581                        boolean *bottom, sitearray nothing)
1582{
1583  boolean maybe, nonzero;
1584  long i;
1585  aas aa;
1586  long anc = 0, hset;
1587  gseq *ancset, *temparray;
1588
1589  protgnu(&ancset);
1590  protgnu(&temparray);
1591  maybe = false;
1592  nonzero = false;
1593  for (i = b1 - 1; i < b2; i++) {
1594    if (!r->tip) {
1595      protancestset(hypset[i], r->next->back->siteset[i],
1596                r->next->next->back->siteset[i], temparray->seq[i], k);
1597      memcpy(r->siteset[i], temparray->seq[i], sizeof(sitearray));
1598    }
1599    if (!(*bottom))
1600      anc = treenode[r->back->index - 1]->siteset[i][0];
1601    if (!r->tip) {
1602      hset = r->siteset[i][0];
1603      r->seq[i] = quest;
1604      for (aa = ala; (long)aa <= (long)stop; aa = (aas)((long)aa + 1)) {
1605        if (hset == 1L << ((long)aa))
1606          r->seq[i] = aa;
1607      }
1608      if (hset == ((1L << ((long)asn)) | (1L << ((long)asp))))
1609        r->seq[i] = asx;
1610      if (hset == ((1L << ((long)gln)) | (1L << ((long)gly))))
1611        r->seq[i] = glx;
1612      if (hset == ((1L << ((long)ser1)) | (1L << ((long)ser2))))
1613        r->seq[i] = ser;
1614      if (hset == fullset)
1615        r->seq[i] = unk;
1616    }
1617    nonzero = (nonzero || (r->siteset[i][0] & anc) == 0);
1618    maybe = (maybe || r->siteset[i][0] != anc);
1619  }
1620  prothyprint(b1, b2,bottom,r,&nonzero,&maybe);
1621  *bottom = false;
1622  if (!r->tip) {
1623    memcpy(temparray->seq, r->next->back->siteset, chars*sizeof(sitearray));
1624    for (i = b1 - 1; i < b2; i++)
1625      protancestset(hypset[i], r->next->next->back->siteset[i], nothing,
1626                ancset->seq[i], k);
1627    prothyptrav(r->next->back, ancset->seq, b1, b2,k,bottom,nothing );
1628    for (i = b1 - 1; i < b2; i++)
1629      protancestset(hypset[i], temparray->seq[i], nothing, ancset->seq[i],k);
1630    prothyptrav(r->next->next->back, ancset->seq, b1, b2, k,bottom,nothing);
1631  }
1632  protchuck(temparray);
1633  protchuck(ancset);
1634}  /* prothyptrav */
1635
1636
1637void prothypstates(long *k)
1638{
1639  /* fill in and describe states at interior nodes */
1640  boolean bottom;
1641  sitearray nothing;
1642  long i, n;
1643  seqptr hypset;
1644
1645  fprintf(outfile, "\nFrom    To     Any Steps?    State at upper node\n");
1646  fprintf(outfile, "                             ");
1647  fprintf(outfile, "( . means same as in the node below it on tree)\n\n");
1648  memcpy(nothing, translate[(long)quest - (long)ala], sizeof(sitearray));
1649  hypset = (seqptr)Malloc(chars*sizeof(sitearray));
1650  for (i = 0; i < (chars); i++)
1651    memcpy(hypset[i], nothing, sizeof(sitearray));
1652  bottom = true;
1653  for (i = 1; i <= ((chars - 1) / 40 + 1); i++) {
1654    putc('\n', outfile);
1655    n = i * 40;
1656    if (n > chars)
1657      n = chars;
1658    bottom = true;
1659    prothyptrav(root, hypset, i * 40 - 39, n, k,&bottom,nothing);
1660  }
1661  free(hypset);
1662}  /* prothypstates */
1663
1664
1665void describe()
1666{
1667  /* prints ancestors, steps and table of numbers of steps in
1668     each site */
1669  long i,j,k;
1670
1671  if (treeprint)
1672    fprintf(outfile, "\nrequires a total of %10.3f\n", like / -10);
1673  if (stepbox) {
1674    putc('\n', outfile);
1675    if (weights)
1676      fprintf(outfile, "weighted ");
1677    fprintf(outfile, "steps in each position:\n");
1678    fprintf(outfile, "      ");
1679    for (i = 0; i <= 9; i++)
1680      fprintf(outfile, "%4ld", i);
1681    fprintf(outfile, "\n     *-----------------------------------------\n");
1682    for (i = 0; i <= (chars / 10); i++) {
1683      fprintf(outfile, "%5ld", i * 10);
1684      putc('!', outfile);
1685      for (j = 0; j <= 9; j++) {
1686        k = i * 10 + j;
1687        if (k == 0 || k > chars)
1688          fprintf(outfile, "    ");
1689        else
1690          fprintf(outfile, "%4ld", root->numsteps[k - 1] / 10);
1691      }
1692      putc('\n', outfile);
1693    }
1694  }
1695  if (ancseq) {
1696    prothypstates(&k);
1697    putc('\n', outfile);
1698  }
1699  putc('\n', outfile);
1700  if (trout) {
1701    col = 0;
1702    treeout(root, nextree, &col, root);
1703  }
1704}  /* describe */
1705
1706
1707void maketree()
1708{
1709  /* constructs a binary tree from the pointers in treenode.
1710     adds each node at location which yields highest "likelihood"
1711     then rearranges the tree for greatest "likelihood" */
1712  long i, j, numtrees;
1713  double gotlike;
1714  node *item, *nufork, *dummy;
1715
1716  if (!usertree) {
1717    for (i = 1; i <= (spp); i++)
1718      enterorder[i - 1] = i;
1719    if (jumble)
1720      randumize(seed, enterorder);
1721    root = treenode[enterorder[0] - 1];
1722    recompute = true;
1723    protadd(treenode[enterorder[0] - 1], treenode[enterorder[1] - 1],
1724        treenode[spp]);
1725    if (progress) {
1726      printf("\nAdding species:\n");
1727      writename(0, 2, enterorder);
1728    }
1729    lastrearr = false;
1730    for (i = 3; i <= (spp); i++) {
1731      bestyet = -30.0*spp*chars;
1732      there = root;
1733      item = treenode[enterorder[i - 1] - 1];
1734      nufork = treenode[spp + i - 2];
1735      addpreorder(root, item, nufork);
1736      protadd(there, item, nufork);
1737      like = bestyet;
1738      rearrange(&root);
1739      if (progress)
1740        writename(i - 1, 1, enterorder);
1741      lastrearr = (i == spp);
1742      if (lastrearr) {
1743        if (progress) {
1744          printf("\nDoing global rearrangements\n");
1745          printf("  !");
1746          for (j = 1; j <= nonodes; j++)
1747            putchar('-');
1748          printf("!\n");
1749        }
1750        bestlike = bestyet;
1751        if (jumb == 1) {
1752          bstlike2 = bestlike;
1753          nextree = 1;
1754        }
1755        do {
1756          if (progress)
1757            printf("   ");
1758          gotlike = bestlike;
1759          for (j = 0; j < (nonodes); j++) {
1760            bestyet = -30.0*spp*chars;
1761            item = treenode[j];
1762            if (item != root) {
1763              nufork = treenode[treenode[j]->back->index - 1];
1764              protre_move(&item, &nufork);
1765              there = root;
1766              addpreorder(root, item, nufork);
1767              protadd(there, item, nufork);
1768            }
1769            if (progress) {
1770              putchar('.');
1771              fflush(stdout);
1772            }
1773          }
1774          if (progress)
1775            putchar('\n');
1776        } while (bestlike > gotlike);
1777      }
1778    }
1779    if (progress)
1780      putchar('\n');
1781    for (i = spp - 1; i >= 1; i--)
1782      protre_move(&treenode[i], &dummy);
1783    if (jumb == njumble) {
1784      if (treeprint) {
1785        putc('\n', outfile);
1786        if (nextree == 2)
1787          fprintf(outfile, "One most parsimonious tree found:\n");
1788        else
1789          fprintf(outfile, "%6ld trees in all found\n", nextree - 1);
1790      }
1791      if (nextree > maxtrees + 1) {
1792        if (treeprint)
1793          fprintf(outfile, "here are the first%4ld of them\n", (long)maxtrees);
1794        nextree = maxtrees + 1;
1795      }
1796      if (treeprint)
1797        putc('\n', outfile);
1798      recompute = false;
1799      for (i = 0; i <= (nextree - 2); i++) {
1800        root = treenode[0];
1801        protadd(treenode[0], treenode[1], treenode[spp]);
1802        for (j = 3; j <= (spp); j++)
1803          protadd(treenode[bestrees[i].btree[j - 1] - 1], treenode[j - 1],
1804              treenode[spp + j - 2]);
1805        protreroot(treenode[outgrno - 1]);
1806        protpostorder(root);
1807        evaluate(root);
1808        printree(root, 1.0);
1809        describe();
1810        for (j = 1; j < (spp); j++)
1811          protre_move(&treenode[j], &dummy);
1812      }
1813    }
1814  } else {
1815    openfile(&intree,INTREE,"input tree file", "r",progname,intreename);
1816    numtrees = countsemic(&intree);
1817    if (treeprint) {
1818      fprintf(outfile, "User-defined tree");
1819      if (numtrees > 1)
1820        putc('s', outfile);
1821      fprintf(outfile, ":\n\n\n\n");
1822    }
1823    which = 1;
1824    while (which <= numtrees) {
1825      prottreeread();
1826      if (outgropt)
1827        protreroot(treenode[outgrno - 1]);
1828      protpostorder(root);
1829      evaluate(root);
1830      printree(root, 1.0);
1831      describe();
1832      which++;
1833    }
1834    FClose(intree);
1835    putc('\n', outfile);
1836    if (numtrees > 1 && chars > 1 )
1837      standev(chars, numtrees, minwhich, minsteps, nsteps, fsteps, seed);
1838  }
1839  if (jumb == njumble && progress) {
1840    printf("Output written to file \"%s\"\n\n", outfilename);
1841    if (trout)
1842      printf("Trees also written onto file \"%s\"\n\n", outtreename);
1843  }
1844}  /* maketree */
1845
1846
1847int main(int argc, Char *argv[])
1848{  /* Protein parsimony by uphill search */
1849#ifdef MAC
1850  argc = 1;         /* macsetup("Protpars","");                */
1851  argv[0] = "Protpars";
1852#endif
1853  init(argc,argv);
1854  progname = argv[0];
1855  openfile(&infile,INFILE,"input file", "r",argv[0],infilename);
1856  openfile(&outfile,OUTFILE,"output file", "w",argv[0],outfilename);
1857
1858  ibmpc = IBMCRT;
1859  ansi = ANSICRT;
1860  garbage = NULL;
1861  mulsets = false;
1862  msets = 1;
1863  firstset = true;
1864  code();
1865  setup();
1866  doinit();
1867  if (weights || justwts)
1868    openfile(&weightfile,WEIGHTFILE,"weights file","r",argv[0],weightfilename);
1869  if (trout)
1870    openfile(&outtree,OUTTREE,"output tree file", "w",argv[0],outtreename);
1871  for (ith = 1; ith <= msets; ith++) {
1872    doinput();
1873    if (ith == 1)
1874      firstset = false;
1875    if (msets > 1 && !justwts) {
1876      fprintf(outfile, "Data set # %ld:\n\n",ith);
1877      if (progress)
1878        printf("Data set # %ld:\n\n",ith);
1879    }
1880    for (jumb = 1; jumb <= njumble; jumb++)
1881      maketree();
1882  }
1883  FClose(infile);
1884  FClose(outfile);
1885  FClose(outtree);
1886#ifdef MAC
1887  fixmacfile(outfilename);
1888  fixmacfile(outtreename);
1889#endif
1890  return 0;
1891}  /* Protein parsimony by uphill search */
Note: See TracBrowser for help on using the repository browser.