source: trunk/GDE/PHYLIP/dollo.c

Last change on this file was 2175, checked in by westram, 21 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: 10.5 KB
Line 
1#include "phylip.h"
2#include "disc.h"
3#include "dollo.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
10void correct(node *p, long fullset, boolean dollo,
11                        bitptr zeroanc, pointptr treenode)
12{  /* get final states for intermediate nodes */
13  long i;
14  long z0, z1, s0, s1, temp;
15
16  if (p->tip)
17    return;
18  for (i = 0; i < (words); i++) {
19    if (p->back == NULL) {
20      s0 = zeroanc[i];
21      s1 = fullset & (~zeroanc[i]);
22    } else {
23      s0 = treenode[p->back->index - 1]->statezero[i];
24      s1 = treenode[p->back->index - 1]->stateone[i];
25    }
26    z0 = (s0 & p->statezero[i]) |
27         (p->next->back->statezero[i] & p->next->next->back->statezero[i]);
28    z1 = (s1 & p->stateone[i]) |
29         (p->next->back->stateone[i] & p->next->next->back->stateone[i]);
30    if (dollo) {
31      temp = z0 & (~(zeroanc[i] & z1));
32      z1 &= ~(fullset & (~zeroanc[i]) & z0);
33      z0 = temp;
34    }
35    temp = fullset & (~z0) & (~z1);
36    p->statezero[i] = z0 | (temp & s0 & (~s1));
37    p->stateone[i] = z1 | (temp & s1 & (~s0));
38  }
39}  /* correct */
40
41void fillin(node *p)
42{
43  /* Sets up for each node in the tree two statesets.
44     stateone and statezero are the sets of character
45     states that must be 1 or must be 0, respectively,
46     in a most parsimonious reconstruction, based on the
47     information at or above this node.  Note that this
48     state assignment may change based on information further
49     down the tree.  If a character is in both sets it is in
50     state "P".  If in neither, it is "?". */
51  long i;
52
53  for (i = 0; i < words; i++) {
54    p->stateone[i] = p->next->back->stateone[i] |
55                     p->next->next->back->stateone[i];
56    p->statezero[i] = p->next->back->statezero[i] |
57                      p->next->next->back->statezero[i];
58  }
59}  /* fillin */
60
61void postorder(node *p)
62{
63  /* traverses a binary tree, calling PROCEDURE fillin at a
64     node's descendants before calling fillin at the node */
65  /* used in dollop, dolmove, & move */
66  if (p->tip)
67    return;
68  postorder(p->next->back);
69  postorder(p->next->next->back);
70  fillin(p);
71}  /* postorder */
72
73void count(long *stps, bitptr zeroanc, steptr numszero, steptr numsone)
74{
75  /* counts the number of steps in a branch of the tree.
76     The program spends much of its time in this PROCEDURE */
77  /* used in dolpenny & move */
78  long i, j, l;
79
80  j = 1;
81  l = 0;
82  for (i = 0; i < (chars); i++) {
83    l++;
84    if (l > bits) {
85      l = 1;
86      j++;
87    }
88    if (((1L << l) & stps[j - 1]) != 0) {
89      if (((1L << l) & zeroanc[j - 1]) != 0)
90        numszero[i] += weight[i];
91      else
92        numsone[i] += weight[i];
93    }
94  }
95}  /* count */
96
97void filltrav(node *r)
98{
99  /* traverse to fill in interior node states */
100  if (r->tip)
101    return;
102  filltrav(r->next->back);
103  filltrav(r->next->next->back);
104  fillin(r);
105}  /* filltrav */
106
107
108void hyprint(struct htrav_vars *Hyptrav, boolean *unknown,
109                        bitptr dohyp, Char *guess)
110{
111  /* print out states at node */
112  long i, j, k;
113  char l;
114  boolean dot, a0, a1, s0, s1;
115
116  if (Hyptrav->bottom)
117    fprintf(outfile, "root   ");
118  else
119    fprintf(outfile, "%3ld    ", Hyptrav->r->back->index - spp);
120  if (Hyptrav->r->tip) {
121    for (i = 0; i < nmlngth; i++)
122      putc(nayme[Hyptrav->r->index - 1][i], outfile);
123  } else
124    fprintf(outfile, "%4ld      ", Hyptrav->r->index - spp);
125  if (Hyptrav->nonzero)
126    fprintf(outfile, "   yes    ");
127  else if (*unknown)
128    fprintf(outfile, "    ?     ");
129  else
130    fprintf(outfile, "   no     ");
131  for (j = 1; j <= (chars); j++) {
132    newline(outfile, j, 40, nmlngth + 17);
133    k = (j - 1) / bits + 1;
134    l = (j - 1) % bits + 1;
135    dot = (((1L << l) & dohyp[k - 1]) == 0 && guess[j - 1] == '?');
136    s0 = (((1L << l) & Hyptrav->r->statezero[k - 1]) != 0);
137    s1 = (((1L << l) & Hyptrav->r->stateone[k - 1]) != 0);
138    a0 = (((1L << l) & Hyptrav->zerobelow->bits_[k - 1]) != 0);
139    a1 = (((1L << l) & Hyptrav->onebelow->bits_[k - 1]) != 0);
140    dot = (dot || (a1 == s1 && a0 == s0));
141    if (dot)
142      putc('.', outfile);
143    else {
144      if (s0) {
145        if (s1)
146          putc('P', outfile);
147        else
148          putc('0', outfile);
149      } else if (s1)
150        putc('1', outfile);
151      else
152        putc('?', outfile);
153    }
154    if (j % 5 == 0)
155      putc(' ', outfile);
156  }
157  putc('\n', outfile);
158}  /* hyprint */
159
160void hyptrav(node *r_, boolean *unknown, bitptr dohyp, long fullset,
161        boolean dollo, Char *guess, pointptr treenode, gbit *garbage,
162        bitptr zeroanc, bitptr oneanc)
163{
164  /*  compute, print out states at one interior node */
165  struct htrav_vars HypVars;
166  long i;
167
168  HypVars.r = r_;
169  disc_gnu(&HypVars.zerobelow, &garbage);
170  disc_gnu(&HypVars.onebelow, &garbage);
171  if (!HypVars.r->tip)
172    correct(HypVars.r, fullset, dollo, zeroanc, treenode);
173  HypVars.bottom = (HypVars.r->back == NULL);
174  HypVars.nonzero = false;
175  if (HypVars.bottom) {
176    memcpy(HypVars.zerobelow->bits_, zeroanc, words*sizeof(long));
177    memcpy(HypVars.onebelow->bits_, oneanc, words*sizeof(long));
178  } else {
179    memcpy(HypVars.zerobelow->bits_,
180          treenode[HypVars.r->back->index - 1]->statezero, words*sizeof(long));
181    memcpy(HypVars.onebelow->bits_,
182          treenode[HypVars.r->back->index - 1]->stateone, words*sizeof(long));
183  }
184  for (i = 0; i < (words); i++)
185    HypVars.nonzero = (HypVars.nonzero ||
186                      ((HypVars.r->stateone[i] & HypVars.zerobelow->bits_[i])
187                      | (HypVars.r->statezero[i]
188                        & HypVars.onebelow->bits_[i])) != 0);
189  hyprint(&HypVars,unknown,dohyp, guess);
190  if (!HypVars.r->tip) {
191    hyptrav(HypVars.r->next->back, unknown,dohyp, fullset, dollo, guess,
192              treenode, garbage, zeroanc, oneanc);
193    hyptrav(HypVars.r->next->next->back, unknown,dohyp, fullset, dollo,
194              guess, treenode, garbage, zeroanc, oneanc);
195  }
196  disc_chuck(HypVars.zerobelow, &garbage);
197  disc_chuck(HypVars.onebelow, &garbage);
198}  /* hyptrav */
199
200void hypstates(long fullset, boolean dollo, Char *guess, pointptr treenode,
201                        node *root, gbit *garbage, bitptr zeroanc, bitptr oneanc)
202{
203  /* fill in and describe states at interior nodes */
204  /* used in dollop & dolpenny */
205  boolean unknown  = false;
206  bitptr dohyp;
207  long i, j, k;
208 
209 for (i = 0; i < (words); i++) {
210    zeroanc[i] = 0;
211    oneanc[i] = 0;
212  }
213  for (i = 0; i < (chars); i++) {
214    j = i / bits + 1;
215    k = i % bits + 1;
216    if (guess[i] == '0')
217      zeroanc[j - 1] = ((long)zeroanc[j - 1]) | (1L << k);
218    if (guess[i] == '1')
219      oneanc[j - 1] = ((long)oneanc[j - 1]) | (1L << k);
220    unknown = (unknown || guess[i] == '?');
221  }
222  dohyp = (bitptr)Malloc(words*sizeof(long));
223  for (i = 0; i < words; i++)
224    dohyp[i] = zeroanc[i] | oneanc[i];
225  filltrav(root);
226  fprintf(outfile, "From    To     Any Steps?");
227  fprintf(outfile, "    State at upper node\n");
228  fprintf(outfile, "                            ");
229  fprintf(outfile, " ( . means same as in the node below it on tree)\n\n");
230  hyptrav(root, &unknown,dohyp, fullset, dollo, guess, treenode, garbage,
231            zeroanc, oneanc);
232  free(dohyp);
233}  /* hypstates */
234
235
236void drawline(long i, double scale, node *root)
237{
238  /* draws one row of the tree diagram by moving up tree */
239  node *p, *q, *r, *first =NULL, *last =NULL;
240  long n, j;
241  boolean extra, done;
242
243  p = root;
244  q = root;
245  extra = false;
246  if (i == (long)p->ycoord && p == root) {
247    if (p->index - spp >= 10)
248      fprintf(outfile, "-%2ld", p->index - spp);
249    else
250      fprintf(outfile, "--%ld", p->index - spp);
251    extra = true;
252  } else
253    fprintf(outfile, "  ");
254  do {
255    if (!p->tip) {
256      r = p->next;
257      done = false;
258      do {
259        if (i >= r->back->ymin && i <= r->back->ymax) {
260          q = r->back;
261          done = true;
262        }
263        r = r->next;
264      } while (!(done || r == p));
265      first = p->next->back;
266      r = p->next;
267      while (r->next != p)
268        r = r->next;
269      last = r->back;
270    }
271    done = (p == q);
272    n = (long)(scale * (p->xcoord - q->xcoord) + 0.5);
273    if (n < 3 && !q->tip)
274      n = 3;
275    if (extra) {
276      n--;
277      extra = false;
278    }
279    if ((long)q->ycoord == i && !done) {
280      putc('+', outfile);
281      if (!q->tip) {
282        for (j = 1; j <= n - 2; j++)
283          putc('-', outfile);
284        if (q->index - spp >= 10)
285          fprintf(outfile, "%2ld", q->index - spp);
286        else
287          fprintf(outfile, "-%ld", q->index - spp);
288        extra = true;
289      } else {
290        for (j = 1; j < n; j++)
291          putc('-', outfile);
292      }
293    } else if (!p->tip) {
294      if ((long)last->ycoord > i && (long)first->ycoord < i
295         && i != (long)p->ycoord) {
296        putc('!', outfile);
297        for (j = 1; j < n; j++)
298          putc(' ', outfile);
299      } else {
300        for (j = 1; j <= n; j++)
301          putc(' ', outfile);
302      }
303    } else {
304      for (j = 1; j <= n; j++)
305        putc(' ', outfile);
306    }
307    if (p != q)
308      p = q;
309  } while (!done);
310  if ((long)p->ycoord == i && p->tip) {
311    for (j = 0; j < nmlngth; j++)
312      putc(nayme[p->index - 1][j], outfile);
313  }
314  putc('\n', outfile);
315}  /* drawline */
316
317void printree(double f, boolean treeprint, node *root)
318{
319  /* prints out diagram of the tree */
320  /* used in dollop & dolpenny */
321  long i, tipy, dummy;
322  double scale;
323
324  putc('\n', outfile);
325  if (!treeprint)
326    return;
327  putc('\n', outfile);
328  tipy = 1;
329  dummy = 0;
330  coordinates(root, &tipy, f, &dummy);
331  scale = 1.5;
332  putc('\n', outfile);
333  for (i = 1; i <= (tipy - down); i++)
334    drawline(i, scale, root);
335  putc('\n', outfile);
336}  /* printree */
337
338
339void writesteps(boolean weights, boolean dollo, steptr numsteps)
340{ /* write number of steps */
341  /* used in dollop & dolpenny */
342  long i, j, k;
343
344  if (weights)
345    fprintf(outfile, "weighted");
346  if (dollo)
347    fprintf(outfile, " reversions ");
348  else
349    fprintf(outfile, " polymorphisms ");
350  fprintf(outfile, "in each character:\n");
351  fprintf(outfile, "      ");
352  for (i = 0; i <= 9; i++)
353    fprintf(outfile, "%4ld", i);
354  fprintf(outfile, "\n     *-----------------------------------------\n");
355  for (i = 0; i <= (chars / 10); i++) {
356    fprintf(outfile, "%5ld", i * 10);
357    putc('!', outfile);
358    for (j = 0; j <= 9; j++) {
359      k = i * 10 + j;
360      if (k == 0 || k > chars)
361        fprintf(outfile, "    ");
362      else
363        fprintf(outfile, "%4ld", numsteps[k - 1] + extras[k - 1]);
364    }
365    putc('\n', outfile);
366  }
367  putc('\n', outfile);
368}  /* writesteps */
369
Note: See TracBrowser for help on using the repository browser.