source: trunk/GDE/PHYLIP/cons.c

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