source: tags/initial/GDE/PHYLIP/dnaml.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: 30.9 KB
Line 
1#include "phylip.h"
2
3/* version 3.56c. (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 maxcategs       9
9#define maxtrees        10   /* maximum number of user trees for test        */
10#define smoothings      7    /* number of passes through smoothing algorithm */
11#define iterations      9    /* number of iterates for each branch           */
12#define nmlngth         10   /* max. number of characters in species name    */
13
14#define epsilon         0.0001   /* used in getthree, makenewv */
15
16#define ibmpc0          false
17#define ansi0           true
18#define vt520           false
19#define down            2
20#define over            60
21#define point           "."
22
23
24typedef enum {  A, C, G, T} base;
25typedef double sitelike[(short)T - (short)A + 1];
26typedef sitelike *ratelike;
27typedef ratelike *phenotype;
28typedef Char **sequence;
29typedef double contribarr[maxcategs];
30typedef Char naym[nmlngth];
31typedef short longer[6];
32
33typedef struct node {
34  struct node *next, *back;
35  boolean tip, iter;
36  short number;
37  phenotype x;
38  naym nayme;
39  double v;
40  short xcoord, ycoord, ymin, ymax;
41} node;
42
43typedef struct tree {
44  node **nodep;
45  double likelihood;
46  node *start;
47} tree;
48
49typedef double *lf[maxtrees];
50
51typedef struct valrec {
52  double rat, ratxi, ratxv, zz, z1, y1, ww1, zz1, ww2, zz2, z1zz, z1yy, xiz1,
53         xiy1xv, ww1zz1, vv1zz1, ww2zz2, vv2zz2;
54} valrec;
55
56extern short categs,endsite,sites,numsp,numsp2,jumb,lengths,njumble,weightsum,
57            outgrno;
58extern double *probcat;
59extern double *rate;
60extern contribarr *contribution;
61extern short   *category,*weight,*alias,*ally,*location,*aliasweight;
62extern double xi,xv,ttratio,freqa,freqc,freqg,freqt,freqr,freqy,freqar,
63              freqcy,freqgr,freqty,lambda,fracchange;
64extern short   *enterorder;
65extern boolean auto_,usertree,global,progress,treeprint,outgropt,trout,
66               ctgry,jumble,lngths;
67extern lf l0gf;
68extern tree curtree,bestree,bestree2;
69extern FILE *infile, *outfile, *treefile;
70extern longer seed;
71
72boolean lngths;
73double *rate,*probcat;
74FILE *infile, *outfile, *treefile;
75short numsp, numsp1, numsp2, sites, endsite, weightsum, categs, inseed,
76            outgrno, datasets, ith, i, j, l, jumb, njumble=0;
77boolean  freqsfrom, global, jumble,  outgropt, weights,
78               trout, usertree, ctgry, auto_, ttr, printdata, progress,
79               treeprint, mulsets, firstset, interleaved, ibmpc, vt52, ansi;
80tree curtree, bestree, bestree2;
81double xi, xv, ttratio, ttratio0, freqa, freqc, freqg, freqt, freqr,
82              freqy, freqar, freqcy, freqgr, freqty, fracchange, sumrates,
83              lambda;
84longer seed;
85short *enterorder;
86sequence y;
87short *category, *weight, *alias, *ally, *location, *aliasweight;
88
89contribarr *contribution;
90lf l0gf;
91
92openfile(fp,filename,mode,application,perm)
93FILE **fp;
94char *filename;
95char *mode;
96char *application;
97char *perm;
98{
99  FILE *of;
100  char file[100];
101  strcpy(file,filename);
102  while (1){
103    of = fopen(file,mode);
104    if (of)
105      break;
106    else {
107      switch (*mode){
108      case 'r':
109        printf("%s:  can't read %s\n",application,file);
110        file[0] = '\0';
111        while (file[0] =='\0'){
112          printf("Please enter a new filename>");
113          gets(file);
114          }
115        break;
116      case 'w':
117        printf("%s: can't write %s\n",application,file);
118        file[0] = '\0';
119        while (file[0] =='\0'){
120          printf("Please enter a new filename>");
121          gets(file);
122          }
123        break;
124      }
125    }
126  }
127  *fp=of;
128  if (perm != NULL)
129    strcpy(perm,file);
130}
131
132
133
134
135void uppercase(ch)
136Char *ch;
137{
138  /* convert ch to upper case -- either ASCII or EBCDIC */
139   *ch = isupper(*ch) ? *ch : toupper(*ch);
140}  /* uppercase */
141
142Local Void getnums()
143{
144  /* input number of species, number of sites */
145  fprintf(outfile, "\n\n");
146  fscanf(infile, "%hd%hd", &numsp, &sites);
147  if (printdata)
148    fprintf(outfile, "%4hd Species, %4hd Sites\n", numsp, sites);
149  numsp1 = numsp + 1;
150  numsp2 = numsp * 2 - 2;
151}  /* getnums */
152
153void getoptions()
154{
155  /* interactively set options */
156  short i, j, inseed0;
157  Char ch;
158  char line[256];
159  char rest[256];
160  int scanned;
161  boolean done1, done2, didchangecat;
162  double probsum;
163
164  fprintf(outfile, "\nNucleic acid sequence Maximum Likelihood");
165  fprintf(outfile, " method, version %s\n\n",VERSION);
166  putchar('\n');
167  auto_ = false;
168  ctgry = false;
169  didchangecat = false;
170  categs = 1;
171  freqsfrom = true;
172  global = false;
173  jumble = false;
174  njumble = 1;
175  lngths = false;
176  lambda = 1.0;
177  outgrno = 1;
178  outgropt = false;
179  trout = true;
180  ttratio = 2.0;
181  ttr = false;
182  usertree = false;
183  weights = false;
184  printdata = false;
185  progress = true;
186  treeprint = true;
187  interleaved = true;
188  for (;;){
189    printf((ansi) ? "\033[2J\033[H" :
190           (vt52) ? "\033E\033H"    : "\n");
191    printf("\nNucleic acid sequence Maximum Likelihood");
192    printf(" method, version %s\n\n",VERSION);
193    printf("Settings for this run:\n");
194    printf("  U                 Search for best tree?  %s\n",
195           (usertree ? "No, use user trees in input file" : "Yes"));
196    if (usertree) {
197      printf("  L          Use lengths from user trees?  %s\n",
198             (lngths ? "Yes" : "No"));
199    }
200    printf("  T        Transition/transversion ratio:%8.4f\n",
201           (ttr ? ttratio : 2.0));
202    printf("  F       Use empirical base frequencies?  %s\n",
203           (freqsfrom ? "Yes" : "No"));
204    printf("  C   One category of substitution rates?");
205    if (!ctgry || categs == 1)
206      printf("  Yes\n");
207    else {
208      printf("  %hd categories\n", categs);
209      printf("  R   Rates at adjacent sites correlated?");
210      if (!auto_)
211        printf("  No, they are independent\n");
212      else
213        printf("  Yes, mean block length =%6.1f\n", 1.0 / lambda);
214    }
215    if (!usertree) {
216      printf("  G                Global rearrangements?  %s\n",
217             (global ? "Yes" : "No"));
218      printf("  J   Randomize input order of sequences?");
219      if (jumble)
220        printf("  Yes (seed =%8hd,%3hd times)\n", inseed0, njumble);
221      else
222        printf("  No. Use input order\n");
223    }
224    printf("  O                        Outgroup root?  %s%3hd\n",
225           (outgropt ? "Yes, at sequence number" :
226                       "No, use as outgroup species"),outgrno);
227    printf("  M           Analyze multiple data sets?");
228    if (mulsets)
229      printf("  Yes, %2hd sets\n", datasets);
230    else
231      printf("  No\n");
232    printf("  I          Input sequences interleaved?  %s\n",
233           (interleaved ? "Yes" : "No, sequential"));
234    printf("  0   Terminal type (IBM PC, VT52, ANSI)?  %s\n",
235           (ibmpc ? "IBM PC" :
236            ansi  ? "ANSI"   :
237            vt52  ? "VT52"   : "(none)"));
238    printf("  1    Print out the data at start of run  %s\n",
239           (printdata ? "Yes" : "No"));
240    printf("  2  Print indications of progress of run  %s\n",
241           (progress ? "Yes" : "No"));
242    printf("  3                        Print out tree  %s\n",
243           (treeprint ? "Yes" : "No"));
244    printf("  4       Write out trees onto tree file?  %s\n",
245           (trout ? "Yes" : "No"));
246    printf("\nAre these settings correct? (type Y or the letter for one to change)\n");
247    scanf("%c%*[^\n]", &ch);
248    getchar();
249    if (ch == '\n')
250      ch = ' ';
251    uppercase(&ch);
252    if (ch == 'Y')
253      break;
254    uppercase(&ch);
255    if (strchr("JOUCRFGLTMI01234",ch) != NULL){
256      switch (ch) {
257      case 'C':
258        ctgry = !ctgry;
259        if (!ctgry)
260          auto_ = false;
261        if (ctgry) {
262          do {
263            printf("Number of categories (1 - %ld)?\n",(long)maxcategs);
264            gets(line);
265            categs = (short)atoi(line);
266          } while (categs < 1 || categs > maxcategs);
267          if (probcat){
268            free(probcat);
269            free(rate);
270          }
271          probcat = (double *)Malloc(categs * sizeof(double));
272          rate    = (double *)Malloc(categs * sizeof(double));
273          didchangecat = true;
274          for (;;){
275            printf("Rate for each category? (use a space to separate)\n");
276            gets(line);
277            done1 = true;
278            for (i = 0; i < categs; i++){
279              scanned = sscanf(line,"%lf %[^\n]", &rate[i],rest);
280              if ((scanned != 2 && i < (categs - 1)) ||
281                 (scanned != 1 && i == (categs - 1))) {
282                printf("Please enter exactly %hd values.\n",categs);
283                done1 = false;
284                break;
285              }
286              strcpy(line,rest);
287            }
288            if (done1)
289              break;
290          }
291        probsum = 0.0;
292        for (;;){
293          printf("Probability for each category? (use a space to separate)\n");
294          gets(line);
295          done1 = true;
296          probsum = 0.0;
297          for (i = 0; i < categs; i++){
298            scanned = sscanf(line,"%lf %[^\n]", &probcat[i],rest);
299            if ((scanned != 2 && i < (categs - 1)) ||
300                (scanned != 1 && i == (categs - 1))){
301              printf("Please enter exactly %hd values.\n",categs);
302              done1 = false;
303              break;
304            }
305            strcpy(line,rest);
306            probsum += probcat[i];
307          }
308          if (!done1)
309            continue;
310          if (fabs(1.0 - probsum) > 0.001) {
311            done1  = false;
312            printf("Probabilities must add up to 1.0, plus or minus 0.001.\n");
313          }
314          else
315            done1 = true;
316          if (done1)
317            break;
318          }
319        }
320        break;
321       
322      case 'R':
323        auto_ = !auto_;
324        if (auto_) {
325          do {
326            printf(
327                "Mean block length of sites having the same rate (greater than 1)?\n");
328            scanf("%lf%*[^\n]", &lambda);
329            getchar();
330            } while (lambda <= 1.0);
331          lambda = 1.0 / lambda;
332        }
333        break;
334       
335      case 'F':
336        freqsfrom = !freqsfrom;
337        if (!freqsfrom) {
338          printf("Base frequencies for A, C, G, T/U (use blanks to separate)?\n");
339          scanf("%lf%lf%lf%lf%*[^\n]", &freqa, &freqc, &freqg, &freqt);
340          getchar();
341        }
342        break;
343       
344      case 'G':
345        global = !global;
346        break;
347       
348      case 'J':
349        jumble = !jumble;
350        if (jumble) {
351          printf("Random number seed (must be odd)?\n");
352          scanf("%hd%*[^\n]", &inseed);
353          getchar();
354          inseed0 = inseed;
355          for (i = 0; i <= 5; i++)
356            seed[i] = 0;
357          i = 0;
358          do {
359            seed[i] = inseed & 63;
360            inseed /= 64;
361            i++;
362          } while (inseed != 0);
363          printf("Number of times to jumble?\n");
364          scanf("%hd%*[^\n]", &njumble);
365          getchar();
366        }
367        else njumble = 1;
368        break;
369       
370      case 'L':
371        lngths = !lngths;
372        break;
373       
374      case 'O':
375        outgropt = !outgropt;
376        if (outgropt) {
377          for (;;) {
378            printf("Type number of the outgroup:\n");
379            scanf("%hd%*[^\n]", &outgrno);
380            getchar();
381            if (outgrno >= 1 || outgrno <= numsp)
382              break;
383            else {
384              printf("BAD OUTGROUP NUMBER: %4hd\n", outgrno);
385              printf("  Must be in range 1 -%2hd\n", numsp);
386            }
387          }
388        }
389        break;
390       
391      case 'T':
392        ttr = !ttr;
393        if (ttr) {
394          do {
395            printf("Transition/transversion ratio?\n");
396            scanf("%lf%*[^\n]", &ttratio);
397            getchar();
398          } while (ttratio < 0.0);
399        }
400        break;
401       
402      case 'U':
403        usertree = !usertree;
404        break;
405       
406      case 'M':
407        mulsets = !mulsets;
408        if (mulsets) {
409          for(;;) {
410            printf("How many data sets?\n");
411            scanf("%hd%*[^\n]", &datasets);
412            getchar();
413            if (datasets >= 1)
414              break;
415            else
416              printf("BAD DATA SETS NUMBER:  it must be greater than 1\n");
417          }
418        }
419        break;
420       
421      case 'I':
422        interleaved = !interleaved;
423        break;
424       
425      case '0':
426        if (ibmpc) {
427          ibmpc = false;
428          vt52 = true;
429        } else {
430          if (vt52) {
431            vt52 = false;
432            ansi = true;
433          } else if (ansi)
434            ansi = false;
435          else
436            ibmpc = true;
437        }
438        break;
439       
440      case '1':
441        printdata = !printdata;
442        break;
443       
444      case '2':
445        progress = !progress;
446        break;
447       
448      case '3':
449        treeprint = !treeprint;
450        break;
451       
452      case '4':
453        trout = !trout;
454        break;
455      }
456    } else
457      printf("Not a possible option!\n");
458  }
459if (!didchangecat){
460     rate       = Malloc(categs*sizeof(double));
461     probcat    = Malloc(categs*sizeof(double));
462     rate[0]    = 1.0;
463     probcat[0] = 1.0;
464   }
465}  /* getoptions */
466
467
468void doinit()
469{
470  /* initializes variables */
471  short i, j;
472  node *p, *q;
473
474  getnums();
475  getoptions();
476  y = (Char **)Malloc(numsp*sizeof(Char *));
477  for (i = 0; i < numsp; i++)
478    y[i] = (Char *)Malloc(sites*sizeof(Char));
479  curtree.nodep = (node **)Malloc(numsp2*sizeof(node *));
480  for (i = 0; i < numsp; i++)
481    curtree.nodep[i] = (node *)Malloc(sizeof(node));
482  for (i = numsp1 - 1; i < numsp2; i++) {
483    q = NULL;
484    for (j = 1; j <= 3; j++) {
485      p = (node *)Malloc(sizeof(node));
486      p->next = q;
487      q = p;
488    }
489    p->next->next->next = p;
490    curtree.nodep[i] = p;
491  }
492  if (usertree)
493    return;
494  bestree.nodep = (node **)Malloc(numsp2*sizeof(node *));
495  for (i = 0; i < numsp; i++)
496    bestree.nodep[i] = (node *)Malloc(sizeof(node));
497  for (i = numsp1 - 1; i < numsp2; i++) {
498    q = NULL;
499    for (j = 1; j <= 3; j++) {
500      p = (node *)Malloc(sizeof(node));
501      p->next = q;
502      q = p;
503    }
504    p->next->next->next = p;
505    bestree.nodep[i] = p;
506  }
507  if (njumble <= 1)
508    return;
509  bestree2.nodep = (node **)Malloc(numsp2*sizeof(node *));
510  for (i = 0; i < numsp; i++)
511    bestree2.nodep[i] = (node *)Malloc(sizeof(node));
512  for (i = numsp1 - 1; i < numsp2; i++) {
513    q = NULL;
514    for (j = 1; j <= 3; j++) {
515      p = (node *)Malloc(sizeof(node));
516      p->next = q;
517      q = p;
518    }
519    p->next->next->next = p;
520    bestree2.nodep[i] = p;
521  }
522}  /* doinit */
523
524
525
526void inputweights()
527{
528  /* input the character weights, 0 or 1 */
529  Char ch;
530  short i;
531
532  for (i = 1; i < nmlngth; i++) {
533    ch = getc(infile);
534    if (ch == '\n')
535      ch = ' ';
536  }
537  weightsum = 0;
538  for (i = 0; i < sites; i++) {
539    do {
540      if (eoln(infile)) {
541        fscanf(infile, "%*[^\n]");
542        getc(infile);
543      }
544      ch = getc(infile);
545      if (ch == '\n')
546        ch = ' ';
547    } while (ch == ' ');
548    weight[i] = 1;
549    if (ch == '0' || ch == '1')
550      weight[i] = ch - '0';
551    else {
552      printf("BAD WEIGHT CHARACTER: %c -- WEIGHTS IN DNAML MUST BE 0 OR 1\n",
553             ch);
554      exit(-1);
555    }
556    weightsum += weight[i];
557  }
558  fscanf(infile, "%*[^\n]");
559  getc(infile);
560  weights = true;
561}  /* inputweights */
562
563void printweights()
564{
565  /* print out the weights of sites */
566  short i, j;
567
568  fprintf(outfile, "\n   Sites are weighted as follows:\n");
569  for (i = 1; i <= sites; i++) {
570    if ((i - 1) % 60 == 0) {
571      putc('\n', outfile);
572      for (j = 1; j <= nmlngth + 3; j++)
573        putc(' ', outfile);
574    }
575    fprintf(outfile, "%hd", weight[i - 1]);
576    if (i % 10 == 0 && i % 60 != 0)
577      putc(' ', outfile);
578  }
579  fprintf(outfile, "\n\n");
580}  /* printweights */
581
582void inputoptions()
583{
584  Char ch;
585  short i, extranum, cursp, curst;
586
587  if (!firstset) {
588    if (eoln(infile)) {
589      fscanf(infile, "%*[^\n]");
590      getc(infile);
591    }
592    fscanf(infile, "%hd%hd", &cursp, &curst);
593    if (cursp != numsp) {
594      printf("\nERROR: INCONSISTENT NUMBER OF SPECIES IN DATA SET %4hd\n",
595             ith);
596      exit(-1);
597    }
598    sites = curst;
599  }
600  for (i = 0; i < sites; i++)
601    category[i] = 1;
602  for (i = 0; i < sites; i++)
603    weight[i] = 1;
604  weightsum = sites;
605  extranum = 0;
606  while (!(eoln(infile))) {
607    ch = getc(infile);
608    if (ch == '\n')
609      ch = ' ';
610    uppercase(&ch);
611    if (ch == 'C' || ch == 'W')
612      extranum++;
613    else if (ch != ' ') {
614      printf("BAD OPTION CHARACTER: %c\n", ch);
615      exit(-1);
616    }
617  }
618  fscanf(infile, "%*[^\n]");
619  getc(infile);
620  for (i = 1; i <= extranum; i++) {
621    ch = getc(infile);
622    if (ch == '\n')
623      ch = ' ';
624    uppercase(&ch);
625    if (ch != 'W'){
626      printf("ERROR: INCORRECT AUXILIARY OPTIONS LINE WHICH STARTS WITH %c\n",
627             ch);
628      exit(-1);
629      }
630    else
631      inputweights();
632  }
633  if (categs > 1) {
634    fprintf(outfile, "\nSite category   Rate of change    Probability\n\n");
635    for (i = 1; i <= categs; i++)
636      fprintf(outfile, "%12hd%13.3f%17.3f\n", i, rate[i - 1], probcat[i-1]);
637    putc('\n', outfile);
638    if (auto_)
639      fprintf(outfile,
640     "\nExpected length of a patch of sites having the same rate = %8.3f\n",
641             1/lambda);
642  }
643  if (weights && printdata)
644    printweights();
645}  /* inputoptions */
646
647void getbasefreqs()
648{
649  double aa, bb;
650
651  putc('\n', outfile);
652  if (freqsfrom)
653    fprintf(outfile, "Empirical ");
654  fprintf(outfile, "Base Frequencies:\n\n");
655  fprintf(outfile, "   A    %10.5f\n", freqa);
656  fprintf(outfile, "   C    %10.5f\n", freqc);
657  fprintf(outfile, "   G    %10.5f\n", freqg);
658  fprintf(outfile, "  T(U)  %10.5f\n", freqt);
659  freqr = freqa + freqg;
660  freqy = freqc + freqt;
661  freqar = freqa / freqr;
662  freqcy = freqc / freqy;
663  freqgr = freqg / freqr;
664  freqty = freqt / freqy;
665  fprintf(outfile, "\nTransition/transversion ratio = %10.6f\n\n", ttratio);
666  aa = ttratio * freqr * freqy - freqa * freqg - freqc * freqt;
667  bb = freqa * freqgr + freqc * freqty;
668  xi = aa / (aa + bb);
669  xv = 1.0 - xi;
670  ttratio = xi / xv;
671  if (xi <= 0.0) {
672    printf("WARNING: This transition/transversion ratio\n");
673    printf("is impossible with these base frequencies!\n");
674    xi = 3.0 / 5;
675    xv = 2.0 / 5;
676    fprintf(outfile, " Transition/transversion parameter reset\n\n");
677  }
678  fprintf(outfile, "(Transition/transversion parameter = %10.6f)\n\n",
679          xi / xv);
680  fracchange = xi * (2 * freqa * freqgr + 2 * freqc * freqty) +
681      xv * (1.0 - freqa * freqa - freqc * freqc - freqg * freqg - freqt * freqt);
682}  /* getbasefreqs */
683
684void setuptree(a)
685tree *a;
686{
687  short i, j;
688  node *p;
689
690  for (i = 1; i <= numsp; i++) {
691    a->nodep[i - 1]->tip = true;
692    a->nodep[i - 1]->iter = true;
693    a->nodep[i - 1]->number = i;
694  }
695  for (i = numsp1; i <= numsp2; i++) {
696    p = a->nodep[i - 1];
697    for (j = 1; j <= 3; j++) {
698      p->tip = false;
699      p->iter = true;
700      p->number = i;
701      p = p->next;
702    }
703  }
704  a->likelihood = -999999.0;
705  a->start = a->nodep[0];
706}  /* setuptree */
707
708void getdata()
709{
710  /* read sequences */
711  short i, j, k, l, basesread, basesnew;
712  Char ch;
713  boolean allread, done;
714
715  putc('\n', outfile);
716  j = nmlngth + (sites + (sites - 1) / 10) / 2 - 5;
717  if (j < nmlngth - 1)
718    j = nmlngth - 1;
719  if (j > 37)
720    j = 37;
721  if (printdata) {
722    fprintf(outfile, "Name");
723    for (i = 1; i <= j; i++)
724      putc(' ', outfile);
725    fprintf(outfile, "Sequences\n");
726    fprintf(outfile, "----");
727    for (i = 1; i <= j; i++)
728      putc(' ', outfile);
729    fprintf(outfile, "---------\n\n");
730  }
731  setuptree(&curtree);
732  basesread = 0;
733  allread = false;
734  while (!(allread)) {
735    allread = true;
736    if (eoln(infile)) {
737      fscanf(infile, "%*[^\n]");
738      getc(infile);
739    }
740    i = 1;
741    while (i <= numsp) {
742      if ((interleaved && basesread == 0) || !interleaved) {
743        for (j = 0; j < nmlngth; j++) {
744          if (eof(infile) || eoln(infile)){
745            printf("ERROR: END-OF-LINE OR END-OF-FILE");
746            printf(" IN THE MIDDLE OF A SPECIES NAME\n");
747            exit(-1);
748            }
749          curtree.nodep[i - 1]->nayme[j] = getc(infile);
750        }
751      }
752      if (interleaved)
753        j = basesread;
754      else
755        j = 0;
756      done = false;
757      while (!done & !eof(infile)) {
758        if (interleaved)
759          done = true;
760        while (((j < sites) & (!(eoln(infile) | eof(infile))))) {
761          ch = getc(infile);
762          if (ch == '\n')
763            ch = ' ';
764          if (ch == ' ' || (ch >= '0' && ch <= '9'))
765            continue;
766          uppercase(&ch);
767          if (strchr("ABCDGHKMNRSTUVWXY?O-.",ch) == NULL){
768            printf("ERROR: BAD BASE:%c AT POSITION%5hd OF SPECIES %3ld\n",
769                   ch, j, i);
770            exit(-1);
771          }
772          j++;
773          if (ch == '.')
774            ch = y[0][j - 1];
775          y[i - 1][j - 1] = ch;
776        }
777        if (interleaved)
778          continue;
779        if (j < sites) {
780          fscanf(infile, "%*[^\n]");
781          getc(infile);
782        } else if (j == sites)
783          done = true;
784      }
785      if (interleaved && i == 1)
786        basesnew = j;
787      fscanf(infile, "%*[^\n]");
788      getc(infile);
789      if ((interleaved && j != basesnew) || ((!interleaved) && j != sites)){
790        printf("ERROR: SEQUENCES OUT OF ALIGNMENT\n");
791        exit(-1);
792        }
793     i++;
794    }
795    if (interleaved) {
796      basesread = basesnew;
797      allread = (basesread == sites);
798    } else
799      allread = (i > numsp);
800  }
801  if (printdata) {
802    for (i = 1; i <= ((sites - 1) / 60 + 1); i++) {
803      for (j = 1; j <= numsp; j++) {
804        for (k = 0; k < nmlngth; k++)
805          putc(curtree.nodep[j - 1]->nayme[k], outfile);
806        fprintf(outfile, "   ");
807        l = i * 60;
808        if (l > sites)
809          l = sites;
810        for (k = (i - 1) * 60 + 1; k <= l; k++) {
811          if (j > 1 && y[j - 1][k - 1] == y[0][k - 1])
812            ch = '.';
813          else
814            ch = y[j - 1][k - 1];
815          putc(ch, outfile);
816          if (k % 10 == 0 && k % 60 != 0)
817            putc(' ', outfile);
818        }
819        putc('\n', outfile);
820      }
821      putc('\n', outfile);
822    }
823  }
824  if (!usertree) {
825    setuptree(&bestree);
826    if (njumble > 1)
827      setuptree(&bestree2);
828  }
829}  /* getdata */
830
831void sitesort()
832{
833  /* Shell sort keeping sites, weights in same order */
834  short gap, i, j, jj, jg, k, itemp;
835  boolean flip, tied;
836
837  gap = sites / 2;
838  while (gap > 0) {
839    for (i = gap + 1; i <= sites; i++) {
840      j = i - gap;
841      flip = true;
842      while (j > 0 && flip) {
843        jj = alias[j - 1];
844        jg = alias[j + gap - 1];
845        tied = (weight[jj - 1] == weight[jg - 1]);
846        flip = (weight[jj - 1] < weight[jg - 1]);
847        k = 1;
848        while (k <= numsp && tied) {
849          flip = (y[k - 1][jj - 1] > y[k - 1][jg - 1]);
850          tied = (tied && y[k - 1][jj - 1] == y[k - 1][jg - 1]);
851          k++;
852        }
853        if (!flip)
854          break;
855        itemp = alias[j - 1];
856        alias[j - 1] = alias[j + gap - 1];
857        alias[j + gap - 1] = itemp;
858        itemp = aliasweight[j - 1];
859        aliasweight[j - 1] = aliasweight[j + gap - 1];
860        aliasweight[j + gap - 1] = itemp;
861        j -= gap;
862      }
863    }
864    gap /= 2;
865  }
866}  /* sitesort */
867
868void sitecombine()
869{
870  /* combine sites that have identical patterns */
871  short i, j, k;
872  boolean tied;
873
874  i = 1;
875  while (i < sites) {
876    j = i + 1;
877    tied = true;
878    while (j <= sites && tied) {
879      tied = (weight[alias[i - 1] - 1] == weight[alias[j - 1] - 1]);
880      k = 1;
881      while (k <= numsp && tied) {
882        tied = (tied &&
883            y[k - 1][alias[i - 1] - 1] == y[k - 1][alias[j - 1] - 1]);
884        k++;
885      }
886      if (!tied)
887        break;
888      aliasweight[i - 1] += aliasweight[j - 1];
889      aliasweight[j - 1] = 0;
890      ally[alias[j - 1] - 1] = alias[i - 1];
891      j++;
892    }
893    i = j;
894  }
895}  /* sitecombine */
896
897void sitescrunch()
898{
899  /* move so positively weighted sites come first */
900  short i, j, itemp;
901  boolean done, found;
902
903  done = false;
904  i = 1;
905  j = 2;
906  while (!done) {
907    found = false;
908    if (aliasweight[i - 1] > 0)
909      i++;
910    else {
911      if (j <= i)
912        j = i + 1;
913      if (j <= sites) {
914        found = false;
915        do {
916          found = (aliasweight[j - 1] > 0);
917          j++;
918        } while (!(found || j > sites));
919        if (found) {
920          j--;
921          itemp = alias[i - 1];
922          alias[i - 1] = alias[j - 1];
923          alias[j - 1] = itemp;
924          itemp = aliasweight[i - 1];
925          aliasweight[i - 1] = aliasweight[j - 1];
926          aliasweight[j - 1] = itemp;
927        } else
928          done = true;
929      } else
930        done = true;
931    }
932    done = (done || i >= sites);
933  }
934}  /* sitescrunch */
935
936void makeweights()
937{
938  /* make up weights vector to avoid duplicate computations */
939  int i,j,k;
940  node *p;
941  double temp;
942
943  for (i = 1; i <= sites; i++) {
944    alias[i - 1] = i;
945    ally[i - 1] = 0;
946    aliasweight[i - 1] = weight[i - 1];
947    location[i - 1] = 0;
948  }
949  sitesort();
950  sitecombine();
951  sitescrunch();
952  for (i = 1; i <= sites; i++) {
953    weight[i - 1] = aliasweight[i - 1];
954    if (weight[i - 1] > 0)
955      endsite = i;
956  }
957  for (i = 1; i <= endsite; i++) {
958    location[alias[i - 1] - 1] = i;
959    ally[alias[i - 1] - 1] = alias[i - 1];
960  }
961  sumrates = 0.0;
962  for (i = 0; i < categs; i++)
963    sumrates += probcat[i] * rate[i];
964  for (i = 0; i < categs; i++)
965    rate[i] /= sumrates;
966  if (usertree)
967    for (i = 0; i < maxtrees; i++)
968      l0gf[i] = (double *)Malloc(endsite*sizeof(double));
969  contribution = (contribarr *)Malloc(endsite*sizeof(contribarr));
970  for (i = 0; i < numsp; i++){
971    curtree.nodep[i]->x = (phenotype)Malloc(endsite*sizeof(ratelike));
972    for (j=0;j<endsite;j++)
973      curtree.nodep[i]->x[j]  = (ratelike)Malloc(categs*sizeof(sitelike));
974  }
975  for (i = numsp1 - 1; i < numsp2; i++) {
976    p = curtree.nodep[i];
977    for (j = 1; j <= 3; j++) {
978      p->x = (phenotype)Malloc(endsite*sizeof(ratelike));
979      for (k=0;k<endsite;++k)
980           p->x[k] = (ratelike)Malloc(categs*sizeof(sitelike));
981      p = p->next;
982    }
983  }
984  if (usertree)
985    return;
986  for (i = 0; i < numsp; i++){
987    bestree.nodep[i]->x = (phenotype)Malloc(endsite*sizeof(ratelike));
988    for (j=0;j<endsite;++j)
989        bestree.nodep[i]->x[j] = (ratelike)Malloc(categs*sizeof(sitelike));
990      }
991
992  for (i = numsp1 - 1; i < numsp2; i++) {
993    p = bestree.nodep[i];
994    for (j = 1; j <= 3; j++) {
995      p->x = (phenotype)Malloc(endsite*sizeof(ratelike));
996      for (k=0;k<endsite;++k)
997        p->x[k] = (ratelike)Malloc(categs*sizeof(sitelike));
998      p = p->next;
999    }
1000  }
1001  if (njumble <= 1)
1002    return;
1003  for (i = 0; i < numsp; i++) {
1004    bestree2.nodep[i]->x = (phenotype)Malloc(endsite*sizeof(ratelike));
1005    for (j=0;j<endsite;++j)
1006        bestree2.nodep[i]->x[j] = (ratelike)Malloc(categs*sizeof(sitelike));
1007  }
1008  for (i = numsp1 - 1; i < numsp2; i++) {
1009    p = bestree2.nodep[i];
1010    for (j = 1; j <= 3; j++) {
1011      p->x = (phenotype)Malloc(endsite*sizeof(ratelike));
1012      for (k=0;k<endsite;++k)
1013        p->x[k] = (ratelike)Malloc(categs*sizeof(sitelike));
1014      p = p->next;
1015    }
1016  }
1017}  /* makeweights */
1018
1019void makevalues()
1020{
1021  /* set up fractional likelihoods at tips */
1022  short i, j, k, l;
1023  base b;
1024
1025  for (k = 0; k < endsite; k++) {
1026    j = alias[k];
1027    for (i = 0; i < numsp; i++) {
1028      for (l = 0; l < categs; l++) {
1029        for (b = A; (short)b <= (short)T; b = (base)((short)b + 1))
1030          curtree.nodep[i]->x[k][l][(short)b - (short)A] = 0.0;
1031        switch (y[i][j - 1]) {
1032
1033        case 'A':
1034          curtree.nodep[i]->x[k][l][0] = 1.0;
1035          break;
1036
1037        case 'C':
1038          curtree.nodep[i]->x[k][l][(short)C - (short)A] = 1.0;
1039          break;
1040
1041        case 'G':
1042          curtree.nodep[i]->x[k][l][(short)G - (short)A] = 1.0;
1043          break;
1044
1045        case 'T':
1046          curtree.nodep[i]->x[k][l][(short)T - (short)A] = 1.0;
1047          break;
1048
1049        case 'U':
1050          curtree.nodep[i]->x[k][l][(short)T - (short)A] = 1.0;
1051          break;
1052
1053        case 'M':
1054          curtree.nodep[i]->x[k][l][0] = 1.0;
1055          curtree.nodep[i]->x[k][l][(short)C - (short)A] = 1.0;
1056          break;
1057
1058        case 'R':
1059          curtree.nodep[i]->x[k][l][0] = 1.0;
1060          curtree.nodep[i]->x[k][l][(short)G - (short)A] = 1.0;
1061          break;
1062
1063        case 'W':
1064          curtree.nodep[i]->x[k][l][0] = 1.0;
1065          curtree.nodep[i]->x[k][l][(short)T - (short)A] = 1.0;
1066          break;
1067
1068        case 'S':
1069          curtree.nodep[i]->x[k][l][(short)C - (short)A] = 1.0;
1070          curtree.nodep[i]->x[k][l][(short)G - (short)A] = 1.0;
1071          break;
1072
1073        case 'Y':
1074          curtree.nodep[i]->x[k][l][(short)C - (short)A] = 1.0;
1075          curtree.nodep[i]->x[k][l][(short)T - (short)A] = 1.0;
1076          break;
1077
1078        case 'K':
1079          curtree.nodep[i]->x[k][l][(short)G - (short)A] = 1.0;
1080          curtree.nodep[i]->x[k][l][(short)T - (short)A] = 1.0;
1081          break;
1082
1083        case 'B':
1084          curtree.nodep[i]->x[k][l][(short)C - (short)A] = 1.0;
1085          curtree.nodep[i]->x[k][l][(short)G - (short)A] = 1.0;
1086          curtree.nodep[i]->x[k][l][(short)T - (short)A] = 1.0;
1087          break;
1088
1089        case 'D':
1090          curtree.nodep[i]->x[k][l][0] = 1.0;
1091          curtree.nodep[i]->x[k][l][(short)G - (short)A] = 1.0;
1092          curtree.nodep[i]->x[k][l][(short)T - (short)A] = 1.0;
1093          break;
1094
1095        case 'H':
1096          curtree.nodep[i]->x[k][l][0] = 1.0;
1097          curtree.nodep[i]->x[k][l][(short)C - (short)A] = 1.0;
1098          curtree.nodep[i]->x[k][l][(short)T - (short)A] = 1.0;
1099          break;
1100
1101        case 'V':
1102          curtree.nodep[i]->x[k][l][0] = 1.0;
1103          curtree.nodep[i]->x[k][l][(short)C - (short)A] = 1.0;
1104          curtree.nodep[i]->x[k][l][(short)G - (short)A] = 1.0;
1105          break;
1106
1107        case 'N':
1108          for (b = A; (short)b <= (short)T; b = (base)((short)b + 1))
1109            curtree.nodep[i]->x[k][l][(short)b - (short)A] = 1.0;
1110          break;
1111
1112        case 'X':
1113          for (b = A; (short)b <= (short)T; b = (base)((short)b + 1))
1114            curtree.nodep[i]->x[k][l][(short)b - (short)A] = 1.0;
1115          break;
1116
1117        case '?':
1118          for (b = A; (short)b <= (short)T; b = (base)((short)b + 1))
1119            curtree.nodep[i]->x[k][l][(short)b - (short)A] = 1.0;
1120          break;
1121
1122        case 'O':
1123          for (b = A; (short)b <= (short)T; b = (base)((short)b + 1))
1124            curtree.nodep[i]->x[k][l][(short)b - (short)A] = 1.0;
1125          break;
1126
1127        case '-':
1128          for (b = A; (short)b <= (short)T; b = (base)((short)b + 1))
1129            curtree.nodep[i]->x[k][l][(short)b - (short)A] = 1.0;
1130          break;
1131        }
1132      }
1133    }
1134  }
1135}  /* makevalues */
1136
1137Local Void empiricalfreqs()
1138{
1139  /* Get empirical base frequencies from the data */
1140  short i, j, k;
1141  double sum, suma, sumc, sumg, sumt, w;
1142
1143  freqa = 0.25;
1144  freqc = 0.25;
1145  freqg = 0.25;
1146  freqt = 0.25;
1147  for (k = 1; k <= 8; k++) {
1148    suma = 0.0;
1149    sumc = 0.0;
1150    sumg = 0.0;
1151    sumt = 0.0;
1152    for (i = 0; i < numsp; i++) {
1153      for (j = 0; j < endsite; j++) {
1154        w = weight[j];
1155        sum = freqa * curtree.nodep[i]->x[j][0][0];
1156        sum += freqc * curtree.nodep[i]->x[j][0][(short)C - (short)A];
1157        sum += freqg * curtree.nodep[i]->x[j][0][(short)G - (short)A];
1158        sum += freqt * curtree.nodep[i]->x[j][0][(short)T - (short)A];
1159        suma += w * freqa * curtree.nodep[i]->x[j][0][0] / sum;
1160        sumc += w * freqc * curtree.nodep[i]->x[j][0][(short)C - (short)A] / sum;
1161        sumg += w * freqg * curtree.nodep[i]->x[j][0][(short)G - (short)A] / sum;
1162        sumt += w * freqt * curtree.nodep[i]->x[j][0][(short)T - (short)A] / sum;
1163      }
1164    }
1165    sum = suma + sumc + sumg + sumt;
1166    freqa = suma / sum;
1167    freqc = sumc / sum;
1168    freqg = sumg / sum;
1169    freqt = sumt / sum;
1170  }
1171}  /* empiricalfreqs */
1172
1173
1174void getinput()
1175{
1176  /* reads the input data */
1177  inputoptions();
1178  if (!freqsfrom)
1179    getbasefreqs();
1180  getdata();
1181  makeweights();
1182  makevalues();
1183  if (freqsfrom) {
1184    empiricalfreqs();
1185    getbasefreqs();
1186  }
1187}  /* getinput */
1188
1189
1190main(argc, argv)
1191int argc;
1192Char *argv[];
1193{  /* DNA Maximum Likelihood */
1194char infilename[100],outfilename[100],trfilename[100];
1195#ifdef MAC
1196  macsetup("dnaml","");
1197#endif
1198  openfile(&infile,"infile","r",argv[0],infilename);
1199  openfile(&outfile,"outfile","w",argv[0],outfilename);
1200  mulsets = false;
1201  datasets = 1;
1202  firstset = true;
1203  ibmpc = ibmpc0;
1204  ansi = ansi0;
1205  vt52 = vt520;
1206  doinit();
1207  ttratio0    = ttratio;
1208  enterorder  = (short *)Malloc(numsp*sizeof(short));
1209  category    = (short *)Malloc(sites*sizeof(short));
1210  weight      = (short *)Malloc(sites*sizeof(short));
1211  alias       = (short *)Malloc(sites*sizeof(short));
1212  ally        = (short *)Malloc(sites*sizeof(short));
1213  location    = (short *)Malloc(sites*sizeof(short));
1214  aliasweight = (short *)Malloc(sites*sizeof(short));
1215  if (trout)
1216    openfile(&treefile,"treefile","w",argv[0],trfilename);
1217  for (ith = 1; ith <= datasets; ith++) {
1218    if (datasets > 1) {
1219      fprintf(outfile, "Data set # %hd:\n", ith);
1220      printf("\nData set # %hd:\n", ith);
1221    }
1222    ttratio = ttratio0;
1223    getinput();
1224    if (ith == 1)
1225      firstset = false;
1226    for (jumb = 1; jumb <= njumble; jumb++)
1227      maketree();
1228  }
1229  FClose(infile);
1230  FClose(outfile);
1231  FClose(treefile);
1232#ifdef MAC
1233  fixmacfile(outfilename);
1234  fixmacfile(trfilename);
1235#endif
1236  exit(0);
1237}  /* DNA Maximum Likelihood */
1238
1239int eof(f)
1240FILE *f;
1241{
1242    register int ch;
1243
1244    if (feof(f))
1245        return 1;
1246    if (f == stdin)
1247        return 0;
1248    ch = getc(f);
1249    if (ch == EOF)
1250        return 1;
1251    ungetc(ch, f);
1252    return 0;
1253}
1254
1255
1256int eoln(f)
1257FILE *f;
1258{
1259    register int ch;
1260
1261    ch = getc(f);
1262    if (ch == EOF)
1263        return 1;
1264    ungetc(ch, f);
1265    return (ch == '\n');
1266}
1267
1268void memerror()
1269{
1270printf("Error allocating memory\n");
1271exit(-1);
1272}
1273
1274MALLOCRETURN *mymalloc(x)
1275long  x;
1276{
1277MALLOCRETURN *mem;
1278mem = (MALLOCRETURN *)calloc(1,x);
1279if (!mem)
1280  memerror();
1281else
1282  return (MALLOCRETURN *)mem;
1283}
1284
1285
Note: See TracBrowser for help on using the repository browser.