source: branches/stable/GDE/PHYLIP/treedist.c

Last change on this file was 11060, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.6 KB
Line 
1
2#include "phylip.h"
3#include "cons.h"
4
5/* version 3.6. (c) Copyright 1993-2002 by the University of Washington.
6   Written by Dan Fineman, Joseph Felsenstein, Hisashi Horino,
7   Akiko Fuseki, Sean Lamont, and Andrew Keeffe.
8   Permission is granted to copy and use this program provided no fee
9   is charged for it and provided that this copyright notice is not removed. */
10
11long output_scheme ;
12
13extern long tree_pairing ;
14
15/* The following extern's refer to things declared in cons.c */
16
17extern Char outfilename[FNMLNGTH], intreename[FNMLNGTH], intree2name[FNMLNGTH], outtreename[FNMLNGTH];
18extern node *root;
19
20extern long numopts, outgrno, col, setsz;
21extern long maxgrp;               /* max. no. of groups in all trees found  */
22
23extern boolean trout, firsttree, noroot, outgropt, didreroot, prntsets,
24               progress, treeprint, goteof;
25extern pointarray treenode, nodep;
26extern group_type **grouping, **grping2, **group2;/* to store groups found  */
27extern long **order, **order2, lasti;
28extern group_type *fullset;
29extern node *grbg;
30extern long tipy;
31
32extern double **timesseen, **tmseen2, **times2 ;
33extern double trweight, ntrees ;
34
35#ifndef OLDC
36/* function prototpes */
37void   assign_tree(group_type **, pattern_elm ***, long, long *); 
38boolean group_is_null(group_type **, long);
39long    tree_diff(group_type **, group_type **, long, long);
40void   compute_distances(pattern_elm ***, long, long, long *);
41void   free_patterns(pattern_elm ***, long); 
42void   produce_square_matrix(long, long *);
43void   produce_full_matrix(long, long, long *);
44void   output_distances(long, long, long *); 
45void   output_submenu(void);
46void   pairing_submenu(void);
47
48void   read_second_file(pattern_elm ***, double *, long *, long *);
49void   getoptions(void);
50/* function prototpes */
51#endif
52
53
54void assign_tree(group_type **treeN, pattern_elm ***pattern_array,
55                long tree_index, long *pattern_size) 
56{ /* set treeN to be the tree_index-th tree in pattern_elm */
57  long i ;
58
59  for (i = 0 ; i < setsz ; i++)
60    {
61      treeN[i] = pattern_array[i][tree_index]->apattern ;
62    }
63  *pattern_size = *pattern_array[0][tree_index]->patternsize;
64}  /* assign_tree */
65
66
67boolean group_is_null(group_type **treeN, long index)
68{
69  /* Check to see if a given index to a tree array points to an empty
70     group */
71  long i ;
72
73  for (i = 0 ; i < setsz ; i++)
74    if (treeN[i][index] != (group_type) 0)
75      return false ;
76
77  /* If we've gotten this far, then the index is to an empty group in
78     the tree. */
79  return true ;
80}  /* group_is_null */
81
82
83long tree_diff(group_type **tree1, group_type **tree2,
84                long patternsz1, long patternsz2)
85{
86  /* Compute the symmetric difference between 2 given trees. Return
87     that value as a long. */
88
89  long index1, index2, return_value = 0 ;
90  boolean match_found ;
91  long i;
92
93  if (group_is_null (tree1, 0) || group_is_null (tree2, 0))
94    {
95      printf ("Error computing tree difference.\n") ;
96      return 0;
97    }
98
99  for (index1 = 0 ; index1 < patternsz1 ; index1++)
100    {
101      /* For every element in the first tree, see if there's
102         a match to it in the second tree. */
103      match_found = false ;
104      if (group_is_null (tree1, index1))
105        {
106          /* When we've gone over all the elements in tree1, greater
107             number of elements in tree2 will constitute that much more
108             of a difference... */
109          while (! group_is_null (tree2, index1)) 
110            {
111              return_value++ ;
112              index1++ ;
113/*              printf ("Found null group %ld, return value at %ld. . .\n",
114                      index1-1, return_value) ; */
115            }
116          break ;
117        }
118
119      for (index2 = 0 ; index2 < patternsz2 ; index2++)
120         {
121          /* For every element in the second tree, see if any match
122             the current element in the first tree. */
123          if (group_is_null (tree2, index2)) {
124              /* When we've gone over all the elements in tree2 */
125              match_found = false ;
126              break ;
127            }
128          else 
129            {
130              /* Tentatively set match_found; will be changed later if
131                 necessary. . . */
132              match_found = true ; 
133
134              for (i = 0 ; i < setsz ; i++) {
135                  /* See if we've got a match, */ 
136                  if (tree1[i][index1] != tree2[i][index2])
137                    match_found = false ;
138                }
139
140              if (match_found == true)
141                /* If the previous loop ran from 0 to setsz without setting
142                   match_found to false, */
143                break ;
144            }
145        }
146
147      if (match_found == false) {
148          return_value++ ;
149        }
150    }
151  return return_value ;
152}  /* tree_diff */
153
154
155void compute_distances(pattern_elm ***pattern_array, long trees_in_1,
156                long trees_in_2, long *diff_array)
157{
158  /* Compute symmetric distances between arrays of trees */
159  long i, tree_index, diff1, diff2, end_tree, index1, index2,
160    diff_index ;
161  group_type **treeA, **treeB ;
162  long patternsz1, patternsz2;
163
164  diff_index = 0 ;
165
166  /* Put together space for treeA and treeB */
167  treeA = (group_type **) Malloc (setsz * sizeof (group_type *)) ;
168  treeB = (group_type **) Malloc (setsz * sizeof (group_type *)) ;
169
170  for (i=0 ; i<setsz; i++) {
171    treeA[i] = (group_type *) Malloc (maxgrp * sizeof (group_type)) ;
172    treeB[i] = (group_type *) Malloc (maxgrp * sizeof (group_type)) ;
173  }
174       
175  switch (tree_pairing) {
176  case (ADJACENT_PAIRS) : 
177    end_tree = trees_in_1 - 1 ;
178    for (tree_index = 0 ; tree_index < end_tree ; tree_index += 2)
179      {
180        /* For every tree, compute the distance between it and the tree
181           at the next location; do this in both directions */
182
183        assign_tree (treeA, pattern_array, tree_index, &patternsz1) ;
184        assign_tree (treeB, pattern_array, tree_index + 1, &patternsz2) ;
185
186        diff1 = tree_diff (treeB, treeA, patternsz2, patternsz1) ;       
187        diff2 = tree_diff (treeA, treeB, patternsz1, patternsz2) ;
188        diff_array[diff_index++] = diff1 + diff2 ;
189        if (tree_index + 2 == end_tree)
190          printf("\nWARNING: extra tree at the end of input tree file.\n");
191      }
192    break ;
193
194  case (ALL_IN_FIRST) : 
195    end_tree   = trees_in_1 ;
196
197    for (index1 = 0 ; index1 < end_tree ; index1++)
198      {
199        /* For every tree, compute the distance between it and every
200           other tree in that file. */
201        assign_tree (treeA, pattern_array, index1, &patternsz1) ;
202
203        for (index2 = 0 ; index2 < end_tree ; index2++)
204          {
205            if (index1 == index2)
206              {
207                /* No need to compute the distance between a tree and
208                   itself, */
209                diff_array[diff_index++] = 0 ;
210                continue ;
211              }
212            else if (index1 > index2) 
213              {
214                /* No need to re-compute something we've already done, */
215                diff_array[diff_index++] = 
216                  diff_array[(index2 * trees_in_1) + index1] ;
217              }
218            else 
219              {
220                assign_tree (treeB, pattern_array, index2, &patternsz2) ;
221                diff1 = tree_diff (treeB, treeA, patternsz2, patternsz1) ;       
222                diff2 = tree_diff (treeA, treeB, patternsz1, patternsz2) ;
223                diff_array[diff_index++] = diff1 + diff2 ;
224              }
225         
226          }
227      }
228    break ;
229
230  case (CORR_IN_1_AND_2) :
231    if (trees_in_1 != trees_in_2)
232      {
233        /* Print something out to the outfile and to the terminal. */
234        fprintf (outfile, "\n\n") ;
235        fprintf (outfile, "*** Warning: differing number of trees in first and second\n") ;
236        fprintf (outfile, "*** tree files.  Only computing %ld pairs.\n\n",
237                 trees_in_1 > trees_in_2 ? trees_in_2 : trees_in_1) ;
238
239        printf ("\n *** Warning: differing number of trees in first and second\n") ;
240        printf (" *** tree files.  Only computing %ld pairs.\n\n",
241                 trees_in_1 > trees_in_2 ? trees_in_2 : trees_in_1) ;
242
243        /* Set end tree to the smaller of the two totals. */
244        end_tree = trees_in_1 > trees_in_2 ? trees_in_2 : trees_in_1 ;
245      }
246    else
247      end_tree = trees_in_1 ;
248
249    for (tree_index = 0 ; tree_index < end_tree ; tree_index++)
250      {
251        /* For every tree, compute the distance between it and the
252           tree at the parallel location in the other file; do this in
253           both directions */
254
255        assign_tree (treeA, pattern_array, tree_index, &patternsz1) ;
256
257        /* (tree_index + trees_in_1) will be the corresponding tree in
258           the second file. */
259        assign_tree (treeB, pattern_array, tree_index + trees_in_1, &patternsz2) ;
260        diff1 = tree_diff (treeB, treeA, patternsz2, patternsz1) ;
261        diff2 = tree_diff (treeA, treeB, patternsz1, patternsz2) ;
262        diff_array[tree_index] = diff1 + diff2 ;
263      }
264    break ; 
265
266  case (ALL_IN_1_AND_2) :
267    end_tree = trees_in_1 + trees_in_2 ;
268
269    for (tree_index = 0 ; tree_index < trees_in_1 ; tree_index++)
270      {
271        /* For every tree in the first file, compute the distance
272           between it and every tree in the second file. */
273
274        assign_tree (treeA, pattern_array, tree_index, &patternsz1) ;
275
276        for (index2 = trees_in_1 ; index2 < end_tree ; index2++)
277          {
278            assign_tree (treeB, pattern_array, index2, &patternsz2) ;
279
280            diff1 = tree_diff (treeB, treeA, patternsz2, patternsz1) ;       
281            diff2 = tree_diff (treeA, treeB, patternsz1, patternsz2) ;
282           
283            diff_array[diff_index++] = diff1 + diff2 ;
284          }
285      }
286
287    for ( ; tree_index < end_tree ; tree_index++)
288      {
289        /* For every tree in the second file, compute the distance
290           between it and every tree in the first file. */
291
292        assign_tree (treeA, pattern_array, tree_index, &patternsz1) ;
293
294        for (index2 = 0 ; index2 < trees_in_1 ; index2++)
295          {
296            assign_tree (treeB, pattern_array, index2, &patternsz2) ;
297
298            diff1 = tree_diff (treeB, treeA, patternsz2, patternsz1) ;       
299            diff2 = tree_diff (treeA, treeB, patternsz1, patternsz2) ;
300           
301            diff_array[diff_index++] = diff1 + diff2 ;
302          }
303      }
304    break ; 
305  }
306
307  /* Free up treeA and treeB */
308  for (i=0 ; i<setsz; i++)
309    {
310      free (treeA[i]) ;
311      free (treeB[i]) ;
312    }
313  free (treeA) ;
314  free (treeB) ;       
315}  /* compute_distances */
316
317
318void free_patterns(pattern_elm ***pattern_array, long total_trees) 
319{
320  long i, j ;
321  long end_pattern = total_trees - 1 ;
322
323  /* Free each pattern array, */
324  for (i=0 ; i < setsz ; i++)
325    {
326      for (j = 0 ; j < end_pattern ; j++) {
327        free (pattern_array[i][j]->apattern) ;
328        free (pattern_array[i][j]->patternsize) ;
329      }
330      free (pattern_array[i]) ;
331    }
332  free (pattern_array) ;
333}  /* free_patterns */
334
335
336void produce_square_matrix(long trees_in_1, long *diff_array)
337{
338  long i, j ;
339  long block_start, block_end, block_index, end_block ;
340
341  end_block         = (int) ceil ((double) trees_in_1 /
342                                  (double) COLUMNS_PER_BLOCK) ;
343  block_start       = 0 ;
344  block_end         = 0 ;
345
346  for (block_index = 0 ; block_index < end_block; block_index++)
347    {
348      block_start  = block_index * COLUMNS_PER_BLOCK ;
349      block_end    = block_start + COLUMNS_PER_BLOCK ;
350
351      if (block_end > trees_in_1) 
352        block_end = trees_in_1 ;
353
354      /* Leading spaces in the top line */
355      fprintf (outfile, "         ") ;
356
357      /* Here's the top line index, */
358      for (i = block_start ; i < block_end ; i++) 
359        fprintf (outfile,"%2ld    ", i+1) ;
360       
361      /* And then a delimiting line. */
362      fprintf (outfile,"\n      \\") ;
363      for (i=block_start ; i < block_end ; i++)
364        fprintf (outfile,"------") ;
365     
366      fprintf (outfile,"\n") ;
367
368      for (i = 0 ; i < trees_in_1 ; i++)
369          {
370            fprintf (outfile," %4ld |", i+1) ;   /* The row indicator, */
371            for (j = 0 ; j < block_end - block_start ; j++)
372            {
373               fprintf (outfile, "%4ld  ", 
374                       diff_array [(i * trees_in_1)  +
375                       (block_index * COLUMNS_PER_BLOCK) +
376                       j]) ;
377            }
378            fprintf (outfile,"\n") ;
379          }
380      fprintf (outfile,"\n\n") ;
381    }
382}  /* produce_square_matrix */
383
384
385void produce_full_matrix(long trees_in_1, long trees_in_2,
386                long *diff_array)
387{
388  long i, j, block_start, block_end, block_index, end_block ;
389
390  end_block         = ((double) trees_in_2  /
391                       (double) COLUMNS_PER_BLOCK) + 1 ;
392
393  block_start = trees_in_1 ;
394  block_end   = 0 ;
395
396  /* Print out the top row, */
397  fprintf (outfile,"\n\n") ;
398  fprintf (outfile, "First\\  Second tree file:\n") ;
399  fprintf (outfile, "tree  \\\n") ;
400  fprintf (outfile, "file:  \\   ") ;
401
402  for (block_index = 0 ; block_index < end_block; block_index++)
403    {
404      block_start += block_index * COLUMNS_PER_BLOCK ;
405      block_end    = block_start + COLUMNS_PER_BLOCK ;
406
407      if (block_end > (trees_in_1 + trees_in_2))
408        block_end = (trees_in_1 + trees_in_2) ;
409
410      /* This is the top row for the block, listing trees in the
411         second file. */
412      if (block_start != trees_in_1) 
413        /* For blocks beyond the first, */
414        fprintf (outfile,"           ") ;
415
416      /* Here's the top line index, */
417      for (i=block_start ; i < block_end ; i++)
418        fprintf (outfile,"%2ld    ", (i+1) - trees_in_1) ;
419
420      /* And then a delimiting line. */
421      fprintf (outfile,"\n        \\") ;
422      for (i=block_start ; i < block_end ; i++)
423        fprintf (outfile,"------") ;
424
425      fprintf (outfile,"\n") ;
426     
427      for (i = 0 ; i < trees_in_1 ; i++)
428        {
429          fprintf (outfile,"  %2ld    |", i+1) ;   /* The row indicator, */
430          for (j = 0 ; j < block_end - block_start ; j++)
431            {
432              fprintf (outfile, "%4ld  ", 
433                       diff_array [(i * trees_in_2)  +
434                       (block_index * COLUMNS_PER_BLOCK) +
435                       j]) ;
436            }
437          fprintf (outfile,"\n") ;
438        }
439      fprintf (outfile,"\n\n") ;
440    }
441} /* produce_full_matrix */
442
443
444void output_distances(long trees_in_1, long trees_in_2, long *diff_array) 
445{
446  long i, j, end_tree, diff_index ;
447
448  diff_index = 0 ;
449
450  switch (tree_pairing) {
451  case (ADJACENT_PAIRS) : 
452    end_tree = trees_in_1 - 1 ;
453
454    if (output_scheme == VERBOSE) 
455      {
456        fprintf(outfile, "\nTree distance program, version %s\n\n", VERSION);
457        fprintf (outfile, 
458             "Symmetric differences between adjacent pairs of trees:\n\n");
459        for (i = 0 ; i < end_tree ; i += 2)
460          fprintf (outfile, "Trees %ld and %ld:    %ld\n", 
461                   i+1, i+2, diff_array[diff_index++]) ;
462        fprintf(outfile, "\n");
463      }
464    else if (output_scheme == SPARSE)
465      {
466        for (i = 0 ; i < end_tree ; i += 2)
467          fprintf (outfile, "%ld %ld %ld\n", 
468                   i+1, i+2, diff_array[diff_index++]) ;
469      }
470    else
471      printf ("Error -- cannot output adjacent pairs into a full matrix.\n") ;
472
473    break ;
474
475  case (ALL_IN_FIRST) : 
476    end_tree   = trees_in_1 ;
477
478    if (output_scheme == VERBOSE) 
479      {
480        fprintf(outfile, "\nTree distance program, version %s\n\n", VERSION);
481        fprintf (outfile, 
482         "Symmetric differences between all pairs of trees in tree file:\n\n");
483        for (i=0; i<end_tree; i++)
484          for (j=0 ; j<end_tree; j++)
485            fprintf (outfile, "Trees %ld and %ld:    %ld\n", 
486                     i+1, j+1, diff_array[diff_index++]) ;
487        fprintf(outfile, "\n");
488      }
489    else if (output_scheme == SPARSE)
490      {
491        for (i=0; i<end_tree; i++)
492          for (j=0 ; j<end_tree; j++)
493            fprintf (outfile, "%ld %ld %ld\n", 
494                     i+1, j+1, diff_array[diff_index++]) ;
495           
496      }
497    else if (output_scheme == FULL_MATRIX)
498      {
499        fprintf(outfile, "\nTree distance program, version %s\n\n", VERSION);
500        fprintf (outfile, 
501         "Symmetric differences between all pairs of trees in tree file:\n\n");
502        produce_square_matrix (trees_in_1, diff_array) ;
503      }
504    break ;
505
506  case (CORR_IN_1_AND_2) :
507
508    if (trees_in_1 != trees_in_2)
509      end_tree = trees_in_1 > trees_in_2 ? trees_in_2 : trees_in_1 ;
510    else
511      end_tree = trees_in_1 ;
512
513    if (output_scheme == VERBOSE)
514      {
515        fprintf(outfile, "\nTree distance program, version %s\n\n", VERSION);
516        fprintf (outfile, 
517             "Symmetric differences between corresponding pairs of trees\n");
518        fprintf (outfile, 
519             "   from first and second tree files:\n\n");
520        for (i = 0 ; i < end_tree ; i++)
521          fprintf (outfile, "Tree pair %ld:    %ld\n", 
522                   i+1, diff_array[i]) ;
523        fprintf(outfile, "\n");
524      }
525    else if (output_scheme == SPARSE)
526      {
527        for (i = 0 ; i < end_tree ; i++)
528          fprintf (outfile, "%ld %ld\n", 
529                   i+1, diff_array[i]) ;
530      }
531    else
532      printf ("Error -- cannot output corresponding pairs into a full matrix.\n") ;
533
534    break ; 
535
536  case (ALL_IN_1_AND_2) :
537    end_tree = trees_in_1 + trees_in_2 ;
538
539    switch (output_scheme) {
540
541    case (VERBOSE) :
542      fprintf(outfile, "\nTree distance program, version %s\n\n", VERSION);
543      fprintf (outfile, 
544             "Symmetric differences between all pairs of trees\n");
545      fprintf (outfile, 
546             "   from first and second tree files:\n\n");
547      for (i = 0 ; i < trees_in_1 ; i++)
548        for (j = trees_in_1 ; j < end_tree ; j++)
549          {
550            fprintf (outfile, "Trees %ld and %ld:    %ld\n", 
551                     i+1, j+1, diff_array[diff_index++]) ;
552          }
553      for (i = trees_in_1; i < end_tree ; i++)
554        for (j = 0 ; j < trees_in_1 ; j++)
555          {
556            fprintf (outfile, "Trees %ld and %ld:    %ld\n", 
557                     i+1, j+1, diff_array[diff_index++]) ;
558          }
559      fprintf(outfile, "\n");
560      break ;
561
562    case (SPARSE) :
563      for (i = 0 ; i < trees_in_1 ; i++)
564        for (j = trees_in_1 ; j < end_tree ; j++)
565          {
566            fprintf (outfile, "%ld %ld %ld\n", 
567                     i+1, j+1, diff_array[diff_index++]) ;
568          }
569      for (i = trees_in_1; i < end_tree ; i++)
570        for (j = 0 ; j < trees_in_1 ; j++)
571          {
572            fprintf (outfile, "%ld %ld %ld\n", 
573                     i+1, j+1, diff_array[diff_index++]) ;
574          }
575      break ;
576
577    case (FULL_MATRIX) :
578      fprintf(outfile, "\nTree distance program, version %s\n\n", VERSION);
579      produce_full_matrix (trees_in_1, trees_in_2, diff_array) ;
580      break ;
581    }
582    break ; 
583  }
584} /* output_distances */
585
586
587void output_submenu()
588{
589  /* this allows the user to select a different output of distances scheme. */
590  long loopcount;
591  boolean done = false;
592  Char    ch   ;
593
594  if (tree_pairing == NO_PAIRING)
595    return ;
596
597  loopcount = 0;
598  while (!done) {
599    printf ("\nDistances output options:\n") ;
600
601    if ((tree_pairing == ALL_IN_1_AND_2) ||
602          (tree_pairing == ALL_IN_FIRST))
603      printf (" F     Full matrix.\n") ;
604      printf (" V     One pair per line, verbose.\n") ;
605      printf (" S     One pair per line, sparse.\n") ;
606     
607      if ((tree_pairing == ALL_IN_1_AND_2) ||
608          (tree_pairing == ALL_IN_FIRST))
609        printf ("\n Choose one: (F,V,S)\n") ;
610      else
611        printf ("\n Choose one: (V,S)\n") ;
612
613      scanf("%c%*[^\n]", &ch);
614      getchar();
615      uppercase(&ch);
616     
617      if (strchr("FVS",ch) != NULL) {
618        switch (ch) 
619          {
620          case 'F':
621            if ((tree_pairing == ALL_IN_1_AND_2) ||
622                (tree_pairing == ALL_IN_FIRST))
623              output_scheme = FULL_MATRIX ;
624            else
625              /* If this can't be a full matrix... */
626              continue ;
627            break ;
628           
629          case 'V':
630            output_scheme = VERBOSE ;
631            break ;
632           
633          case 'S':
634            output_scheme = SPARSE ;
635            break ;
636          }
637        done = true ;
638        }
639      countup(&loopcount, 10);
640    }
641}  /* output_submenu */
642
643
644void pairing_submenu()
645{
646  /* this allows the user to select a different tree pairing scheme. */
647  long loopcount;
648  boolean done = false;
649  Char    ch   ;
650
651  loopcount = 0;
652  while (!done) {
653    cleerhome();
654    printf ("Tree Pairing Submenu:\n") ;
655    printf (" A     Distances between adjacent pairs in tree file.\n") ;
656    printf (" P     Distances between all possible pairs in tree file.\n") ;
657    printf (" C     Distances between corresponding pairs in one tree file and another.\n") ;
658    printf (" L     Distances between all pairs in one tree file and another.\n") ;
659
660    printf ("\n Choose one: (A,P,C,L)\n") ;
661     
662    scanf("%c%*[^\n]", &ch);
663    getchar();
664    uppercase(&ch);
665
666    if (strchr("APCL",ch) != NULL) {
667      switch (ch) {
668        case 'A':
669          tree_pairing = ADJACENT_PAIRS ;
670          break ;
671             
672        case 'P':
673          tree_pairing = ALL_IN_FIRST ;
674          break ;
675
676        case 'C':
677          tree_pairing = CORR_IN_1_AND_2 ;
678          break ;
679             
680        case 'L':
681          tree_pairing = ALL_IN_1_AND_2 ;
682          break ;
683      }
684      output_submenu() ;
685      done = true ;
686    }
687    countup(&loopcount, 10);
688  }
689}  /* pairing_submenu */
690
691
692void read_second_file(pattern_elm ***pattern_array,
693                double *timesseen_changes, long *trees_in_1, long *trees_in_2)
694{
695  boolean firsttree2, haslengths, initial;
696  long nextnode;
697  long j;
698
699  firsttree2 = true;
700  grbg = NULL;
701  initial = true;
702  while (!eoff(intree2)) {
703    goteof = false;
704    nextnode = 0;
705    haslengths = false;
706    allocate_nodep(&nodep, &intree2, &spp);
707    if (firsttree2)
708      nayme = (naym *)Malloc(spp*sizeof(naym));
709    treeread(intree2, &root, treenode, &goteof, &firsttree2,
710               nodep, &nextnode, &haslengths,
711               &grbg, initconsnode);
712    if (!initial) { 
713      reordertips();
714    } else {
715      initial = false;
716      dupname(root);
717      initreenode(root);
718    }
719    if (goteof)
720      continue;
721    ntrees += trweight;
722    if (noroot) {
723      reroot(nodep[outgrno - 1], &nextnode);
724      didreroot = outgropt;
725    }
726    accumulate(root);
727    gdispose(root);
728    for (j = 0; j < 2*(1 + spp); j++)
729      nodep[j] = NULL;
730    free(nodep);
731
732    store_pattern (pattern_array, 
733                   timesseen_changes,
734                   (*trees_in_1) + (*trees_in_2)) ;
735    (*trees_in_2)++ ;
736  }
737  free(nayme);
738}  /* read_second_file */
739
740
741void getoptions()
742{
743  /* interactively set options */
744  long loopcount, loopcount2;
745  Char ch;
746  boolean done, done1;
747
748  /* Initial settings */
749  tree_pairing   = ADJACENT_PAIRS ;
750  output_scheme  = VERBOSE ;
751  ibmpc          = IBMCRT;
752  ansi           = ANSICRT;
753  didreroot      = false;
754  spp            = 0 ;
755  grbg           = NULL;
756  col            = 0 ;
757
758  putchar('\n');
759  noroot = true;
760  numopts = 0;
761  outgrno = 1;
762  outgropt = false;
763  progress = true;
764
765  /* The following are not used by treedist, but may be used
766     in functions in cons.c, so we set them here. */
767  treeprint = false;
768  trout = false;
769  prntsets = false;
770
771  loopcount = 0;
772  do {
773    cleerhome();
774    printf("\nTree distance program, version %s\n\n", VERSION);
775    printf("Settings for this run:\n");
776    if (noroot) {
777      printf(" O                         Outgroup root:");
778      if (outgropt)
779        printf("  Yes, at species number%3ld\n", outgrno);
780      else
781        printf("  No, use as outgroup species%3ld\n", outgrno);
782      }
783    printf(" R         Trees to be treated as Rooted:");
784    if (noroot)
785      printf("  No\n");
786    else
787      printf("  Yes\n");
788    printf(" T    Terminal type (IBM PC, ANSI, none):");
789    if (ibmpc)
790      printf("  IBM PC\n");
791    if (ansi)
792      printf("  ANSI\n");
793    if (!(ibmpc || ansi))
794      printf("  (none)\n");
795    printf(" 1  Print indications of progress of run:  %s\n",
796           (progress ? "Yes" : "No"));
797
798    /* Added by Dan F. */
799    printf(" 2                 Tree distance submenu:") ;
800    switch (tree_pairing)
801      {
802      case NO_PAIRING: 
803        printf("\n\nERROR: Unallowable option!\n\n") ;
804        exxit(-1);
805        break ;
806
807      case ADJACENT_PAIRS:
808        printf("  Distance between adjacent pairs\n") ;
809        break ;
810
811      case CORR_IN_1_AND_2: 
812        printf("  Distances between corresponding \n") ;
813        printf("                                             pairs in first and second tree files\n") ;
814        break ;
815
816      case ALL_IN_FIRST: 
817        printf("  Distances between all possible\n") ;
818        printf("                                             pairs in tree file.\n") ;
819        break ;
820
821      case ALL_IN_1_AND_2: 
822        printf("  Distances between all pairs in\n") ;
823        printf("                                              first and second tree files\n") ;
824        break ;
825      }
826
827    printf("\nAre these settings correct? (type Y or the letter for one to change)\n");
828    scanf("%c%*[^\n]", &ch);
829    getchar();
830    uppercase(&ch);
831    done = (ch == 'Y');
832    if (!done) {
833      if ((noroot && (ch == 'O')) || strchr("RT12",ch) != NULL) {
834        switch (ch) {
835
836        case 'O':
837          outgropt = !outgropt;
838          if (outgropt) {
839            numopts++;
840            done1 = true;
841            loopcount2 = 0;
842            do {
843              printf("Type number of the outgroup:\n");
844              scanf("%ld%*[^\n]", &outgrno);
845              getchar();
846              done1 = (outgrno >= 1);
847              if (!done1) {
848                printf("\n\nERROR: Bad outgroup number: %ld", outgrno);
849                printf("  (must be greater than zero)\n\n");
850              }
851              countup(&loopcount2, 10);
852            } while (done1 != true);
853          }
854          break;
855
856        case 'R':
857          noroot = !noroot;
858          break;
859
860        case 'T':
861          initterminal(&ibmpc, &ansi);
862          break;
863
864        case '1':
865          progress = !progress;
866          break;
867       
868        case '2':
869          pairing_submenu() ;
870          break ;
871        }
872      } else
873        printf("Not a possible option!\n");
874    }
875    countup(&loopcount, 100);
876  } while (!done);
877}  /* getoptions */
878
879
880int main(int argc, Char *argv[])
881{ 
882  /* Local variables added by Dan F. */
883  pattern_elm  ***pattern_array ;
884  double *timesseen_changes ;
885  long trees_in_1 = 0, trees_in_2 = 0 ;
886  long *diff_array ;
887
888#ifdef MAC
889  argc = 1;                /* macsetup("Treedist", "");        */
890  argv[0] = "Treedist";
891#endif
892  init(argc, argv);
893  openfile(&intree, INTREE, "input tree file", "r", argv[0], intreename);
894  openfile(&outfile, OUTFILE, "output file", "w", argv[0], outfilename);
895
896  /* Initialize option-based variables, then ask for changes regarding
897     their values. */
898  getoptions();
899
900  ntrees = 0.0;
901  maxgrp = 10000;
902  lasti  = -1;
903
904  if ((tree_pairing == ALL_IN_1_AND_2) ||
905      (tree_pairing == CORR_IN_1_AND_2))
906    /* If another intree file should exist, */
907    openfile(&intree2, INTREE2, "input tree file 2", "r", 
908             argv[0], intree2name);
909
910  if (tree_pairing != NO_PAIRING){
911    timesseen_changes = (double *)Malloc(maxgrp * sizeof(double)) ;
912  }
913
914  /* Read the (first) tree file and put together grouping, order, and
915     timesseen */
916  read_groups (&pattern_array, timesseen_changes, &trees_in_1,
917                 intree);
918
919  if ((tree_pairing == ADJACENT_PAIRS) ||
920      (tree_pairing == ALL_IN_FIRST)) {
921
922    trees_in_2 = 0 ;   /* Just to avoid problems. . .*/
923   
924    /* Here deal with the adjacent or all-in-first pairing
925       difference computation */
926    if (tree_pairing == ADJACENT_PAIRS)
927      diff_array = (long *) Malloc (trees_in_1 * sizeof (long *)) ;
928    else if (tree_pairing == ALL_IN_FIRST) 
929      diff_array = (long *) Malloc ((trees_in_1 * trees_in_1)
930                                   * sizeof (long *)) ;
931
932    compute_distances (pattern_array, trees_in_1, trees_in_2, diff_array) ;
933    output_distances  (trees_in_1, trees_in_2, diff_array) ;
934
935    /* Free all the buffers needed to compute the differences. */
936    free (diff_array) ;
937    free (timesseen_changes) ;
938    /* Patterns need to be freed in a more complex fashion. */
939    /* This removed 'cause it was causing problems */
940    /* free_patterns (pattern_array, trees_in_1 + trees_in_2) ;*/
941
942  } else if ((tree_pairing == CORR_IN_1_AND_2) ||
943             (tree_pairing == ALL_IN_1_AND_2)) {
944    /* Here, open the other tree file, parse it, and then put
945         together the difference array */
946    read_second_file (pattern_array, timesseen_changes, 
947                      &trees_in_1, &trees_in_2) ;
948
949    /* Allocate a proper amount of space for the diff_array, */
950    if (tree_pairing == CORR_IN_1_AND_2)
951      diff_array = (long *) Malloc ((trees_in_1 + trees_in_2)
952                                   * sizeof (long *)) ;
953    else if (tree_pairing == ALL_IN_1_AND_2)
954      diff_array = (long *) Malloc ((trees_in_1 * trees_in_2)
955                                   * 2 * sizeof (long *)) ;
956
957    compute_distances (pattern_array, trees_in_1, trees_in_2, diff_array) ;
958    output_distances (trees_in_1, trees_in_2, diff_array) ;
959
960    /* Free all the buffers needed to compute the differences. */
961    free (diff_array) ;
962    free (timesseen_changes) ;
963    /* Patterns need to be freed in a more complex fashion. */
964    /* This removed 'cause it was causing problems */
965    /* free_patterns (pattern_array, trees_in_1 + trees_in_2) ; */
966
967  } else if (tree_pairing == NO_PAIRING) {
968    /* Compute the consensus tree. */
969    putc('\n', outfile);
970    /* consensus();         Reserved for future development */
971  }
972
973  if (progress)
974    printf("\nOutput written to file \"%s\"\n\n", outfilename);
975
976  FClose(outtree);
977  FClose(intree);
978  FClose(outfile);
979
980  if ((tree_pairing == ALL_IN_1_AND_2) || 
981      (tree_pairing == CORR_IN_1_AND_2))
982    FClose(intree2) ;
983
984  printf("Done.\n\n");
985
986#ifdef MAC
987  fixmacfile(outfilename);
988  fixmacfile(outtreename);
989#endif
990  return 0;
991}  /* main */
992
Note: See TracBrowser for help on using the repository browser.