6 Char outfilename[FNMLNGTH], intreename[FNMLNGTH], intree2name[FNMLNGTH], outtreename[FNMLNGTH];
9 long numopts, outgrno, col, setsz;
10 long maxgrp; /* max. no. of groups in all trees found */
12 boolean trout, firsttree, noroot, outgropt, didreroot, prntsets,
13 progress, treeprint, goteof, strict, mr=false, mre=false,
14 ml=false; /* initialized all false for Treedist */
17 group_type **grouping, **grping2, **group2;/* to store groups found */
18 double *lengths, *lengths2;
19 long **order, **order2, lasti;
24 double **timesseen, **tmseen2, **times2 ;
25 double trweight, ntrees, mlfrac;
29 boolean compatible(long, long);
31 void enternohash(group_type*, long*);
32 void enterpartition (group_type*, long*);
33 void reorient(node* n);
35 /* begin hash table code */
37 #define NUM_BUCKETS 100
39 typedef struct namenode {
40 struct namenode *next;
45 typedef namenode **hashtype;
49 long namesGetBucket(plotstring);
50 void namesAdd(plotstring);
51 boolean namesSearch(plotstring);
52 void namesDelete(plotstring);
53 void namesClearTable(void);
54 void namesCheckTable(void);
55 void missingnameRecurs(node *p);
58 * namesGetBucket - return the bucket for a given name
60 long namesGetBucket(plotstring searchname) {
64 for (i = 0; (i < MAXNCH) && (searchname[i] != '\0'); i++) {
67 return (sum % NUM_BUCKETS);
72 * namesAdd - add a name to the hash table
74 * The argument is added at the head of the appropriate linked list. No
75 * checking is done for duplicates. The caller can call
76 * namesSearch to check for an existing name prior to calling
79 void namesAdd(plotstring addname) {
80 long bucket = namesGetBucket(addname);
84 hashp[bucket] = (namenode *)Malloc(sizeof(namenode));
86 strcpy(hp->naym, addname);
92 * namesSearch - search for a name in the hash table
94 * Return true if the name is found, else false.
96 boolean namesSearch(plotstring searchname) {
97 long i = namesGetBucket(searchname);
105 if (strcmp(searchname,p->naym) == 0) {
116 * Go through hash table and check that the hit count on all entries is one.
117 * If it is zero, then a species was missed, if it is two, then there is a
121 void namesCheckTable(void) {
125 for (i=0; i< NUM_BUCKETS; i++) {
129 printf("\n\nERROR in user tree: duplicate name found: ");
133 } else if(p->hitCount == 0){
134 printf("\n\nERROR in user tree: name %s not found\n\n\n",
145 * namesClearTable - empty names out of the table and
146 * return allocated memory
148 void namesClearTable(void) {
152 for (i=0; i< NUM_BUCKETS; i++) {
164 /* end hash table code */
166 void initconsnode(node **p, node **grbg, node *q, long len, long nodei,
167 long *ntips, long *parens, initops whichinit,
168 pointarray treenode, pointarray nodep, Char *str,
169 Char *ch, FILE *intree)
171 /* initializes a node */
175 double valyew, divisor, fracchange;
182 for (i=0; i<MAXNCH; i++)
183 (*p)->nayme[i] = '\0';
184 nodep[(*p)->index - 1] = (*p);
195 nodep[(*ntips) - 1] = *p;
196 setupnode(*p, *ntips);
198 strncpy ((*p)->nayme, str, MAXNCH);
199 if (firsttree && prntsets) {
200 fprintf(outfile, " %ld. ", *ntips);
201 for (i = 0; i < len; i++)
202 putc(str[i], outfile);
204 if ((*ntips > 0) && (((*ntips) % 10) == 0))
210 processlength(&valyew, &divisor, ch, &minusread, intree, parens);
212 (*p)->v = valyew / divisor / fracchange;
216 fscanf(intree, "%lf", &trweight);
217 getch(ch, parens, intree);
219 printf("\n\nERROR: Missing right square bracket\n\n");
222 getch(ch, parens, intree);
224 printf("\n\nERROR: Missing semicolon after square brackets\n\n");
231 /* This comes not only when setting trweight but also at the end of
232 * any tree. The following code saves the current position in a
233 * file and reads to a new line. If there is a new line then we're
234 * at the end of tree, otherwise warn the user. This function should
235 * really leave the file alone, so once we're done with 'intree'
236 * we seek the position back so that it doesn't look like we did
243 fseek(intree,i,SEEK_SET);
248 fseek(intree,i,SEEK_SET);
249 if ( c != '\n' && c!= '\r')
250 printf("WARNING: Tree weight set to 1.0\n");
252 if ( (c == gettc(intree)) != '\n')
256 (*p)->v = -1; /* signal value that a length is missing */
258 default: /* cases hslength, iter, hsnolength */
259 break; /* should there be an error message here?*/
266 /* delete groups that are too rare to be in the consensus tree */
272 if (!(mre || (mr && (2*(*timesseen[i-1]) > ntrees))
273 || (ml && ((*timesseen[i-1]) > mlfrac*ntrees))
274 || (strict && ((*timesseen[i-1]) == ntrees)))) {
275 free(grouping[i - 1]);
276 free(timesseen[i - 1]);
277 grouping[i - 1] = NULL;
278 timesseen[i - 1] = NULL;
281 } while (i < maxgrp);
285 void compress(long *n)
287 /* push all the nonempty subsets to the front end of their array */
293 while (grouping[i - 1] != NULL)
297 while ((grouping[j - 1] == NULL) && (j < maxgrp))
300 grouping[i - 1] = (group_type *)Malloc(setsz * sizeof(group_type));
301 timesseen[i - 1] = (double *)Malloc(sizeof(double));
302 memcpy(grouping[i - 1], grouping[j - 1], setsz * sizeof(group_type));
303 *timesseen[i - 1] = *timesseen[j - 1];
304 free(grouping[j - 1]);
305 free(timesseen[j - 1]);
306 grouping[j - 1] = NULL;
307 timesseen[j - 1] = NULL;
309 } while (j != maxgrp);
316 /* Shell sort keeping grouping, timesseen in same order */
322 stemp = (group_type *)Malloc(setsz * sizeof(group_type));
324 for (i = gap + 1; i <= n; i++) {
327 if (*timesseen[j - 1] < *timesseen[j + gap - 1]) {
328 memcpy(stemp, grouping[j - 1], setsz * sizeof(group_type));
329 memcpy(grouping[j - 1], grouping[j + gap - 1], setsz * sizeof(group_type));
330 memcpy(grouping[j + gap - 1], stemp, setsz * sizeof(group_type));
331 rtemp = *timesseen[j - 1];
332 *timesseen[j - 1] = *timesseen[j + gap - 1];
333 *timesseen[j + gap - 1] = rtemp;
344 boolean compatible(long i, long j)
346 /* are groups i and j compatible? */
351 for (k = 0; k < setsz; k++)
352 if ((grouping[i][k] & grouping[j][k]) != 0)
356 for (k = 0; k < setsz; k++)
357 if ((grouping[i][k] & ~grouping[j][k]) != 0)
361 for (k = 0; k < setsz; k++)
362 if ((grouping[j][k] & ~grouping[i][k]) != 0)
367 for (k = 0; k < setsz; k++)
368 if ((fullset[k] & ~grouping[i][k] & ~grouping[j][k]) != 0)
378 void eliminate(long *n, long *n2)
380 /* eliminate groups incompatible with preceding ones */
384 for (i = 2; i <= (*n); i++) {
386 for (j = 0; comp && (j <= i - 2); j++) {
387 if ((timesseen[j] != NULL) && *timesseen[j] > 0) {
388 comp = compatible(i-1,j);
391 times2[(*n2) - 1] = (double *)Malloc(sizeof(double));
392 group2[(*n2) - 1] = (group_type *)Malloc(setsz * sizeof(group_type));
393 *times2[(*n2) - 1] = *timesseen[i - 1];
394 memcpy(group2[(*n2) - 1], grouping[i - 1], setsz * sizeof(group_type));
395 *timesseen[i - 1] = 0.0;
396 for (k = 0; k < setsz; k++)
397 grouping[i - 1][k] = 0;
401 if (*timesseen[i - 1] == 0.0) {
402 free(grouping[i - 1]);
403 free(timesseen[i - 1]);
404 timesseen[i - 1] = NULL;
405 grouping[i - 1] = NULL;
411 void printset(long n)
413 /* print out the n sets of species */
417 fprintf(outfile, "\nSet (species in order) ");
418 for (i = 1; i <= spp - 25; i++)
420 fprintf(outfile, " How many times out of %7.2f\n\n", ntrees);
422 for (i = 0; i < n; i++) {
423 if ((timesseen[i] != NULL) && (*timesseen[i] > 0)) {
426 for (j = 1; j <= spp; j++) {
427 if (j == ((k+1)*SETBITS+1)) k++;
428 if (((1L << (j - 1 - k*SETBITS)) & grouping[i][k]) != 0)
431 if (size != 1 && !(noroot && size >= (spp-1))) {
434 for (j = 1; j <= spp; j++) {
435 if (j == ((k+1)*SETBITS+1)) k++;
436 if (((1L << (j - 1 - k*SETBITS)) & grouping[i][k]) != 0)
443 for (j = 1; j <= 23 - spp; j++)
445 fprintf(outfile, " %5.2f\n", *timesseen[i]);
450 fprintf(outfile, " NONE\n");
454 void bigsubset(group_type *st, long n)
456 /* Find a maximal subset of st among the n groupings,
457 to be the set at the base of the tree. */
462 su = (group_type *)Malloc(setsz * sizeof(group_type));
463 for (i = 0; i < setsz; i++)
465 for (i = 0; i < n; i++) {
467 for (j = 0; j < setsz; j++)
468 if ((grouping[i][j] & ~st[j]) != 0)
472 for (j = 0; j < setsz; j++)
473 if (grouping[i][j] != st[j])
478 for (j = 0; j < setsz; j ++)
479 if ((su[j] & ~grouping[i][j]) != 0)
483 for (j = 0; j < setsz; j ++)
484 if (su[j] != grouping[i][j])
489 memcpy(su, grouping[i], setsz * sizeof(group_type));
492 memcpy(st, su, setsz * sizeof(group_type));
497 void recontraverse(node **p, group_type *st, long n, long *nextnode)
499 /* traverse to add next node to consensus tree */
500 long i, j = 0, k = 0, l = 0;
502 boolean found, same = 0, zero, zero2;
503 group_type *tempset, *st2;
506 for (i = 1; i <= spp; i++) { /* count species in set */
507 if (i == ((l+1)*SETBITS+1)) l++;
508 if (((1L << (i - 1 - l*SETBITS)) & st[l]) != 0) {
509 k++; /* k is the number of species in the set */
510 j = i; /* j is set to last species in the set */
513 if (k == 1) { /* if only 1, set up that tip */
519 gnu(&grbg, p); /* otherwise make interior node */
521 (*p)->index = *nextnode;
522 nodep[*nextnode - 1] = *p;
525 for (i = 0; i < n; i++) { /* go through all sets */
526 same = true; /* to find one which is this one */
527 for (j = 0; j < setsz; j++)
528 if (grouping[i][j] != st[j])
531 (*p)->deltav = *timesseen[i];
533 tempset = (group_type *)Malloc(setsz * sizeof(group_type));
534 memcpy(tempset, st, setsz * sizeof(group_type));
536 st2 = (group_type *)Malloc(setsz * sizeof(group_type));
537 memcpy(st2, st, setsz * sizeof(group_type));
538 zero = true; /* having made two copies of the set ... */
539 for (j = 0; j < setsz; j++) /* see if they are empty */
543 bigsubset(tempset, n); /* find biggest set within it */
544 zero = zero2 = false; /* ... tempset is that subset */
545 while (!zero && !zero2) {
547 for (j = 0; j < setsz; j++) {
553 if (!zero && !zero2) {
554 gnu(&grbg, &q->next);
555 q->next->index = q->index;
559 recontraverse(&q->back, tempset, n, nextnode); /* put it on tree */
562 for (j = 0; j < setsz; j++)
563 st2[j] &= ~tempset[j]; /* remove that subset from the set */
564 memcpy(tempset, st2, setsz * sizeof(group_type)); /* that becomes set */
567 while (!found && i <= n) {
568 if (grouping[i - 1] != 0) {
570 for (j = 0; j < setsz; j++)
571 if (grouping[i - 1][j] != tempset[j])
574 if ((grouping[i - 1] != 0) && same)
580 for (j = 0; j < setsz; j++)
584 bigsubset(tempset, n);
590 } /* recontraverse */
593 void reconstruct(long n)
595 /* reconstruct tree from the subsets */
600 s = (group_type *)Malloc(setsz * sizeof(group_type));
601 memcpy(s, fullset, setsz * sizeof(group_type));
602 recontraverse(&root, s, n, &nextnode);
607 void coordinates(node *p, long *tipy)
609 /* establishes coordinates of nodes */
610 node *q, *first, *last;
624 coordinates(q->back, tipy);
626 if (q->back->xcoord > maxx)
627 maxx = q->back->xcoord;
631 first = p->next->back;
636 p->xcoord = maxx + OVER;
637 p->ycoord = (long)((first->ycoord + last->ycoord) / 2);
638 p->ymin = first->ymin;
639 p->ymax = last->ymax;
643 void drawline(long i)
645 /* draws one row of the tree diagram by moving up tree */
648 boolean extra, done, trif;
649 node *r, *first = NULL, *last = NULL;
654 fprintf(outfile, " ");
661 while (r != p && !found) {
662 if (i >= r->back->ymin && i <= r->back->ymax) {
668 first = p->next->back;
674 done = (p->tip || p == q);
675 n = p->xcoord - q->xcoord;
680 if (q->ycoord == i && !done) {
687 for (j = 1; j <= n - 7; j++)
689 if (noroot && (root->next->next->next == root) &&
690 (((root->next->back == q) && root->next->next->back->tip)
691 || ((root->next->next->back == q) && root->next->back->tip)))
692 fprintf(outfile, "------|");
694 if (!strict) { /* write number of times seen */
695 if (q->deltav >= 100)
696 fprintf(outfile, "%5.1f-|", (double)q->deltav);
697 else if (q->deltav >= 10)
698 fprintf(outfile, "-%4.1f-|", (double)q->deltav);
700 fprintf(outfile, "--%3.1f-|", (double)q->deltav);
702 fprintf(outfile, "------|");
707 for (j = 1; j < n; j++)
710 } else if (!p->tip && last->ycoord > i && first->ycoord < i &&
711 (i != p->ycoord || p == root)) {
713 for (j = 1; j < n; j++)
716 for (j = 1; j <= n; j++)
724 if (p->ycoord == i && p->tip) {
725 for (j = 0; (j < MAXNCH) && (p->nayme[j] != '\0'); j++)
726 putc(p->nayme[j], outfile);
734 /* prints out diagram of the tree */
739 fprintf(outfile, "\nCONSENSUS TREE:\n");
740 if (mr || mre || ml) {
742 fprintf(outfile, "the numbers on the branches indicate the number\n");
743 fprintf(outfile, "of times the partition of the species into the two sets\n");
744 fprintf(outfile, "which are separated by that branch occurred\n");
746 fprintf(outfile, "the numbers forks indicate the number\n");
747 fprintf(outfile, "of times the group consisting of the species\n");
748 fprintf(outfile, "which are to the right of that fork occurred\n");
750 fprintf(outfile, "among the trees, out of %6.2f trees\n", ntrees);
752 fprintf(outfile, "(trees had fractional weights)\n");
755 coordinates(root, &tipy);
757 for (i = 1; i <= tipy - down; i++)
762 fprintf(outfile, "\n remember:");
764 fprintf(outfile, " (though rerooted by outgroup)");
765 fprintf(outfile, " this is an unrooted tree!\n");
771 void enternohash(group_type *s, long *n)
773 /* if set s is already there, enter it into groupings in the next slot
774 (without hash-coding). n is number of sets stored there and is updated */
779 for (i = 0; i < (*n); i++) { /* go through looking whether it is there */
781 for (j = 0; j < setsz; j++) { /* check both parts of partition */
782 found = found && (grouping[i][j] == s[j]);
783 found = found && (group2[i][j] == (fullset[j] & (~s[j])));
788 if (!found) { /* if not, add it to the slot after the end,
789 which must be empty */
790 grouping[i] = (group_type *)Malloc(setsz * sizeof(group_type));
791 timesseen[i] = (double *)Malloc(sizeof(double));
792 group2[i] = (group_type *)Malloc(setsz * sizeof(group_type));
793 for (j = 0; j < setsz; j++)
794 grouping[i][j] = s[j];
801 void enterpartition (group_type *s1, long *n)
803 /* try to put this partition in list of partitions. If implied by others,
804 don't bother. If others implied by it, replace them. If this one
805 vacuous because only one element in s1, forget it */
809 /* this stuff all to be rewritten but left here so pieces can be used */
811 for (i = 0; i < (*n); i++) { /* go through looking whether it is there */
813 for (j = 0; j < setsz; j++) { /* check both parts of partition */
814 found = found && (grouping[i][j] == s1[j]);
815 found = found && (group2[i][j] == (fullset[j] & (~s1[j])));
820 if (!found) { /* if not, add it to the slot after the end,
821 which must be empty */
822 grouping[i] = (group_type *)Malloc(setsz * sizeof(group_type));
823 timesseen[i] = (double *)Malloc(sizeof(double));
824 group2[i] = (group_type *)Malloc(setsz * sizeof(group_type));
825 for (j = 0; j < setsz; j++)
826 grouping[i][j] = s1[j];
830 } /* enterpartition */
833 void elimboth(long n)
835 /* for Adams case: eliminate pairs of groups incompatible with each other */
839 for (i = 0; i < n-1; i++) {
840 for (j = i+1; j < n; j++) {
841 comp = compatible(i,j);
847 if (*timesseen[i] == 0.0) {
854 if (*timesseen[n-1] == 0.0) {
856 free(timesseen[n-1]);
857 timesseen[n-1] = NULL;
858 grouping[n-1] = NULL;
863 void consensus(pattern_elm ***pattern_array, long trees_in)
867 group2 = (group_type **) Malloc(maxgrp*sizeof(group_type *));
868 for (i = 0; i < maxgrp; i++)
870 times2 = (double **)Malloc(maxgrp*sizeof(double *));
871 for (i = 0; i < maxgrp; i++)
874 censor(); /* drop groups that are too rare */
875 compress(&n); /* push everybody to front of array */
876 if (!strict) { /* drop those incompatible, if any */
883 coordinates(root, &tipy);
885 fprintf(outfile, "\nSets included in the consensus tree\n");
887 for (i = 0; i < n2; i++) {
889 grouping[i] = (group_type *)Malloc(setsz * sizeof(group_type));
890 timesseen[i] = (double *)Malloc(sizeof(double));
892 memcpy(grouping[i], group2[i], setsz * sizeof(group_type));
893 *timesseen[i] = *times2[i];
896 fprintf(outfile, "\n\nSets NOT included in consensus tree:");
898 fprintf(outfile, " NONE\n");
906 fprintf(outfile, "\nStrict consensus tree\n");
908 fprintf(outfile, "\nExtended majority rule consensus tree\n");
910 fprintf(outfile, "\nM consensus tree (l = %4.2f)\n", mlfrac);
911 fprintf(outfile, " l\n");
914 fprintf(outfile, "\nMajority rule consensus tree\n");
917 for (i = 0; i < maxgrp; i++)
920 for (i = 0; i < maxgrp; i++)
923 for (i = 0; i < maxgrp; i++)
924 if (timesseen[i] != NULL)
934 double temp, ss, smult;
937 smult = (sqrt(5.0) - 1) / 2;
938 s = (group_type *)Malloc(setsz * sizeof(group_type));
939 for (i = 0; i < maxgrp/2; i++) {
941 memcpy(s, grouping[k], setsz * sizeof(group_type));
943 for (j = 0; j < setsz; j++)
944 ss += s[j] /* pow(2, SETBITS*j)*/;
946 j = (long)(maxgrp * (temp - floor(temp)));
950 grping2[j] = (group_type *)Malloc(setsz * sizeof(group_type));
951 order2[i] = (long *)Malloc(sizeof(long));
952 tmseen2[j] = (double *)Malloc(sizeof(double));
953 memcpy(grping2[j], grouping[k], setsz * sizeof(group_type));
954 *tmseen2[j] = *timesseen[k];
962 if (j >= maxgrp) j -= maxgrp;
970 void enternodeset(node* r)
971 { /* enter a set of species into the hash table */
980 for (i = 0; i < setsz; i++)
981 if (s[i] != fullset[i])
986 ss = 0.0; /* compute the hashcode for the set */
987 n = ((sqrt(5.0) - 1.0) / 2.0); /* use an irrational multiplier */
988 for (i = 0; i < setsz; i++)
990 i = (long)(maxgrp * (ss - floor(ss))) + 1; /* use fractional part of code */
992 done = false; /* go through seeing if it is there */
994 if (grouping[i - 1]) { /* ... i.e. if group is absent, or */
995 same = false; /* (will be false if timesseen = 0) */
996 if (!(timesseen[i-1] == 0)) { /* ... if timesseen = 0 */
998 for (j = 0; j < setsz; j++) {
999 if (s[j] != grouping[i - 1][j])
1004 if (grouping[i - 1] && same) { /* if it is there, increment timesseen */
1005 *timesseen[i - 1] += times;
1006 lengths[i - 1] = nodep[r->index - 1]->v;
1008 } else if (!grouping[i - 1]) { /* if not there and slot empty ... */
1009 grouping[i - 1] = (group_type *)Malloc(setsz * sizeof(group_type));
1011 order[lasti] = (long *)Malloc(sizeof(long));
1012 timesseen[i - 1] = (double *)Malloc(sizeof(double));
1013 memcpy(grouping[i - 1], s, setsz * sizeof(group_type));
1014 *timesseen[i - 1] = times;
1015 *order[lasti] = i - 1;
1017 lengths[i - 1] = nodep[r->index -1]->v;
1018 } else { /* otherwise look to put it in next slot ... */
1020 if (i > maxgrp) i -= maxgrp;
1022 if (!done && i == start) { /* if no place to put it, expand hash table */
1024 tmseen2 = (double **)Malloc(maxgrp*sizeof(double *));
1025 for (j = 0; j < maxgrp; j++)
1027 grping2 = (group_type **)Malloc(maxgrp*sizeof(group_type *));
1028 for (j = 0; j < maxgrp; j++)
1030 order2 = (long **)Malloc(maxgrp*sizeof(long *));
1031 for (j = 0; j < maxgrp; j++)
1033 lengths2 = (double *)Malloc(maxgrp*sizeof(double));
1034 for (j = 0; j < maxgrp; j++)
1036 memcpy(lengths2,lengths,maxgrp*sizeof(double) / 2);
1042 timesseen = tmseen2;
1047 lasti = maxgrp/2 - 1;
1051 } /* enternodeset */
1054 void accumulate(node *r)
1061 r->nodeset = (group_type *)Malloc(setsz * sizeof(group_type));
1062 for (i = 0; i < setsz; i++)
1064 i = (r->index-1) / (long)SETBITS;
1065 r->nodeset[i] = 1L << (r->index - 1 - i*SETBITS);
1070 accumulate(q->back);
1075 r->nodeset = (group_type *)Malloc(setsz * sizeof(group_type));
1076 for (i = 0; i < setsz; i++)
1079 for (i = 0; i < setsz; i++)
1080 r->nodeset[i] |= q->back->nodeset[i];
1084 if ((!r->tip && (r->next->next != r)) || r->tip)
1089 void dupname2(Char *name, node *p, node *this)
1091 /* search for a duplicate name recursively */
1096 if (namesSearch(p->nayme)) {
1097 printf("\n\nERROR in user tree: duplicate name found: ");
1107 while (p->next != q) {
1108 dupname2(name, p->next->back, this);
1115 void dupname(node *p)
1117 /* search for a duplicate name in tree */
1121 if (namesSearch(p->nayme)) {
1122 printf("\n\nERROR in user tree: duplicate name found: ");
1131 while (p->next != q) {
1132 dupname(p->next->back);
1139 void missingnameRecurs(node *p)
1141 /* search for missing names in first tree */
1145 if (!namesSearch(p->nayme)) {
1146 printf("\n\nERROR in user tree: name %s not found in first tree\n\n\n",
1152 while (p->next != q) {
1153 missingnameRecurs(p->next->back);
1157 } /* missingnameRecurs */
1160 * wrapper for recursive missingname function
1162 void missingname(node *p){
1163 missingnameRecurs(p);
1167 void gdispose(node *p)
1169 /* go through tree throwing away nodes */
1187 void initreenode(node *p)
1189 /* traverse tree and assign species names to tip nodes */
1193 memcpy(nayme[p->index - 1], p->nayme, MAXNCH);
1196 while (q && q != p) {
1197 initreenode(q->back);
1204 void reroot(node *outgroup, long *nextnode)
1206 /* reorients tree, putting outgroup in desired position. */
1215 if ((outgroup->back == p) && (root->next->next->next == root)) {
1221 if (nroot && root->next->next->next == root) {
1222 root->next->next->back->v += root->next->back->v;
1223 root->next->back->v = 0;
1229 while (p->next != root) {
1234 newv = root->next->back->v + root->next->next->back->v;
1235 root->next->back->back = p->back;
1236 p->back->back = root->next->back;
1241 p->next = root->next;
1242 nodep[root->index-1] = root->next;
1243 gnu(&grbg, &root->next);
1245 gnu(&grbg, &q->next);
1250 nodep[*nextnode] = root;
1252 root->index = *nextnode;
1253 root->next->index = root->index;
1254 root->next->next->index = root->index;
1258 p->back = outgroup->back;
1259 outgroup->back->back = p;
1262 outgroup->back->v = 0;
1270 void reorient(node* n) {
1273 if ( n->tip ) return;
1274 if ( nodep[n->index - 1] != n ) {
1275 nodep[n->index - 1] = n;
1280 for ( p = n->next ; p != n ; p = p->next)
1285 void store_pattern (pattern_elm ***pattern_array,
1286 double *timesseen_changes, int trees_in_file)
1288 /* put a tree's groups into a pattern array.
1289 Don't forget that when not Adams, grouping[] is not compressed. . . */
1290 long i, total_groups=0, j=0, k;
1292 /* First, find out how many groups exist in the given tree. */
1293 for (i = 0 ; i < maxgrp ; i++)
1294 if ((grouping[i] != NULL) &&
1295 (*timesseen[i] > timesseen_changes[i]))
1296 /* If this is group exists and is present in the current tree, */
1299 /* Then allocate a space to store the bit patterns. . . */
1300 for (i = 0 ; i < setsz ; i++) {
1301 pattern_array[i][trees_in_file]
1302 = (pattern_elm *) Malloc(sizeof(pattern_elm)) ;
1303 pattern_array[i][trees_in_file]->apattern =
1304 (group_type *) Malloc (total_groups * sizeof (group_type)) ;
1305 pattern_array[i][trees_in_file]->length =
1306 (double *) Malloc (maxgrp * sizeof (double)) ;
1307 for ( j = 0 ; j < maxgrp ; j++ ) {
1308 pattern_array[i][trees_in_file]->length[j] = -1;
1310 pattern_array[i][trees_in_file]->patternsize = (long *)Malloc(sizeof(long));
1313 /* Then go through groupings again, and copy in each element
1315 for (i = 0 ; i < maxgrp ; i++)
1316 if (grouping[i] != NULL) {
1317 if (*timesseen[i] > timesseen_changes[i]) {
1318 for (k = 0 ; k < setsz ; k++)
1319 pattern_array[k][trees_in_file]->apattern[j] = grouping[i][k] ;
1320 pattern_array[0][trees_in_file]->length[j] = lengths[i];
1322 timesseen_changes[i] = *timesseen[i] ;
1325 *pattern_array[0][trees_in_file]->patternsize = total_groups;
1326 } /* store_pattern */
1329 boolean samename(naym name1, plotstring name2)
1331 return !(strncmp(name1, name2, MAXNCH));
1337 /* matchs tip nodes to species names first read in */
1341 for (i = 0; i < spp; i++) {
1345 if (samename(nayme[i], nodep[j]->nayme)) {
1355 memcpy(q->nayme, p->nayme, MAXNCH);
1356 memcpy(p->nayme, nayme[i], MAXNCH);
1360 } while (j < spp && !done);
1365 void read_groups (pattern_elm ****pattern_array,double *timesseen_changes,
1366 long trees_in_1, long total_trees, FILE *intree)
1368 /* read the trees. Accumulate sets. */
1370 boolean haslengths, initial;
1371 long nextnode, trees_read = 0;
1373 /* set up the groupings array and the timesseen array */
1374 grouping = (group_type **) Malloc(maxgrp*sizeof(group_type *));
1375 lengths = (double *) Malloc(maxgrp*sizeof(double));
1376 for (i = 0; i < maxgrp; i++)
1378 order = (long **) Malloc(maxgrp*sizeof(long *));
1379 for (i = 0; i < maxgrp; i++)
1381 timesseen = (double **)Malloc(maxgrp*sizeof(double *));
1382 for (i = 0; i < maxgrp; i++)
1383 timesseen[i] = NULL;
1388 while (!eoff(intree)) { /* go till end of input tree file */
1389 for (i = 0; i < maxgrp; i++) {
1395 allocate_nodep(&nodep, &intree, &spp);
1397 nayme = (naym *)Malloc(spp*sizeof(naym));
1398 treeread(intree, &root, treenode, &goteof, &firsttree, nodep,
1399 &nextnode, &haslengths, &grbg, initconsnode,true,-1);
1405 hashp = (hashtype)Malloc(sizeof(namenode) * NUM_BUCKETS);
1406 for (i=0;i<NUM_BUCKETS;i++) {
1411 setsz = (long)ceil((double)spp/(double)SETBITS);
1412 if (tree_pairing != NO_PAIRING)
1414 /* Now that we know setsz, we can malloc pattern_array
1415 and pattern_array[n] accordingly. */
1417 (pattern_elm ***)Malloc(setsz * sizeof(pattern_elm **));
1419 /* For this assignment, let's assume that there will be no
1420 more than maxtrees. */
1421 for (j = 0 ; j < setsz ; j++)
1422 (*pattern_array)[j] =
1423 (pattern_elm **)Malloc(total_trees * sizeof(pattern_elm *));
1426 fullset = (group_type *)Malloc(setsz * sizeof(group_type));
1427 for (j = 0; j < setsz; j++)
1430 for (j = 1; j <= spp; j++) {
1431 if (j == ((k+1)*SETBITS+1)) k++;
1432 fullset[k] |= 1L << (j - k*SETBITS - 1);
1439 reroot(nodep[outgrno - 1], &nextnode);
1440 didreroot = outgropt;
1444 for (j = 0; j < 2*(1+spp); j++)
1447 /* Added by Dan F. */
1448 if (tree_pairing != NO_PAIRING) {
1449 /* If we're computing pairing or need separate tree sets, store the
1450 current pattern as an element of it's trees array. */
1451 store_pattern ((*pattern_array), timesseen_changes, trees_read) ;