source: tags/arb-6.0/GDE/PHYLIP/cons.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: 32.6 KB
Line 
1#include "phylip.h"
2#include "cons.h"
3
4int tree_pairing;
5
6Char outfilename[FNMLNGTH], intreename[FNMLNGTH], intree2name[FNMLNGTH], outtreename[FNMLNGTH];
7node *root;
8
9long numopts, outgrno, col, setsz;
10long maxgrp;               /* max. no. of groups in all trees found  */
11
12boolean trout, firsttree, noroot, outgropt, didreroot, prntsets,
13               progress, treeprint, goteof, strict, mr=false, mre=false,
14               ml=false; /* initialized all false for Treedist */
15pointarray nodep;
16pointarray treenode;
17group_type **grouping, **grping2, **group2;/* to store groups found  */
18long **order, **order2, lasti;
19group_type *fullset;
20node *grbg;
21long tipy;
22
23double **timesseen, **tmseen2, **times2 ;
24double trweight, ntrees, mlfrac;
25
26/* prototypes */
27void censor(void);
28boolean compatible(long, long);
29void elimboth(long);
30void enternohash(group_type*, long*);
31void enterpartition (group_type*, long*);
32
33
34void initconsnode(node **p, node **grbg, node *q, long len, long nodei,
35                        long *ntips, long *parens, initops whichinit,
36                        pointarray treenode, pointarray nodep, Char *str,
37                        Char *ch, FILE *intree)
38{
39  /* initializes a node */
40  long i;
41  char c;
42  boolean minusread;
43  double valyew, divisor, fracchange;
44
45  switch (whichinit) {
46  case bottom:
47    gnu(grbg, p);
48    (*p)->index = nodei;
49    (*p)->tip = false;
50    for (i=0; i<MAXNCH; i++)
51      (*p)->nayme[i] = '\0';
52    nodep[(*p)->index - 1] = (*p);
53    break;
54  case nonbottom:
55    gnu(grbg, p);
56    (*p)->index = nodei;
57    break;
58  case tip:
59    (*ntips)++;
60    gnu(grbg, p);
61    nodep[(*ntips) - 1] = *p;
62    setupnode(*p, *ntips);
63    (*p)->tip = true;
64    strncpy ((*p)->nayme, str, MAXNCH);
65    if (firsttree && prntsets) {
66      fprintf(outfile, "  %ld. ", *ntips);
67      for (i = 0; i < len; i++)
68        putc(str[i], outfile);
69      putc('\n', outfile);
70      if ((*ntips > 0) && (((*ntips) % 10) == 0))
71        putc('\n', outfile);
72    }
73    break;
74  case length:
75    processlength(&valyew, &divisor, ch, &minusread, intree, parens);
76    fracchange = 1.0;
77    (*p)->v = valyew / divisor / fracchange;
78    break;
79  case treewt:
80    if (!eoln(intree)) {
81      fscanf(intree, "%lf", &trweight);
82      getch(ch, parens, intree);
83      if (*ch != ']') {
84        printf("\n\nERROR: Missing right square bracket\n\n");
85        exxit(-1);
86      } else {
87        getch(ch, parens, intree);
88        if (*ch != ';') {
89          printf("\n\nERROR: Missing semicolon after square brackets\n\n");
90          exxit(-1);
91        }
92      }
93    }
94    break;
95  case unittrwt:
96    /* This comes not only when seting trweight but also at the end of
97     * any tree. The following code saves the current position in a
98     * file and reads to a new line. If there is a new line then we're
99     * at the end of tree, otherwise warn the user. This function should
100     * really leave the file alone, so once we're done with 'intree'
101     * we seek the position back so that it doesn't look like we did
102     * anything */
103    trweight = 1.0 ;
104    i = ftell (intree);
105    c = ' ';
106    while (c == ' ')  {
107        if (eoff(intree)) {
108                fseek(intree,i,SEEK_SET);
109                return;
110        }
111        c = gettc(intree);
112    }
113    fseek(intree,i,SEEK_SET);
114    if ( c != '\n')
115      printf("WARNING: Tree weight set to 1.0\n");
116    break;
117  default:                /* cases hslength, iter, hsnolength      */ 
118    break;                /* should there be an error message here?*/
119  }
120} /* initconsnode */
121
122
123void censor(void)
124{
125  /* delete groups that are too rare to be in the consensus tree */
126  long i;
127
128  i = 1;
129  do {
130    if (timesseen[i-1])
131      if (!(mre || (mr && (2*(*timesseen[i-1]) > ntrees))
132                || (ml && ((*timesseen[i-1]) > mlfrac*ntrees))
133                || (strict && ((*timesseen[i-1]) == ntrees)))) {
134        free(grouping[i - 1]);
135        free(timesseen[i - 1]);
136        grouping[i - 1] = NULL;
137        timesseen[i - 1] = NULL;
138    }
139    i++;
140  } while (i < maxgrp);
141} /* censor */
142
143
144void compress(long *n)
145{
146  /* push all the nonempty subsets to the front end of their array */
147  long i, j;
148
149  i = 1;
150  j = 1;
151  do {
152    while (grouping[i - 1] != NULL)
153      i++;
154    if (j <= i)
155      j = i + 1;
156    while ((grouping[j - 1] == NULL) && (j < maxgrp))
157      j++;
158    if (j < maxgrp) {
159      grouping[i - 1] = (group_type *)Malloc(setsz * sizeof(group_type));
160      timesseen[i - 1] = (double *)Malloc(sizeof(double));
161      memcpy(grouping[i - 1], grouping[j - 1], setsz * sizeof(group_type));
162      *timesseen[i - 1] = *timesseen[j - 1];
163      free(grouping[j - 1]);
164      free(timesseen[j - 1]);
165      grouping[j - 1] = NULL;
166      timesseen[j - 1] = NULL;
167    }
168  } while (j != maxgrp);
169  (*n) = i - 1;
170}  /* compress */
171
172
173void sort(long n)
174{
175  /* Shell sort keeping grouping, timesseen in same order */
176  long gap, i, j;
177  group_type *stemp;
178  double rtemp;
179
180  gap = n / 2;
181  stemp = (group_type *)Malloc(setsz * sizeof(group_type));
182  while (gap > 0) {
183    for (i = gap + 1; i <= n; i++) {
184      j = i - gap;
185      while (j > 0) {
186        if (*timesseen[j - 1] < *timesseen[j + gap - 1]) {
187          memcpy(stemp, grouping[j - 1], setsz * sizeof(group_type));
188          memcpy(grouping[j - 1], grouping[j + gap - 1], setsz * sizeof(group_type));
189          memcpy(grouping[j + gap - 1], stemp, setsz * sizeof(group_type));
190          rtemp = *timesseen[j - 1];
191          *timesseen[j - 1] = *timesseen[j + gap - 1];
192          *timesseen[j + gap - 1] = rtemp;
193        }
194        j -= gap;
195      }
196    }
197    gap /= 2;
198  }
199  free(stemp);
200}  /* sort */
201
202
203boolean compatible(long i, long j)
204{
205  /* are groups i and j compatible? */
206  boolean comp;
207  long k;
208
209  comp = true;
210  for (k = 0; k < setsz; k++)
211    if ((grouping[i][k] & grouping[j][k]) != 0)
212      comp = false;
213  if (!comp) {
214    comp = true;
215    for (k = 0; k < setsz; k++)
216      if ((grouping[i][k] & ~grouping[j][k]) != 0)
217        comp = false;
218    if (!comp) {
219      comp = true;
220      for (k = 0; k < setsz; k++)
221        if ((grouping[j][k] & ~grouping[i][k]) != 0)
222          comp = false;
223      if (!comp) {
224        comp = noroot;
225        if (comp) {
226          for (k = 0; k < setsz; k++)
227            if ((fullset[k] & ~grouping[i][k] & ~grouping[j][k]) != 0)
228              comp = false;
229        }
230      }
231    }
232  }
233  return comp;
234} /* compatible */
235
236
237void eliminate(long *n, long *n2)
238{
239  /* eliminate groups incompatible with preceding ones */
240  long i, j, k;
241  boolean comp;
242
243  for (i = 2; i <= (*n); i++) {
244    comp = true;
245    for (j = 0; comp && (j <= i - 2); j++) {
246      if ((timesseen[j] != NULL) && *timesseen[j] > 0) {
247        comp = compatible(i-1,j);
248        if (!comp) {
249          (*n2)++;
250          times2[(*n2) - 1] = (double *)Malloc(sizeof(double));
251          group2[(*n2) - 1] = (group_type *)Malloc(setsz * sizeof(group_type));
252          *times2[(*n2) - 1] = *timesseen[i - 1];
253          memcpy(group2[(*n2) - 1], grouping[i - 1], setsz * sizeof(group_type));
254          *timesseen[i - 1] = 0.0;
255          for (k = 0; k < setsz; k++)
256            grouping[i - 1][k] = 0;
257        }
258      }
259    }
260    if (*timesseen[i - 1] == 0.0) {
261      free(grouping[i - 1]);
262      free(timesseen[i -  1]);
263      timesseen[i - 1] = NULL;
264      grouping[i - 1] = NULL;
265    }
266  }
267}  /* eliminate */
268
269
270void printset(long n)
271{
272  /* print out the n sets of species */
273  long i, j, k, size;
274  boolean noneprinted;
275
276  fprintf(outfile, "\nSet (species in order)   ");
277  for (i = 1; i <= spp - 25; i++)
278    putc(' ', outfile);
279  fprintf(outfile, "  How many times out of %7.2f\n\n", ntrees);
280  noneprinted = true;
281  for (i = 0; i < n; i++) {
282    if ((timesseen[i] != NULL) && (*timesseen[i] > 0)) {
283      size = 0;
284      k = 0;
285      for (j = 1; j <= spp; j++) {
286        if (j == ((k+1)*SETBITS+1)) k++;
287        if (((1L << (j - 1 - k*SETBITS)) & grouping[i][k]) != 0)
288          size++;
289      }
290      if (size != 1 && !(noroot && size >= (spp-1))) {
291        noneprinted = false;
292        k = 0;
293        for (j = 1; j <= spp; j++) {
294          if (j == ((k+1)*SETBITS+1)) k++;
295          if (((1L << (j - 1 - k*SETBITS)) & grouping[i][k]) != 0)
296            putc('*', outfile);
297          else
298            putc('.', outfile);
299          if (j % 10 == 0)
300            putc(' ', outfile);
301        }
302        for (j = 1; j <= 23 - spp; j++)
303          putc(' ', outfile);
304        fprintf(outfile, "    %5.2f\n", *timesseen[i]);
305      }
306    }
307  }
308  if (noneprinted)
309    fprintf(outfile, " NONE\n");
310}  /* printset */
311
312
313void bigsubset(group_type *st, long n)
314{
315  /* Find a maximal subset of st among the n groupings,
316     to be the set at the base of the tree.  */
317  long i, j;
318  group_type *su;
319  boolean max, same;
320
321  su = (group_type *)Malloc(setsz * sizeof(group_type));
322  for (i = 0; i < setsz; i++)
323    su[i] = 0;
324  for (i = 0; i < n; i++) {
325    max = true;
326    for (j = 0; j < setsz; j++)
327      if ((grouping[i][j] & ~st[j]) != 0)
328        max = false;
329    if (max) {
330      same = true;
331      for (j = 0; j < setsz; j++)
332        if (grouping[i][j] != st[j])
333          same = false;
334      max = !same;
335    }
336    if (max) {
337      for (j = 0; j < setsz; j ++)
338        if ((su[j] & ~grouping[i][j]) != 0)
339          max = false;
340      if (max) {
341        same = true;
342        for (j = 0; j < setsz; j ++)
343          if (su[j] != grouping[i][j])
344            same = false;
345        max = !same;
346      }
347      if (max)
348        memcpy(su, grouping[i], setsz * sizeof(group_type));
349    }
350  }
351  memcpy(st, su, setsz * sizeof(group_type));
352  free(su);
353}  /* bigsubset */
354
355
356void recontraverse(node **p, group_type *st, long n, long *nextnode)
357{
358  /* traverse to add next node to consensus tree */
359  long i, j = 0, k = 0, l = 0;
360
361  boolean found, same = 0, zero, zero2;
362  group_type *tempset, *st2;
363  node *q, *r;
364
365  for (i = 1; i <= spp; i++) {  /* count species in set */
366    if (i == ((l+1)*SETBITS+1)) l++;
367    if (((1L << (i - 1 - l*SETBITS)) & st[l]) != 0) {
368      k++;               /* k  is the number of species in the set */
369      j = i;             /* j  is set to last species in the set */
370    }
371  }
372  if (k == 1) {           /* if only 1, set up that tip */
373    *p = nodep[j - 1];
374    (*p)->tip = true;
375    (*p)->index = j;
376    return;
377  }
378  gnu(&grbg, p);          /* otherwise make interior node */
379  (*p)->tip = false;
380  (*p)->index = *nextnode;
381  nodep[*nextnode - 1] = *p;
382  (*nextnode)++;
383  (*p)->deltav = 0.0;
384  for (i = 0; i < n; i++) { /* go through all sets */
385    same = true;            /* to find one which is this one */
386    for (j = 0; j < setsz; j++)
387      if (grouping[i][j] != st[j])
388        same = false;
389    if (same)
390      (*p)->deltav = *timesseen[i];
391  }
392  tempset = (group_type *)Malloc(setsz * sizeof(group_type));
393  memcpy(tempset, st, setsz * sizeof(group_type));
394  q = *p;
395  st2 = (group_type *)Malloc(setsz * sizeof(group_type));
396  memcpy(st2, st, setsz * sizeof(group_type));
397  zero = true;      /* having made two copies of the set ... */
398  for (j = 0; j < setsz; j++)       /* see if they are empty */
399    if (tempset[j] != 0)
400      zero = false;
401  if (!zero)
402    bigsubset(tempset, n);        /* find biggest set within it */
403  zero = zero2 = false;           /* ... tempset is that subset */
404  while (!zero && !zero2) {
405    zero = zero2 = true;
406    for (j = 0; j < setsz; j++) {
407      if (st2[j] != 0)
408        zero = false;
409      if (tempset[j] != 0)
410        zero2 = false;
411    }
412    if (!zero && !zero2) {
413      gnu(&grbg, &q->next);
414      q->next->index = q->index;
415      q = q->next;
416      q->tip = false;
417      r = *p;
418      recontraverse(&q->back, tempset, n, nextnode); /* put it on tree */
419      *p = r;
420      q->back->back = q;
421      for (j = 0; j < setsz; j++)
422        st2[j] &= ~tempset[j];     /* remove that subset from the set */
423      memcpy(tempset, st2, setsz * sizeof(group_type));  /* that becomes set */
424      found = false;
425      i = 1;
426      while (!found && i <= n) {
427        if (grouping[i - 1] != 0) {
428          same = true;
429          for (j = 0; j < setsz; j++)
430            if (grouping[i - 1][j] != tempset[j])
431              same = false;
432        }
433        if ((grouping[i - 1] != 0) && same)
434          found = true;
435        else
436          i++;
437      }
438      zero = true;
439      for (j = 0; j < setsz; j++)
440        if (tempset[j] != 0)
441          zero = false;
442      if (!zero && !found)
443        bigsubset(tempset, n);
444    }
445  }
446  q->next = *p;
447  free(tempset);
448  free(st2);
449}  /* recontraverse */
450
451
452void reconstruct(long n)
453{
454  /* reconstruct tree from the subsets */
455  long nextnode;
456  group_type *s;
457
458  nextnode = spp + 1;
459  s = (group_type *)Malloc(setsz * sizeof(group_type));
460  memcpy(s, fullset, setsz * sizeof(group_type));
461  recontraverse(&root, s, n, &nextnode);
462  free(s);
463}  /* reconstruct */
464
465
466void coordinates(node *p, long *tipy)
467{
468  /* establishes coordinates of nodes */
469  node *q, *first, *last;
470  long maxx;
471
472  if (p->tip) {
473    p->xcoord = 0;
474    p->ycoord = *tipy;
475    p->ymin = *tipy;
476    p->ymax = *tipy;
477    (*tipy) += down;
478    return;
479  }
480  q = p->next;
481  maxx = 0;
482  while (q != p) {
483    coordinates(q->back, tipy);
484    if (!q->back->tip) {
485      if (q->back->xcoord > maxx)
486        maxx = q->back->xcoord;
487    }
488    q = q->next;
489  }
490  first = p->next->back;
491  q = p;
492  while (q->next != p)
493    q = q->next;
494  last = q->back;
495  p->xcoord = maxx + OVER;
496  p->ycoord = (long)((first->ycoord + last->ycoord) / 2);
497  p->ymin = first->ymin;
498  p->ymax = last->ymax;
499}  /* coordinates */
500
501
502void drawline(long i)
503{
504  /* draws one row of the tree diagram by moving up tree */
505  node *p, *q;
506  long n, j;
507  boolean extra, done, trif;
508  node *r,  *first = NULL, *last = NULL;
509  boolean found;
510
511  p = root;
512  q = root;
513  fprintf(outfile, "  ");
514  extra = false;
515  trif = false;
516  do {
517    if (!p->tip) {
518      found = false;
519      r = p->next;
520      while (r != p && !found) {
521        if (i >= r->back->ymin && i <= r->back->ymax) {
522          q = r->back;
523          found = true;
524        } else
525          r = r->next;
526      }
527      first = p->next->back;
528      r = p;
529      while (r->next != p)
530        r = r->next;
531      last = r->back;
532    }
533    done = (p->tip || p == q);
534    n = p->xcoord - q->xcoord;
535    if (extra) {
536      n--;
537      extra = false;
538    }
539    if (q->ycoord == i && !done) {
540      if (trif)
541        putc('-', outfile);
542      else
543        putc('+', outfile);
544      trif = false;
545      if (!q->tip) {
546        for (j = 1; j <= n - 7; j++)
547          putc('-', outfile);
548        if (noroot && (root->next->next->next == root) &&
549            (((root->next->back == q) && root->next->next->back->tip)
550             || ((root->next->next->back == q) && root->next->back->tip)))
551          fprintf(outfile, "------|");
552        else {
553          if (!strict) {   /* write number of times seen */
554            if (q->deltav >= 100)
555              fprintf(outfile, "%5.1f-|", (double)q->deltav);
556            else if (q->deltav >= 10)
557              fprintf(outfile, "-%4.1f-|", (double)q->deltav);
558            else
559              fprintf(outfile, "--%3.1f-|", (double)q->deltav);
560          } else
561            fprintf(outfile, "------|");
562        }
563        extra = true;
564        trif = true;
565      } else {
566        for (j = 1; j < n; j++)
567          putc('-', outfile);
568      }
569    } else if (!p->tip && last->ycoord > i && first->ycoord < i &&
570               (i != p->ycoord || p == root)) {
571      putc('|', outfile);
572      for (j = 1; j < n; j++)
573        putc(' ', outfile);
574    } else {
575      for (j = 1; j <= n; j++)
576        putc(' ', outfile);
577      if (trif)
578        trif = false;
579    }
580    if (q != p)
581      p = q;
582  } while (!done);
583  if (p->ycoord == i && p->tip) {
584    for (j = 0; (j < MAXNCH) && (p->nayme[j] != '\0'); j++)
585      putc(p->nayme[j], outfile);
586  }
587  putc('\n', outfile);
588}  /* drawline */
589
590
591void printree()
592{
593  /* prints out diagram of the tree */
594  long i;
595  long tipy;
596
597  if (treeprint) {
598    fprintf(outfile, "\nCONSENSUS TREE:\n");
599    if (mr || mre || ml) {
600      if (noroot) {
601        fprintf(outfile, "the numbers on the branches indicate the number\n");
602 fprintf(outfile, "of times the partition of the species into the two sets\n");
603        fprintf(outfile, "which are separated by that branch occurred\n");
604      } else {
605        fprintf(outfile, "the numbers forks indicate the number\n");
606        fprintf(outfile, "of times the group consisting of the species\n");
607        fprintf(outfile, "which are to the right of that fork occurred\n");
608      }
609      fprintf(outfile, "among the trees, out of %6.2f trees\n", ntrees);
610      if (ntrees <= 1.001)
611        fprintf(outfile, "(trees had fractional weights)\n");
612    }
613    tipy = 1;
614    coordinates(root, &tipy);
615    putc('\n', outfile);
616    for (i = 1; i <= tipy - down; i++)
617      drawline(i);
618    putc('\n', outfile);
619  }
620  if (noroot) {
621    fprintf(outfile, "\n  remember:");
622    if (didreroot)
623      fprintf(outfile, " (though rerooted by outgroup)");
624    fprintf(outfile, " this is an unrooted tree!\n");
625  }
626  putc('\n', outfile);
627}  /* printree */
628
629
630void enternohash(group_type *s, long *n)
631{
632  /* if set s is already there, enter it into groupings in the next slot
633     (without hash-coding).  n is number of sets stored there and is updated */
634  long i, j;
635  boolean found;
636
637  found = false;
638  for (i = 0; i < (*n); i++) {  /* go through looking whether it is there */
639    found = true;
640    for (j = 0; j < setsz; j++) {  /* check both parts of partition */
641      found = found && (grouping[i][j] == s[j]);
642      found = found && (group2[i][j] == (fullset[j] & (~s[j])));
643    }
644    if (found)
645      break;
646  }
647  if (!found) {    /* if not, add it to the slot after the end,
648                      which must be empty */
649    grouping[i] = (group_type *)Malloc(setsz * sizeof(group_type));
650    timesseen[i] = (double *)Malloc(sizeof(double));
651    group2[i] = (group_type *)Malloc(setsz * sizeof(group_type));
652    for (j = 0; j < setsz; j++)
653      grouping[i][j] = s[j];
654    *timesseen[i] = 1;
655    (*n)++;
656  }
657} /* enternohash */
658
659
660void enterpartition (group_type *s1, long *n)
661{
662  /* try to put this partition in list of partitions.  If implied by others,
663     don't bother.  If others implied by it, replace them.  If this one
664     vacuous because only one element in s1, forget it */
665  long i, j;
666  boolean found;
667
668/* this stuff all to be rewritten but left here so pieces can be used */
669  found = false;
670  for (i = 0; i < (*n); i++) {  /* go through looking whether it is there */
671    found = true;
672    for (j = 0; j < setsz; j++) {  /* check both parts of partition */
673      found = found && (grouping[i][j] == s1[j]);
674      found = found && (group2[i][j] == (fullset[j] & (~s1[j])));
675    }
676    if (found)
677      break;
678  }
679  if (!found) {    /* if not, add it to the slot after the end,
680                      which must be empty */
681    grouping[i] = (group_type *)Malloc(setsz * sizeof(group_type));
682    timesseen[i] = (double *)Malloc(sizeof(double));
683    group2[i] = (group_type *)Malloc(setsz * sizeof(group_type));
684    for (j = 0; j < setsz; j++)
685      grouping[i][j] = s1[j];
686    *timesseen[i] = 1;
687    (*n)++;
688  }
689} /* enterpartition */
690
691
692void elimboth(long n)
693{
694  /* for Adams case: eliminate pairs of groups incompatible with each other */
695  long i, j;
696  boolean comp;
697
698  for (i = 0; i < n-1; i++) {
699    for (j = i+1; j < n; j++) {
700      comp = compatible(i,j);
701      if (!comp) {
702        *timesseen[i] = 0.0;
703        *timesseen[j] = 0.0;
704      }
705    }
706    if (*timesseen[i] == 0.0) {
707      free(grouping[i]);
708      free(timesseen[i]);
709      timesseen[i] = NULL;
710      grouping[i] = NULL;
711    }
712  }
713  if (*timesseen[n-1] == 0.0) {
714    free(grouping[n-1]);
715    free(timesseen[n-1]);
716    timesseen[n-1] = NULL;
717    grouping[n-1] = NULL;
718  }
719}  /* elimboth */
720
721
722void consensus(pattern_elm ***pattern_array, long trees_in)
723{
724  long i, n, n2, tipy;
725
726  group2 = (group_type **)  Malloc(maxgrp*sizeof(group_type *));
727  for (i = 0; i < maxgrp; i++)
728    group2[i] = NULL;
729  times2 = (double **)Malloc(maxgrp*sizeof(double *));
730  for (i = 0; i < maxgrp; i++)
731    times2[i] = NULL;
732  n2 = 0;
733  censor();                /* drop groups that are too rare */
734  compress(&n);            /* push everybody to front of array */
735  if (!strict) {           /* drop those incompatible, if any */
736    sort(n);
737    eliminate(&n, &n2);
738    compress(&n);
739    }
740  reconstruct(n);
741  tipy = 1;
742  coordinates(root, &tipy);
743  if (prntsets) {
744    fprintf(outfile, "\nSets included in the consensus tree\n");
745    printset(n);
746    for (i = 0; i < n2; i++) {
747      if (!grouping[i]) {
748        grouping[i] = (group_type *)Malloc(setsz * sizeof(group_type));
749        timesseen[i] = (double *)Malloc(sizeof(double));
750        }
751      memcpy(grouping[i], group2[i], setsz * sizeof(group_type));
752      *timesseen[i] = *times2[i];
753    }
754    n = n2;
755    fprintf(outfile, "\n\nSets NOT included in consensus tree:");
756    if (n2 == 0)
757      fprintf(outfile, " NONE\n");
758    else {
759      putc('\n', outfile);
760      printset(n);
761    }
762  }
763  putc('\n', outfile);
764  if (strict)
765    fprintf(outfile, "\nStrict consensus tree\n");
766  if (mre)
767    fprintf(outfile, "\nExtended majority rule consensus tree\n");
768  if (ml) {
769    fprintf(outfile, "\nM  consensus tree (l = %4.2f)\n", mlfrac);
770    fprintf(outfile, " l\n");
771  }
772  if (mr)
773    fprintf(outfile, "\nMajority rule consensus tree\n");
774  printree();
775  free(nayme); 
776  for (i = 0; i < maxgrp; i++)
777    free(grouping[i]);
778  free(grouping);
779  for (i = 0; i < maxgrp; i++)
780    free(order[i]);
781  free(order);
782  for (i = 0; i < maxgrp; i++)
783    if (timesseen[i] != NULL)
784      free(timesseen[i]);
785  free(timesseen);
786}  /* consensus */
787
788
789void rehash()
790{
791  group_type *s;
792  long i, j, k;
793  double temp, ss, smult;
794  boolean done;
795
796  smult = (sqrt(5.0) - 1) / 2;
797  s = (group_type *)Malloc(setsz * sizeof(group_type));
798  for (i = 0; i < maxgrp/2; i++) {
799    k = *order[i];
800    memcpy(s, grouping[k], setsz * sizeof(group_type));
801    ss = 0.0;
802    for (j = 0; j < setsz; j++)
803      ss += s[j] /* pow(2, SETBITS*j)*/;
804    temp = ss * smult;
805    j = (long)(maxgrp * (temp - floor(temp)));
806    done = false;
807    while (!done) {
808      if (!grping2[j]) {
809        grping2[j] = (group_type *)Malloc(setsz * sizeof(group_type));
810        order2[i] = (long *)Malloc(sizeof(long));
811        tmseen2[j] = (double *)Malloc(sizeof(double));
812        memcpy(grping2[j], grouping[k], setsz * sizeof(group_type));
813        *tmseen2[j] = *timesseen[k];
814        *order2[i] = j;
815        grouping[k] = NULL;
816        timesseen[k] = NULL;
817        order[i] = NULL;
818        done = true;
819      } else {
820        j++;
821        if (j >= maxgrp) j -= maxgrp;
822      }
823    }
824  }
825  free(s);
826}  /* rehash */
827
828
829void enternodeset(node *r)
830{ /* enter a the set of species from a node into the hash table */
831  group_type *s;
832
833  s = (group_type *)Malloc(setsz * sizeof(group_type));
834  memcpy(s, r->nodeset, setsz * sizeof(group_type));
835  enterset(s);
836  free(s);
837} /* enternodeset */
838
839
840void enterset(group_type *s)
841{ /* enter a set of species into the hash table */
842  long i, j, start;
843  double ss, n;
844  boolean done, same;
845  double times ;
846
847  same = true;
848  for (i = 0; i < setsz; i++)
849    if (s[i] != fullset[i])
850      same = false;
851  if (same) 
852    return;
853  times = trweight;
854  ss = 0.0;                        /* compute the hashcode for the set */
855  n = ((sqrt(5.0) - 1.0) / 2.0);   /* use an irrational multiplier */
856  for (i = 0; i < setsz; i++)
857    ss += s[i] * n;
858  i = (long)(maxgrp * (ss - floor(ss))) + 1; /* use fractional part of code */
859  start = i;
860  done = false;                   /* go through seeing if it is there */
861  while (!done) {
862    if (grouping[i - 1]) {        /* ... i.e. if group is absent, or  */
863      same = false;               /* (will be false if timesseen = 0) */
864      if (!(timesseen[i-1] == 0)) {  /* ... if timesseen = 0 */
865        same = true;
866        for (j = 0; j < setsz; j++) {
867          if (s[j] != grouping[i - 1][j])
868            same = false;
869        }
870      }
871    }
872    if (grouping[i - 1] && same) {  /* if it is there, increment timesseen */
873      *timesseen[i - 1] += times;
874      done = true;
875    } else if (!grouping[i - 1]) {  /* if not there and slot empty ... */
876      grouping[i - 1] = (group_type *)Malloc(setsz * sizeof(group_type));
877      lasti++;
878      order[lasti] = (long *)Malloc(sizeof(long));
879      timesseen[i - 1] = (double *)Malloc(sizeof(double));
880      memcpy(grouping[i - 1], s, setsz * sizeof(group_type));
881      *timesseen[i - 1] = times;
882      *order[lasti] = i - 1;
883      done = true;
884    } else {  /* otherwise look to put it in next slot ... */
885      i++;
886      if (i > maxgrp) i -= maxgrp;
887    }
888    if (!done && i == start) {  /* if no place to put it, expand hash table */
889      maxgrp = maxgrp*2;
890      tmseen2 = (double **)Malloc(maxgrp*sizeof(double *));
891      for (j = 0; j < maxgrp; j++)
892        tmseen2[j] = NULL;
893      grping2 = (group_type **)Malloc(maxgrp*sizeof(group_type *));
894      for (j = 0; j < maxgrp; j++)
895        grping2[j] = NULL;
896      order2 = (long **)Malloc(maxgrp*sizeof(long *));
897      for (j = 0; j < maxgrp; j++)
898        order2[j] = NULL;
899      rehash();
900      free(timesseen);
901      free(grouping);
902      free(order);
903      timesseen = tmseen2;
904      grouping = grping2;
905      order = order2;
906      done = true;
907      lasti = maxgrp/2 - 1;
908      enterset(s);
909    }
910  }
911}  /* enterset */
912
913
914void accumulate(node *r_)
915{
916  node *r;
917  node *q;
918  long i;
919
920  r = r_;
921  if (r->tip) {
922    if (!r->nodeset)
923      r->nodeset = (group_type *)Malloc(setsz * sizeof(group_type));
924    for (i = 0; i < setsz; i++)
925      r->nodeset[i] = 0L;
926    i = (r->index-1) / (long)SETBITS;
927    r->nodeset[i] = 1L << (r->index - 1 - i*SETBITS);
928  }
929  else {
930    q = r->next;
931    while (q != r) {
932      accumulate(q->back);
933      q = q->next;
934    }
935    q = r->next;
936    if (!r->nodeset)
937      r->nodeset = (group_type *)Malloc(setsz * sizeof(group_type));
938    for (i = 0; i < setsz; i++)
939      r->nodeset[i] = 0;
940    while (q != r) {
941      for (i = 0; i < setsz; i++)
942        r->nodeset[i] |= q->back->nodeset[i];
943      q = q->next;
944    }
945  }
946  if ((!r->tip && (r->next->next != r)) || r->tip)
947    enternodeset(r);
948}  /* accumulate */
949
950
951void dupname2(Char *name, node *p, node *this)
952{
953  /* search for a duplicate name recursively */
954  node *q;
955
956  if (p->tip) {
957    if (p != this) {
958     
959      if (strcmp(name,p->nayme) == 0) {
960        printf("\n\nERROR in user tree: duplicate name found: ");
961        puts(p->nayme);
962        printf("\n\n");
963        exxit(-1);
964      }
965    }
966  } else {
967    q = p;
968    while (p->next != q) {
969      dupname2(name, p->next->back, this);
970      p = p->next;
971    }
972  }
973}  /* dupname2 */
974
975
976void dupname(node *p)
977{
978  /* search for a duplicate name in tree */
979  node *q;
980
981  if (p->tip)
982    dupname2(p->nayme, root, p);
983  else {
984    q = p;
985    while (p->next != q) {
986      dupname(p->next->back);
987      p = p->next;
988    }
989  }
990}  /* dupname */
991
992
993void gdispose(node *p)
994{
995  /* go through tree throwing away nodes */
996  node *q, *r;
997
998  if (p->tip) {
999    chuck(&grbg, p);
1000    return;
1001  }
1002  q = p->next;
1003  while (q != p) {
1004    gdispose(q->back);
1005    r = q;
1006    q = q->next;
1007    chuck(&grbg, r);
1008  }
1009  chuck(&grbg, q);
1010}  /* gdispose */
1011
1012
1013void initreenode(node *p)
1014{
1015  /* traverse tree and assign species names to tip nodes */
1016  node *q;
1017
1018  if (p->tip) {
1019    memcpy(nayme[p->index - 1], p->nayme, MAXNCH);
1020  } else {
1021    q = p->next;
1022    while (q && q != p) {
1023      initreenode(q->back);
1024      q = q->next;
1025    }
1026  }
1027} /* initreenode */
1028
1029
1030void reroot(node *outgroup, long *nextnode)
1031{
1032  /* reorients tree, putting outgroup in desired position. */
1033  long i;
1034  boolean nroot;
1035  node *p, *q;
1036
1037  nroot = false;
1038  p = root->next;
1039  while (p != root) {
1040    if ((outgroup->back == p) && (root->next->next->next == root)) {
1041      nroot = true;
1042      p = root;
1043    } else
1044      p = p->next;
1045  }
1046  if (nroot)
1047    return;
1048  p = root;
1049  i = 0;
1050  while (p->next != root) {
1051    p = p->next;
1052    i++;
1053  }
1054  if (i == 2) {
1055    root->next->back->back = p->back;
1056    p->back->back = root->next->back;
1057    q = root->next;
1058  } else {
1059    p->next = root->next;
1060    nodep[root->index-1] = root->next;
1061    gnu(&grbg, &root->next);
1062    q = root->next;
1063    gnu(&grbg, &q->next);
1064    p = q->next;
1065    p->next = root;
1066    q->tip = false;
1067    p->tip = false;
1068    nodep[*nextnode] = root;
1069    (*nextnode)++;
1070    root->index = *nextnode;
1071    root->next->index = root->index;
1072    root->next->next->index = root->index;
1073  }
1074  q->back = outgroup;
1075  p->back = outgroup->back;
1076  outgroup->back->back = p;
1077  outgroup->back = q;
1078}  /* reroot */
1079
1080
1081void store_pattern (pattern_elm ***pattern_array,
1082                        double *timesseen_changes, int trees_in_file)
1083{ 
1084  /* put a tree's groups into a pattern array.
1085     Don't forget that when not Adams, grouping[] is not compressed. . . */
1086  long i, total_groups=0, j=0, k;
1087
1088  /* First, find out how many groups exist in the given tree. */
1089  for (i = 0 ; i < maxgrp ; i++)
1090    if ((grouping[i] != NULL) &&
1091       (*timesseen[i] > timesseen_changes[i]))
1092      /* If this is group exists and is present in the current tree, */
1093      total_groups++ ;
1094
1095  /* Then allocate a space to store the bit patterns. . . */
1096  for (i = 0 ; i < setsz ; i++) {
1097    pattern_array[i][trees_in_file]
1098      = (pattern_elm *) Malloc(sizeof(pattern_elm)) ;
1099    pattern_array[i][trees_in_file]->apattern = 
1100      (group_type *) Malloc (total_groups * sizeof (group_type)) ;
1101    pattern_array[i][trees_in_file]->patternsize = (long *)Malloc(sizeof(long));
1102  }
1103  /* Then go through groupings again, and copy in each element
1104     appropriately. */
1105  for (i = 0 ; i < maxgrp ; i++)
1106    if (grouping[i] != NULL)
1107      if (*timesseen[i] > timesseen_changes[i]) {
1108        for (k = 0 ; k < setsz ; k++)
1109          pattern_array[k][trees_in_file]->apattern[j] = grouping[i][k] ; 
1110        j++ ;
1111        timesseen_changes[i] = *timesseen[i] ;
1112      }
1113  *pattern_array[0][trees_in_file]->patternsize = total_groups;
1114}  /* store_pattern */
1115
1116
1117boolean samename(naym name1, plotstring name2)
1118{
1119  return !(strncmp(name1, name2, MAXNCH)); 
1120}  /* samename */
1121
1122
1123void reordertips()
1124{
1125  /* matchs tip nodes to species names first read in */
1126  long i, j;
1127  boolean done;
1128  node *p, *q, *r;
1129  for (i = 0;  i < spp; i++) {
1130    j = 0;
1131    done = false;
1132    do {
1133      if (samename(nayme[i], nodep[j]->nayme)) {
1134        done =  true;
1135        if (i != j) {
1136          p = nodep[i];
1137          q = nodep[j];
1138          r = p->back;
1139          p->back->back = q;
1140          q->back->back = p;
1141          p->back =  q->back;
1142          q->back = r;
1143          memcpy(q->nayme, p->nayme, MAXNCH);
1144          memcpy(p->nayme, nayme[i], MAXNCH);
1145        }
1146      }
1147      j++;
1148    } while (j < spp && !done);
1149  }
1150}  /* reordertips */
1151
1152
1153void read_groups (pattern_elm ****pattern_array,double *timesseen_changes,
1154                        long *trees_in_1, FILE *intree)
1155{
1156  /* read the trees.  Accumulate sets. */
1157  int i, j, k;
1158  boolean haslengths, initial;
1159  long nextnode;
1160
1161  /* set up the groupings array and the timesseen array */
1162  grouping  = (group_type **)  Malloc(maxgrp*sizeof(group_type *));
1163  for (i = 0; i < maxgrp; i++)
1164    grouping[i] = NULL;
1165  order     = (long **) Malloc(maxgrp*sizeof(long *));
1166  for (i = 0; i < maxgrp; i++)
1167    order[i] = NULL;
1168  timesseen = (double **)Malloc(maxgrp*sizeof(double *));
1169  for (i = 0; i < maxgrp; i++)
1170    timesseen[i] = NULL;
1171
1172  firsttree = true;
1173  grbg = NULL;
1174  initial = true;
1175  while (!eoff(intree)) {          /* go till end of input tree file */
1176    goteof = false;
1177    nextnode = 0;
1178    haslengths = false;
1179    allocate_nodep(&nodep, &intree, &spp);
1180    if (firsttree)
1181      nayme = (naym *)Malloc(spp*sizeof(naym));
1182    treeread(intree, &root, treenode, &goteof, &firsttree, nodep, 
1183              &nextnode, &haslengths, &grbg, initconsnode);
1184    if (!initial) { 
1185      reordertips();
1186    } else {
1187      initial = false;
1188      dupname(root);
1189      initreenode(root);
1190      setsz = (long)ceil((double)spp/(double)SETBITS);
1191      if (tree_pairing != NO_PAIRING)
1192        {
1193          /* Now that we know setsz, we can malloc pattern_array
1194          and pattern_array[n] accordingly. */
1195          (*pattern_array) =
1196            (pattern_elm ***)Malloc(setsz * sizeof(pattern_elm **));
1197
1198          /* For this assignment, let's assume that there will be no
1199             more than maxtrees. */
1200          for (j = 0 ; j < setsz ; j++)
1201            (*pattern_array)[j] = 
1202              (pattern_elm **)Malloc(maxtrees * sizeof(pattern_elm *)) ;
1203        }
1204
1205      fullset = (group_type *)Malloc(setsz * sizeof(group_type));
1206      for (j = 0; j < setsz; j++)
1207        fullset[j] = 0L;
1208      k = 0;
1209      for (j = 1; j <= spp; j++) {
1210        if (j == ((k+1)*SETBITS+1)) k++;
1211        fullset[k] |= 1L << (j - k*SETBITS - 1);
1212      }
1213    }
1214    if (goteof)
1215      continue;
1216    ntrees += trweight;
1217    if (noroot) {
1218      reroot(nodep[outgrno - 1], &nextnode);
1219      didreroot = outgropt;
1220    }
1221    accumulate(root);
1222    gdispose(root);
1223    for (j = 0; j < 2*(1+spp); j++)
1224      nodep[j] = NULL;
1225    free(nodep);
1226    /* Added by Dan F. */
1227    if (tree_pairing != NO_PAIRING) {
1228        /* If we're computing pairing or need separate tree sets, store the
1229           current pattern as an element of it's trees array. */
1230        store_pattern ((*pattern_array), timesseen_changes, (*trees_in_1)) ;
1231        (*trees_in_1)++ ;
1232    }
1233  }
1234} /* read_groups */
1235
1236
Note: See TracBrowser for help on using the repository browser.