source: branches/profile/GDE/PHYLIP/move.c

Last change on this file was 2175, checked in by westram, 20 years ago

upgrade to PHYLIP 3.6

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 39.8 KB
Line 
1
2#include "phylip.h"
3#include "disc.h"
4#include "moves.h"
5#include "wagner.h"
6
7/* version 3.6. (c) Copyright 1993-2002 by the University of Washington.
8   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, and Andrew Keeffe.
9   Permission is granted to copy and use this program provided no fee is
10   charged for it and provided that this copyright notice is not removed. */
11
12#define overr           4
13#define which           1
14
15typedef enum {
16  horiz, vert, up, overt, upcorner, downcorner, onne, zerro, question
17} chartype;
18typedef enum {
19  arb, use, spec
20} howtree;
21
22typedef enum {
23  rearr, flipp, reroott, none
24} rearrtype;
25
26#ifndef OLDC
27/*function prototypes */
28void   getoptions(void);
29void   inputoptions(void);
30void   allocrest(void);
31void   doinput(void);
32void   configure(void);
33void   prefix(chartype);
34void   postfix(chartype);
35void   makechar(chartype);
36void   move_fillin(node *);
37void   move_postorder(node *);
38
39void   evaluate(node *);
40void   reroot(node *);
41void   move_filltrav(node *);
42void   move_hyptrav(node *);
43void   move_hypstates(void);
44void   grwrite(chartype, long, long *);
45void   move_drawline(long, long);
46void   move_printree(void);
47void   arbitree(void);
48void   yourtree(void);
49
50void   initmovenode(node **, node **, node *, long, long, long *, long *,
51        initops, pointarray, pointarray, Char *, Char *, FILE *);
52void   buildtree(void);
53void   rearrange(void);
54void   tryadd(node *, node *, node *, double *);
55void   addpreorder(node *, node *, node *, double *);
56void   try(void);
57void   undo(void);
58void   treewrite(boolean);
59void   clade(void);
60void   flip(void);
61
62void   changeoutgroup(void);
63void   redisplay(void);
64void   treeconstruct(void);
65/*function prototypes */
66#endif
67 
68char infilename[FNMLNGTH],intreename[FNMLNGTH],outtreename[FNMLNGTH], weightfilename[FNMLNGTH], ancfilename[FNMLNGTH], mixfilename[FNMLNGTH], factfilename[FNMLNGTH];
69node *root;
70long outgrno, screenlines, col, treelines, leftedge, topedge,
71  vmargin, hscroll, vscroll, scrollinc, screenwidth, farthest;
72/* outgrno indicates outgroup */
73boolean weights, thresh, outgropt, ancvar, questions, allsokal,
74               allwagner, mixture, factors, noroot,  waswritten;
75boolean *ancone, *anczero, *ancone0, *anczero0;
76Char *factor;
77pointptr treenode;   /* pointers to all nodes in tree */
78double threshold;
79double *threshwt;
80bitptr wagner, wagner0;
81unsigned char che[9];
82boolean reversed[9];
83boolean graphic[9];
84howtree how;
85gbit *garbage;
86char* progname;
87Char ch;
88
89/* Variables for treeread */
90boolean usertree, goteof, firsttree, haslengths;
91pointarray nodep;
92node *grbg;
93long *zeros;
94
95/* Local variables for treeconstruct, propagated globally for C vesion: */
96long dispchar, dispword, dispbit, atwhat, what, fromwhere, towhere,
97     oldoutgrno, compatible;
98double like, bestyet, gotlike;
99Char *guess;
100boolean display, newtree, changed, subtree, written, oldwritten, restoring,
101  wasleft, oldleft, earlytree;
102boolean *in_tree;
103steptr numsteps, numsone, numszero;
104long fullset;
105bitptr steps, zeroanc, oneanc;
106node *nuroot;
107rearrtype lastop;
108boolean *names;
109
110
111void getoptions()
112{
113  /* interactively set options */
114  long loopcount;
115  Char ch;
116  boolean done, gotopt;
117
118  how = arb;
119  usertree = false;
120  goteof = false;
121  outgrno = 1;
122  outgropt = false;
123  thresh = false;
124  threshold = spp;
125  weights = false;
126  ancvar = false;
127  allsokal = false;
128  allwagner = true;
129  mixture = false;
130  factors = false;
131  loopcount = 0;
132  do {
133    printf((ansi || ibmpc) ? "\033[2J\033[H" : "\n");
134    printf("\n\nInteractive mixed parsimony algorithm, version %s\n\n",
135           VERSION);
136    printf("Settings for this run:\n");
137    printf("  X                         Use Mixed method?  %s\n",
138           mixture ? "Yes" : "No");
139    printf("  P                         Parsimony method?  %s\n",
140           (allwagner && !mixture)   ? "Wagner"       :
141           (!(allwagner || mixture)) ? "Camin-Sokal"  : "(methods in mixture)");
142       
143    printf("  A                     Use ancestral states?  %s\n",
144           ancvar ? "Yes" : "No");
145    printf("  F                  Use factors information?  %s\n",
146           factors ? "Yes" : "No");
147    printf("  O                            Outgroup root?  %s %3ld\n",
148           outgropt ? "Yes, at species number" : "No, use as outgroup species",
149           outgrno);
150    printf("  W                           Sites weighted?  %s\n",
151           (weights ? "Yes" : "No"));
152    printf("  T                  Use Threshold parsimony?");
153    if (thresh)
154      printf("  Yes, count steps up to%4.1f\n", threshold);
155    else
156      printf("  No, use ordinary parsimony\n");
157    printf("  U  Initial tree (arbitrary, user, specify)?  %s\n",
158           (how == arb) ? "Arbitrary"                   :
159           (how == use) ? "User tree from tree file"    : "Tree you specify");
160    printf("  0       Graphics type (IBM PC, ANSI, none)?  %s\n",
161           ibmpc ? "IBM PC" : ansi  ? "ANSI" : "(none)");
162    printf("  S                 Width of terminal screen?");
163    printf("%4ld\n", screenwidth);
164    printf("  L                Number of lines on screen?%4ld",screenlines);
165    printf("\n\nAre these settings correct?");
166    printf(" (type Y or the letter for one to change)\n");
167#ifdef WIN32
168    phyFillScreenColor();
169#endif
170    scanf("%c%*[^\n]", &ch);
171    getchar();
172    if (ch == '\n')
173      ch = ' ';
174    uppercase(&ch);
175    done = (ch == 'Y');
176    gotopt = (strchr("SFOTXPAU0WL",ch) != NULL) ? true : false;
177    if (gotopt) {
178      switch (ch) {
179
180      case 'F':
181        factors = !factors;
182        break;
183
184      case 'X':
185        mixture = !mixture;
186        break;
187
188      case 'W':
189          weights = !weights;
190          break;
191
192      case 'P':
193        allwagner = !allwagner;
194        break;
195
196      case 'A':
197        ancvar = !ancvar;
198        break;
199
200      case 'O':
201        outgropt = !outgropt;
202        if (outgropt)
203          initoutgroup(&outgrno, spp);
204        break;
205
206      case 'T':
207        thresh = !thresh;
208        if (thresh)
209          initthreshold(&threshold);
210        break;
211
212      case 'U':
213        if (how == arb)
214          how = use;
215        else if (how == use)
216          how = spec;
217        else
218          how = arb;
219        break;
220
221      case '0':
222        initterminal(&ibmpc, &ansi);
223        break;
224
225      case 'S':
226        screenwidth= readlong("Width of terminal screen (in characters)?\n");
227        break;
228
229      case 'L':
230        initnumlines(&screenlines);
231        break;
232      }
233    }
234    if (!(gotopt || done))
235      printf("Not a possible option!\n");
236    countup(&loopcount, 100);
237  } while (!done);
238  allsokal = (!allwagner && !mixture);
239  if (scrollinc < screenwidth / 2.0)
240    hscroll = scrollinc;
241  else
242    hscroll = screenwidth / 2;
243  if (scrollinc < screenlines / 2.0)
244    vscroll = scrollinc;
245  else
246    vscroll = screenlines / 2;
247}  /* getoptions */
248
249
250void inputoptions()
251{
252  /* input the information on the options */
253  long i;
254  scan_eoln(infile);
255  for (i = 0; i < (chars); i++)
256    weight[i] = 1;
257    if (ancvar)
258        inputancestorsnew(anczero0, ancone0);
259
260    if (factors) {
261      factor = (Char *)Malloc(chars*sizeof(Char));
262      inputfactorsnew(chars, factor, &factors);
263    }
264    if (mixture)
265        inputmixturenew(wagner0);
266    if (weights)
267      inputweights(chars, weight, &weights);
268  putchar('\n');
269  if (weights)
270    printweights(stdout, 0, chars, weight, "Characters");
271  for (i = 0; i < (words); i++) {
272    if (mixture)
273      wagner[i] = wagner0[i];
274    else if (allsokal)
275      wagner[i] = 0;
276    else
277      wagner[i] = (1L << (bits + 1)) - (1L << 1);
278  }
279  if (allsokal && !mixture)
280    printf("Camin-Sokal parsimony method\n\n");
281  if (allwagner && !mixture)
282    printf("Wagner parsimony method\n\n");
283  if (mixture)
284    printmixture(stdout, wagner);
285  for (i = 0; i < (chars); i++) {
286    if (!ancvar) {
287      anczero[i] = true;
288      ancone[i] = (((1L << (i % bits + 1)) & wagner[i / bits]) != 0);
289    } else {
290      anczero[i] = anczero0[i];
291      ancone[i] = ancone0[i];
292    }
293  }
294  if (factors)
295    printfactors(stdout, chars, factor, "");
296  if (ancvar)
297    printancestors(stdout, anczero, ancone);
298  noroot = true;
299  questions = false;
300  for (i = 0; i < (chars); i++) {
301    if (weight[i] > 0) {
302      noroot = (noroot && ancone[i] && anczero[i] &&
303          ((((1L << (i % bits + 1)) & wagner[i / bits]) != 0)
304            || threshold <= 2.0));
305    }
306    questions = (questions || (ancone[i] && anczero[i]));
307    threshwt[i] = threshold * weight[i];
308  }
309}  /* inputoptions */
310
311
312void allocrest()
313{
314  nayme = (naym *)Malloc(spp*sizeof(naym));
315  in_tree = (boolean *)Malloc(nonodes*sizeof(boolean));
316  extras = (steptr)Malloc(chars*sizeof(long));
317  weight = (steptr)Malloc(chars*sizeof(long));
318  numsteps = (steptr)Malloc(chars*sizeof(long));
319  numsone = (steptr)Malloc(chars*sizeof(long));
320  numszero = (steptr)Malloc(chars*sizeof(long));
321  threshwt = (double *)Malloc(chars*sizeof(double));
322  guess = (Char *)Malloc(chars*sizeof(Char));
323  ancone = (boolean *)Malloc(chars*sizeof(boolean));
324  anczero = (boolean *)Malloc(chars*sizeof(boolean));
325  ancone0 = (boolean *)Malloc(chars*sizeof(boolean));
326  anczero0 = (boolean *)Malloc(chars*sizeof(boolean));
327  wagner = (bitptr)Malloc(words*sizeof(long));
328  wagner0 = (bitptr)Malloc(words*sizeof(long));
329  steps = (bitptr)Malloc(words*sizeof(long));
330  zeroanc = (bitptr)Malloc(words*sizeof(long));
331  oneanc = (bitptr)Malloc(words*sizeof(long));
332}  /* allocrest */
333
334
335void doinput()
336{
337  /* reads the input data */
338
339  inputnumbers(&spp, &chars, &nonodes, 1);
340  words = chars / bits + 1;
341  printf("%2ld species, %3ld characters\n", spp, chars);
342  printf("\nReading input file ...\n\n");
343  getoptions();
344  if (weights)
345    openfile(&weightfile,WEIGHTFILE,"weights file","r",progname,weightfilename);
346  if(ancvar)
347      openfile(&ancfile,ANCFILE,"ancestors file", "r",progname,ancfilename);
348  if(mixture)
349      openfile(&mixfile,MIXFILE,"mixture file", "r",progname,mixfilename);
350  if(factors)
351      openfile(&factfile,FACTFILE,"factors file", "r",progname,factfilename);
352
353  alloctree(&treenode);
354  setuptree(treenode);
355  allocrest();
356  inputoptions();
357  inputdata(treenode, true, false, stdout);
358}  /* doinput */
359
360
361void configure()
362{
363  /* configure to machine -- set up special characters */
364  chartype a;
365
366  for (a = horiz; (long)a <= (long)question; a = (chartype)((long)a + 1))
367    reversed[(long)a] = false;
368  for (a = horiz; (long)a <= (long)question; a = (chartype)((long)a + 1))
369    graphic[(long)a] = false;
370  if (ibmpc) {
371    che[(long)horiz] = 205;
372    graphic[(long)horiz] = true;
373    che[(long)vert] = 186;
374    graphic[(long)vert] = true;
375    che[(long)up] = 186;
376    graphic[(long)up] = true;
377    che[(long)overt] = 205;
378    graphic[(long)overt] = true;
379    che[(long)onne] = 219;
380    reversed[(long)onne] = true;
381    che[(long)zerro] = 176;
382    graphic[(long)zerro] = true;
383    che[(long)question] = 178;   /* or try CHR(177) */
384    graphic[(long)question] = true;
385    che[(long)upcorner] = 200;
386    graphic[(long)upcorner] = true;
387    che[(long)downcorner] = 201;
388    graphic[(long)downcorner] = true;
389    return;
390  }
391  if (ansi) {
392    che[(long)onne] = ' ';
393    reversed[(long)onne] = true;
394    che[(long)horiz] = che[(long)onne];
395    reversed[(long)horiz] = true;
396    che[(long)vert] = che[(long)onne];
397    reversed[(long)vert] = true;
398    che[(long)up] = 'x';
399    graphic[(long)up] = true;
400    che[(long)overt] = 'q';
401    graphic[(long)overt] = true;
402    che[(long)zerro] = 'a';
403    graphic[(long)zerro] = true;
404    reversed[(long)zerro] = true;
405    che[(long)question] = '?';
406    reversed[(long)question] = true;
407    che[(long)upcorner] = 'm';
408    graphic[(long)upcorner] = true;
409    che[(long)downcorner] = 'l';
410    graphic[(long)downcorner] = true;
411    return;
412  }
413  che[(long)horiz] = '=';
414  che[(long)vert] = ' ';
415  che[(long)up] = '!';
416  che[(long)overt] = '-';
417  che[(long)onne] = '*';
418  che[(long)zerro] = '=';
419  che[(long)question] = '.';
420  che[(long)upcorner] = '`';
421  che[(long)downcorner] = ',';
422}  /* configure */
423
424
425void prefix(chartype a)
426{
427  /* give prefix appropriate for this character */
428  if (reversed[(long)a])
429    prereverse(ansi);
430  if (graphic[(long)a])
431    pregraph(ansi);
432}  /* prefix */
433
434
435void postfix(chartype a)
436{
437  /* give postfix appropriate for this character */
438  if (reversed[(long)a])
439    postreverse(ansi);
440  if (graphic[(long)a])
441    postgraph(ansi);
442}  /* postfix */
443
444
445void makechar(chartype a)
446{
447  /* print out a character with appropriate prefix or postfix */
448  prefix(a);
449  putchar(che[(long)a]);
450  postfix(a);
451}  /* makechar */
452
453
454void move_fillin(node *p)
455{
456  /* Sets up for each node in the tree two statesets.
457     stateone and statezero are the sets of character
458     states that must be 1 or must be 0, respectively,
459     in a most parsimonious reconstruction, based on the
460     information at or above this node.   Note that this
461     state assignment may change based on information further
462     down the tree.   If a character is in both sets it is in
463     state "P".   If in neither, it is "?". */
464  long i;
465  long l0, l1, r0, r1, st, wa, za, oa;
466
467  for (i = 0; i < (words); i++) {
468    l0 = p->next->back->statezero[i];
469    l1 = p->next->back->stateone[i];
470    r0 = p->next->next->back->statezero[i];
471    r1 = p->next->next->back->stateone[i];
472    wa = wagner[i];
473    za = zeroanc[i];
474    oa = oneanc[i];
475    st = (l1 & r0) | (l0 & r1);
476    steps[i] = st;
477    p->stateone[i] = (l1 | r1) & (~(st & (wa | za)));
478    p->statezero[i] = (l0 | r0) & (~(st & (wa | oa)));
479  }
480}  /* move_fillin */
481
482
483void move_postorder(node *p)
484{
485  /* traverses a binary tree, calling function fillin at a
486     node's descendants before calling fillin at the node */
487  if (p->tip)
488    return;
489  move_postorder(p->next->back);
490  move_postorder(p->next->next->back);
491  move_fillin(p);
492  count(steps, zeroanc, numszero, numsone);
493}  /* move_postorder */
494
495
496void evaluate(node *r)
497{
498  /* Determines the number of steps needed for a tree.
499     This is the minimum number needed to evolve chars on this tree */
500  long i, stepnum, smaller;
501  double sum;
502  boolean nextcompat, thiscompat, done;
503
504  sum = 0.0;
505  for (i = 0; i < (chars); i++) {
506    numszero[i] = 0;
507    numsone[i] = 0;
508  }
509  for (i = 0; i < (words); i++) {
510    zeroanc[i] = fullset;
511    oneanc[i] = 0;
512  }
513  compatible = 0;
514  nextcompat = true;
515  move_postorder(r);
516  count(r->stateone, zeroanc, numszero, numsone);
517  for (i = 0; i < (words); i++) {
518    zeroanc[i] = 0;
519    oneanc[i] = fullset;
520  }
521  move_postorder(r);
522  count(r->statezero, zeroanc, numszero, numsone);
523  for (i = 0; i < (chars); i++) {
524    smaller = spp * weight[i];
525    numsteps[i] = smaller;
526    if (anczero[i]) {
527      numsteps[i] = numszero[i];
528      smaller = numszero[i];
529    }
530    if (ancone[i] && numsone[i] < smaller)
531     numsteps[i] = numsone[i];
532    stepnum = numsteps[i] + extras[i];
533    if (stepnum <= threshwt[i])
534      sum += stepnum;
535    else
536      sum += threshwt[i];
537    thiscompat = (stepnum <= weight[i]);
538    if (factors) {
539      done = (i + 1 == chars);
540      if (!done)
541        done = (factor[i + 1] != factor[i]);
542      nextcompat = (nextcompat && thiscompat);
543      if (done) {
544        if (nextcompat)
545          compatible += weight[i];
546        nextcompat = true;
547      }
548    } else if (thiscompat)
549      compatible += weight[i];
550    guess[i] = '?';
551    if (!ancone[i] ||
552        (anczero[i] && numszero[i] < numsone[i]))
553      guess[i] = '0';
554    else if (!anczero[i] ||
555             (ancone[i] && numsone[i] < numszero[i]))
556     guess[i] = '1';
557  }
558  like = -sum;
559}  /* evaluate */
560
561
562void reroot(node *outgroup)
563{
564  /* reorients tree, putting outgroup in desired position. */
565  node *p, *q, *newbottom, *oldbottom;
566  boolean onleft;
567
568  if (outgroup->back->index == root->index)
569    return;
570  newbottom = outgroup->back;
571  p = treenode[newbottom->index - 1]->back;
572  while (p->index != root->index) {
573    oldbottom = treenode[p->index - 1];
574    treenode[p->index - 1] = p;
575    p = oldbottom->back;
576  }
577  onleft = (p == root->next);
578  if (restoring)
579    if (!onleft && wasleft){
580      p = root->next->next;
581      q = root->next;
582    } else {
583      p = root->next;
584      q = root->next->next;
585    }
586  else {
587    if (onleft)
588      oldoutgrno = root->next->next->back->index;
589    else
590      oldoutgrno = root->next->back->index;
591    wasleft = onleft;
592    p = root->next;
593    q = root->next->next;
594  }
595  p->back->back = q->back;
596  q->back->back = p->back;
597  p->back = outgroup;
598  q->back = outgroup->back;
599  if (restoring) {
600    if (!onleft && wasleft) {
601      outgroup->back->back = root->next;
602      outgroup->back = root->next->next;
603    } else {
604      outgroup->back->back = root->next->next;
605      outgroup->back = root->next;
606    }
607  } else {
608    outgroup->back->back = root->next->next;
609    outgroup->back = root->next;
610  }
611  treenode[newbottom->index - 1] = newbottom;
612}  /* reroot */
613
614
615void move_filltrav(node *r)
616{
617  /* traverse to fill in interior node states */
618  if (r->tip)
619    return;
620  move_filltrav(r->next->back);
621  move_filltrav(r->next->next->back);
622  move_fillin(r);
623}  /* move_filltrav */
624
625
626void move_hyptrav(node *r)
627{
628  /* compute states at one interior node */
629  long i;
630  boolean bottom;
631  long l0, l1, r0, r1, s0, s1, a0, a1, temp, wa;
632  gbit *zerobelow = NULL, *onebelow = NULL;
633
634  disc_gnu(&zerobelow, &garbage);
635  disc_gnu(&onebelow, &garbage);
636  bottom = (r->back == NULL);
637  if (bottom) {
638    memcpy(zerobelow->bits_, zeroanc, words*sizeof(long));
639    memcpy(onebelow->bits_, oneanc, words*sizeof(long));
640  } else {
641    memcpy(zerobelow->bits_, treenode[r->back->index - 1]->statezero,
642           words*sizeof(long));
643    memcpy(onebelow->bits_, treenode[r->back->index - 1]->stateone,
644           words*sizeof(long));
645  }
646  for (i = 0; i < (words); i++) {
647    s0 = r->statezero[i];
648    s1 = r->stateone[i];
649    a0 = zerobelow->bits_[i];
650    a1 = onebelow->bits_[i];
651    if (!r->tip) {
652      wa = wagner[i];
653      l0 = r->next->back->statezero[i];
654      l1 = r->next->back->stateone[i];
655      r0 = r->next->next->back->statezero[i];
656      r1 = r->next->next->back->stateone[i];
657      s0 = (wa & ((a0 & l0) | (a0 & r0) | (l0 & r0))) |
658           (fullset & (~wa) & s0);
659      s1 = (wa & ((a1 & l1) | (a1 & r1) | (l1 & r1))) |
660           (fullset & (~wa) & s1);
661      temp = fullset & (~(s0 | s1 | l1 | l0 | r1 | r0));
662      s0 |= temp & a0;
663      s1 |= temp & a1;
664      r->statezero[i] = s0;
665      r->stateone[i] = s1;
666    }
667  }
668  if (((1L << dispbit) & r->stateone[dispword - 1]) != 0) {
669    if (((1L << dispbit) & r->statezero[dispword - 1]) != 0)
670      r->state = '?';
671    else
672      r->state = '1';
673  } else {
674    if (((1L << dispbit) & r->statezero[dispword - 1]) != 0)
675      r->state = '0';
676    else
677      r->state = '?';
678  }
679  if (!r->tip) {
680    move_hyptrav(r->next->back);
681    move_hyptrav(r->next->next->back);
682  }
683  disc_chuck(zerobelow, &garbage);
684  disc_chuck(onebelow, &garbage);
685}  /* move_hyptrav */
686
687
688void move_hypstates()
689{
690  /* fill in and describe states at interior nodes */
691  long i, j, k;
692
693  for (i = 0; i < (words); i++) {
694    zeroanc[i] = 0;
695    oneanc[i] = 0;
696  }
697  for (i = 0; i < (chars); i++) {
698    j = i / bits + 1;
699    k = i % bits + 1;
700    if (guess[i] == '0')
701      zeroanc[j - 1] = ((long)zeroanc[j - 1]) | (1L << k);
702    if (guess[i] == '1')
703      oneanc[j - 1] = ((long)oneanc[j - 1]) | (1L << k);
704  }
705  move_filltrav(root);
706  move_hyptrav(root);
707}  /* move_hypstates */
708
709
710void grwrite(chartype c, long num, long *pos)
711{
712  long i;
713
714  prefix(c);
715  for (i = 1; i <= num; i++) {
716    if ((*pos) >= leftedge && (*pos) - leftedge + 1 < screenwidth)
717      putchar(che[(long)c]);
718    (*pos)++;
719  }
720  postfix(c);
721}  /* grwrite */
722
723
724void move_drawline(long i, long lastline)
725{
726  /* draws one row of the tree diagram by moving up tree */
727  node *p, *q, *r, *first =NULL, *last =NULL;
728  long n, j, pos;
729  boolean extra, done;
730  Char st;
731  chartype c, d;
732
733  pos = 1;
734  p = nuroot;
735  q = nuroot;
736  extra = false;
737  if (i == (long)p->ycoord && (p == root || subtree)) {
738    extra = true;
739    c = overt;
740    if (display) {
741      switch (p->state) {
742
743      case '1':
744        c = onne;
745        break;
746
747      case '0':
748        c = zerro;
749        break;
750
751      case '?':
752        c = question;
753        break;
754      }
755    }
756    if ((subtree))
757      stwrite("Subtree:", 8, &pos, leftedge, screenwidth);
758    if (p->index >= 100)
759      nnwrite(p->index, 3, &pos, leftedge, screenwidth);
760    else if (p->index >= 10) {
761      grwrite(c, 1, &pos);
762      nnwrite(p->index, 2, &pos, leftedge, screenwidth);
763    } else {
764      grwrite(c, 2, &pos);
765      nnwrite(p->index, 1, &pos, leftedge, screenwidth);
766    }
767  } else {
768    if (subtree)
769      stwrite("          ", 10, &pos, leftedge, screenwidth);
770    else
771      stwrite("  ", 2, &pos, leftedge, screenwidth);
772  }
773  do {
774    if (!p->tip) {
775      r = p->next;
776      done = false;
777      do {
778        if (i >= r->back->ymin && i <= r->back->ymax) {
779          q = r->back;
780          done = true;
781        }
782        r = r->next;
783      } while (!(done || r == p));
784      first = p->next->back;
785      r = p->next;
786      while (r->next != p)
787        r = r->next;
788      last = r->back;
789    }
790    done = (p == q);
791    n = (long)p->xcoord - (long)q->xcoord;
792    if (n < 3 && !q->tip)
793      n = 3;
794    if (extra) {
795      n--;
796      extra = false;
797    }
798    if ((long)q->ycoord == i && !done) {
799      if ((long)q->ycoord > (long)p->ycoord)
800        d = upcorner;
801      else
802        d = downcorner;
803      c = overt;
804      if (display) {
805        switch (q->state) {
806
807        case '1':
808          c = onne;
809          break;
810
811        case '0':
812          c = zerro;
813          break;
814
815        case '?':
816          c = question;
817          break;
818        }
819        d = c;
820      }
821      if (n > 1) {
822        grwrite(d, 1, &pos);
823        grwrite(c, n - 3, &pos);
824      }
825      if (q->index >= 100)
826        nnwrite(q->index, 3, &pos, leftedge, screenwidth);
827      else if (q->index >= 10) {
828        grwrite(c, 1, &pos);
829        nnwrite(q->index, 2, &pos, leftedge, screenwidth);
830      } else {
831        grwrite(c, 2, &pos);
832        nnwrite(q->index, 1, &pos, leftedge, screenwidth);
833      }
834      extra = true;
835    } else if (!q->tip) {
836      if ((long)last->ycoord > i && (long)first->ycoord < i
837        && i != (long)p->ycoord) {
838        c = up;
839        if (i < (long)p->ycoord)
840          st = p->next->back->state;
841        else
842          st = p->next->next->back->state;
843        if (display) {
844          switch (st) {
845
846          case '1':
847            c = onne;
848            break;
849
850          case '0':
851            c = zerro;
852            break;
853
854          case '?':
855            c = question;
856            break;
857          }
858        }
859        grwrite(c, 1, &pos);
860        chwrite(' ', n - 1, &pos, leftedge, screenwidth);
861      } else
862        chwrite(' ', n, &pos, leftedge, screenwidth);
863    } else
864      chwrite(' ', n, &pos, leftedge, screenwidth);
865    if (p != q)
866      p = q;
867  } while (!done);
868  if ((long)p->ycoord == i && p->tip) {
869    n = 0;
870    for (j = 1; j <= nmlngth; j++) {
871      if (nayme[p->index - 1][j - 1] != '\0')
872        n = j;
873    }
874    chwrite(':', 1, &pos, leftedge, screenwidth);
875    for (j = 0; j < n; j++)
876      chwrite(nayme[p->index - 1][j], 1, &pos, leftedge, screenwidth);
877  }
878  putchar('\n');
879}  /* move_drawline */
880
881
882void move_printree()
883{
884  /* prints out diagram of the tree */
885  long tipy, i, rover, dow;
886
887  if (!subtree)
888    nuroot = root;
889  if (changed || newtree)
890    evaluate(root);
891  if (display)
892    move_hypstates();
893  if (ansi || ibmpc)
894    printf("\033[2J\033[H");
895  else
896    putchar('\n');
897  tipy = 1;
898  rover = 100 / spp;
899  if (rover > overr)
900    rover = overr;
901  dow = down;
902  if (spp * dow > screenlines && !subtree) {
903    dow--;
904    rover--;
905  }
906  if (noroot)
907    printf("(unrooted)");
908  if (display) {
909    printf(" ");
910    makechar(onne);
911    printf(":1 ");
912    makechar(question);
913    printf(":? ");
914    makechar(zerro);
915    printf(":0 ");
916  } else
917    printf("             ");
918  if (!earlytree) {
919    printf("%10.1f Steps", -like);
920  }
921  if (display)
922    printf("  CHAR%3ld", dispchar);
923  else
924    printf("         ");
925  if (!earlytree) {
926    printf("  %3ld chars compatible\n", compatible);
927  }
928  printf("                            ");
929  if (changed && !earlytree) {
930    if (-like < bestyet) {
931      printf("     BEST YET!");
932      bestyet = -like;
933    } else if (fabs(-like - bestyet) < 0.000001)
934      printf("  (as good as best)");
935    else {
936      if (-like < gotlike)
937        printf("     better");
938      else if (-like > gotlike)
939        printf("     worse!");
940    }
941  }
942  printf("\n");
943
944  farthest = 0;
945  coordinates(nuroot, &tipy, 1.5, &farthest);
946  vmargin = 4;
947  treelines = tipy - dow;
948  if (topedge != 1) {
949    printf("** %ld lines above screen **\n", topedge - 1);
950    vmargin++;
951  }
952
953  if ((treelines - topedge + 1) > (screenlines - vmargin))
954    vmargin++;
955  for (i = 1; i <= treelines; i++) {
956    if (i >= topedge && i < topedge + screenlines - vmargin)
957      move_drawline(i, treelines);
958  }
959
960  if ((treelines - topedge + 1) > (screenlines - vmargin)) {
961    printf("** %ld", treelines - (topedge - 1 + screenlines - vmargin));
962    printf(" lines below screen **\n");
963  }
964  if (treelines - topedge + vmargin + 1 < screenlines)
965    putchar('\n');
966  gotlike = -like;
967  changed = false;
968}  /* move_printree */
969
970
971void arbitree()
972{
973  long i;
974
975  root = treenode[0];
976  add2(treenode[0], treenode[1], treenode[spp], &root,
977    restoring, wasleft, treenode);
978  for (i = 3; i <= (spp); i++)
979    add2(treenode[spp+ i - 3], treenode[i - 1], treenode[spp + i - 2],
980      &root, restoring, wasleft, treenode);
981  for (i = 0; i < (nonodes); i++)
982    in_tree[i] = true;
983}  /* arbitree */
984
985
986void yourtree()
987{
988  long i, j;
989  boolean ok;
990
991  root = treenode[0];
992  add2(treenode[0], treenode[1], treenode[spp], &root,
993    restoring, wasleft, treenode);
994  i = 2;
995  do {
996    i++;
997    move_printree();
998    printf("\nAdd species%3ld: \n", i);
999    printf("   \n");
1000    for (j = 0; j < nmlngth; j++)
1001      putchar(nayme[i - 1][j]);
1002    do {
1003      printf("\nbefore node (type number): ");
1004      inpnum(&j, &ok);
1005      ok = (ok && ((j >= 1 && j < i) || (j > spp && j < spp + i - 1)));
1006      if (!ok)
1007        printf("Impossible number. Please try again:\n");
1008    } while (!ok);
1009    add2(treenode[j - 1], treenode[i - 1], treenode[spp + i - 2], &root,
1010      restoring, wasleft, treenode);
1011  } while (i != spp);
1012  for (i = 0; i < (nonodes); i++)
1013    in_tree[i] = true;
1014}  /* yourtree */
1015
1016
1017void initmovenode(node **p, node **grbg, node *q, long len, long nodei,
1018                        long *ntips, long *parens, initops whichinit,
1019                        pointarray treenode, pointarray nodep, Char *str, Char *ch,
1020                        FILE *intree)
1021{
1022  /* initializes a node */
1023  /* LM 7/27  I added this function and the commented lines around */
1024  /* treeread() to get the program running, but all 4 move programs*/
1025  /* are improperly integrated into the v4.0 support files.  As is */
1026  /* this is a patchwork function              */
1027  boolean minusread;
1028  double valyew, divisor;
1029
1030  switch (whichinit) {
1031  case bottom:
1032    gnutreenode(grbg, p, nodei, chars, zeros);
1033    treenode[nodei - 1] = *p;
1034    break;
1035  case nonbottom:
1036    gnutreenode(grbg, p, nodei, chars, zeros);
1037    break;
1038  case tip:
1039    match_names_to_data (str, treenode, p, spp);
1040    break;
1041  case length:
1042    processlength(&valyew, &divisor, ch, &minusread, intree, parens);
1043    /* process lengths and discard */
1044  default:      /*cases hslength,hsnolength,treewt,unittrwt,iter,*/
1045    break;
1046  }
1047} /* initmovenode */
1048
1049
1050void buildtree()
1051{
1052  long i, j, nextnode;
1053  node *p;
1054
1055  changed = false;
1056  newtree = false;
1057  switch (how) {
1058
1059  case arb:
1060    arbitree();
1061    break;
1062
1063  case use:
1064    openfile(&intree,INTREE,"input tree file", "r",progname,intreename);
1065    names = (boolean *)Malloc(spp*sizeof(boolean));
1066    firsttree = true;                                            /**/
1067    nodep = NULL;                                       /**/
1068    nextnode = 0;                                           /**/
1069    haslengths = 0;                                         /**/
1070    zeros = (long *)Malloc(chars*sizeof(long));         /**/
1071    for (i = 0; i < chars; i++)                           /**/
1072      zeros[i] = 0;                                         /**/
1073    treeread(intree, &root, treenode, &goteof, &firsttree,
1074                nodep, &nextnode, &haslengths,
1075                &grbg, initmovenode); /*debug*/
1076    for (i = spp; i < (nonodes); i++) {
1077      p = treenode[i];
1078      for (j = 1; j <= 3; j++) {
1079        p->stateone = (bitptr)Malloc(words*sizeof(long));
1080        p->statezero = (bitptr)Malloc(words*sizeof(long));
1081        p = p->next;
1082      }
1083    } /* debug: see comment at initmovenode() */
1084
1085   /*  treeread(which, ch, &root, treenode, names);*/
1086    for (i = 0; i < (spp); i++)
1087      in_tree[i] = names[i];
1088    free(names);
1089    FClose(intree);
1090    break;
1091
1092  case spec:
1093    yourtree();
1094    break;
1095  }
1096  if (!outgropt)
1097    outgrno = root->next->back->index;
1098  if (outgropt && in_tree[outgrno - 1])
1099    reroot(treenode[outgrno - 1]);
1100}  /* buildtree */
1101
1102
1103void rearrange()
1104{
1105  long i, j;
1106  boolean ok1, ok2;
1107  node *p, *q;
1108
1109  printf("Remove everything to the right of which node? ");
1110  inpnum(&i, &ok1);
1111  ok1 = (ok1 && i >= 1 && i < spp * 2 && i != root->index);
1112  if (ok1) {
1113    printf("Add before which node? ");
1114    inpnum(&j, &ok2);
1115    ok2 = (ok2 && j >= 1 && j < spp * 2);
1116    if (ok2) {
1117      ok2 = (treenode[j - 1] != treenode[treenode[i - 1]->back->index - 1]);
1118      p = treenode[j - 1];
1119      while (p != root) {
1120        ok2 = (ok2 && p != treenode[i - 1]);
1121        p = treenode[p->back->index - 1];
1122      }
1123      if (ok1 && ok2) {
1124        what = i;
1125        q = treenode[treenode[i - 1]->back->index - 1];
1126        if (q->next->back->index == i)
1127          fromwhere = q->next->next->back->index;
1128        else
1129          fromwhere = q->next->back->index;
1130        towhere = j;
1131        re_move2(&treenode[i - 1], &q, &root, &wasleft, treenode);
1132        add2(treenode[j - 1], treenode[i - 1], q, &root,
1133          restoring, wasleft, treenode);
1134      }
1135      lastop = rearr;
1136    }
1137  }
1138  changed = (ok1 && ok2);
1139  move_printree();
1140  if (!(ok1 && ok2))
1141    printf("Not a possible rearrangement.   Try again: ");
1142  else {
1143    oldwritten =written;
1144    written = false;
1145  }
1146}  /* rearrange */
1147
1148
1149void tryadd(node *p, node *item, node *nufork, double *place)
1150{
1151  /* temporarily adds one fork and one tip to the tree.
1152     Records scores in array place */
1153  add2(p, item, nufork, &root, restoring, wasleft, treenode);
1154  evaluate(root);
1155  place[p->index - 1] = -like;
1156  re_move2(&item, &nufork, &root, &wasleft, treenode);
1157}  /* tryadd */
1158
1159
1160void addpreorder(node *p, node *item, node *nufork, double *place)
1161{
1162  /* traverses a binary tree, calling function tryadd
1163     at a node before calling tryadd at its descendants */
1164  if (p == NULL)
1165    return;
1166  tryadd(p,item,nufork,place);
1167  if (!p->tip) {
1168    addpreorder(p->next->back, item, nufork, place);
1169    addpreorder(p->next->next->back, item, nufork, place);
1170  }
1171}  /* addpreorder */
1172
1173
1174void try()
1175{
1176  /* Remove node, try it in all possible places */
1177  double *place;
1178  long i, j, oldcompat;
1179  double current;
1180  node *q, *dummy, *rute;
1181  boolean tied, better, ok;
1182
1183  printf("Try other positions for which node? ");
1184  inpnum(&i, &ok);
1185  if (!(ok && i >= 1 && i <= nonodes && i != root->index)) {
1186    printf("Not a possible choice! ");
1187    return;
1188  }
1189  printf("WAIT ...\n");
1190  place = (double *)Malloc(nonodes*sizeof(double));
1191  for (j = 0; j < (nonodes); j++)
1192    place[j] = -1.0;
1193  evaluate(root);
1194  current = -like;
1195  oldcompat = compatible;
1196  what = i;
1197  q = treenode[treenode[i - 1]->back->index - 1];
1198  if (q->next->back->index == i)
1199    fromwhere = q->next->next->back->index;
1200  else
1201    fromwhere = q->next->back->index;
1202  rute = root;
1203  if (root->index == treenode[i - 1]->back->index) {
1204    if (treenode[treenode[i - 1]->back->index - 1]->next->back == treenode[i - 1])
1205      rute = treenode[treenode[i - 1]->back->index - 1]->next->next->back;
1206    else
1207      rute = treenode[treenode[i - 1]->back->index - 1]->next->back;
1208  }
1209  re_move2(&treenode[i - 1], &dummy, &root, &wasleft, treenode);
1210  oldleft = wasleft;
1211  root = rute;
1212  addpreorder(root, treenode[i - 1], dummy, place);
1213  wasleft =oldleft;
1214  restoring = true;
1215  add2(treenode[fromwhere - 1], treenode[what - 1],dummy, &root,
1216    restoring, wasleft, treenode);
1217  like = -current;
1218  compatible = oldcompat;
1219  restoring = false;
1220  better = false;
1221  printf("          BETTER: ");
1222  for (j = 1; j <= (nonodes); j++) {
1223    if (place[j - 1] < current && place[j - 1] >= 0.0) {
1224      printf("%3ld:%6.2f", j, place[j - 1]);
1225      better = true;
1226    }
1227  }
1228  if (!better)
1229    printf(" NONE");
1230  printf("\n          TIED:    ");
1231  tied = false;
1232  for (j = 1; j <= (nonodes); j++) {
1233    if (fabs(place[j - 1] - current) < 1.0e-6 && j != fromwhere) {
1234      if (j < 10)
1235        printf("%2ld", j);
1236      else
1237        printf("%3ld", j);
1238      tied = true;
1239    }
1240  }
1241  if (tied)
1242    printf(":%6.2f\n", current);
1243  else
1244    printf("NONE\n");
1245  changed = true;
1246  free(place);
1247}  /* try */
1248
1249
1250void undo()
1251{
1252  /* restore to tree before last rearrangement */
1253  long temp;
1254  boolean btemp;
1255  node *q;
1256
1257  switch (lastop) {
1258
1259  case rearr:
1260    restoring = true;
1261    oldleft = wasleft;
1262    re_move2(&treenode[what - 1], &q, &root, &wasleft, treenode);
1263    btemp = wasleft;
1264    wasleft = oldleft;
1265    add2(treenode[fromwhere - 1], treenode[what - 1],q, &root,
1266      restoring, wasleft, treenode);
1267    wasleft = btemp;
1268    restoring = false;
1269    temp = fromwhere;
1270    fromwhere = towhere;
1271    towhere = temp;
1272    changed = true;
1273    break;
1274
1275  case flipp:
1276    q = treenode[atwhat - 1]->next->back;
1277    treenode[atwhat - 1]->next->back =
1278      treenode[atwhat - 1]->next->next->back;
1279    treenode[atwhat - 1]->next->next->back = q;
1280    treenode[atwhat - 1]->next->back->back = treenode[atwhat - 1]->next;
1281    treenode[atwhat - 1]->next->next->back->back =
1282      treenode[atwhat - 1]->next->next;
1283    break;
1284
1285  case reroott:
1286    restoring = true;
1287    temp = oldoutgrno;
1288    oldoutgrno = outgrno;
1289    outgrno = temp;
1290    reroot(treenode[outgrno - 1]);
1291    restoring = false;
1292    break;
1293
1294  case none:
1295    /* blank case */
1296    break;
1297  }
1298  move_printree();
1299  if (lastop == none) {
1300    printf("No operation to undo! \n");
1301    return;
1302  }
1303  btemp = oldwritten;
1304  oldwritten = written;
1305  written = btemp;
1306}  /* undo */
1307
1308
1309void treewrite(boolean done)
1310{
1311  /* write out tree to a file */
1312  Char ch;
1313
1314  treeoptions(waswritten, &ch, &outtree, outtreename, progname);
1315  if (!done)
1316    move_printree();
1317  if (waswritten && ch == 'N')
1318    return;
1319  col = 0;
1320  treeout(root, 1, &col, root);
1321  printf("\nTree written to file \"%s\"\n\n", outtreename);
1322  waswritten = true;
1323  written = true;
1324  FClose(outtree);
1325#ifdef MAC
1326  fixmacfile(outtreename);
1327#endif
1328}
1329  /* treewrite */
1330
1331
1332void clade()
1333{
1334  /* pick a subtree and show only that on screen */
1335  long i;
1336  boolean ok;
1337
1338  printf("Select subtree rooted at which node (0 for whole tree)? ");
1339  inpnum(&i, &ok);
1340  ok = (ok && (unsigned)i <= nonodes);
1341  if (ok) {
1342    subtree = (i > 0);
1343    if (subtree)
1344      nuroot = treenode[i - 1];
1345    else
1346      nuroot = root;
1347  }
1348  move_printree();
1349  if (!ok)
1350    printf("Not possible to use this node. ");
1351}  /* clade */
1352
1353
1354void flip()
1355{
1356  /* flip at a node left-right */
1357  long i;
1358  boolean ok;
1359  node *p;
1360
1361  printf("Flip branches at which node? ");
1362  inpnum(&i, &ok);
1363  ok = (ok && i > spp && i <= nonodes);
1364  if (ok) {
1365    p = treenode[i - 1]->next->back;
1366    treenode[i - 1]->next->back = treenode[i - 1]->next->next->back;
1367    treenode[i - 1]->next->next->back = p;
1368    treenode[i - 1]->next->back->back = treenode[i - 1]->next;
1369    treenode[i - 1]->next->next->back->back = treenode[i - 1]->next->next;
1370    atwhat = i;
1371    lastop = flipp;
1372  }
1373  move_printree();
1374  if (ok) {
1375    oldwritten = written;
1376    written = false;
1377    return;
1378  }
1379  if (i >= 1 && i <= spp)
1380    printf("Can't flip there. ");
1381  else
1382    printf("No such node. ");
1383}  /* flip */
1384
1385
1386void changeoutgroup()
1387{
1388  long i;
1389  boolean ok;
1390
1391  oldoutgrno = outgrno;
1392  do {
1393    printf("Which node should be the new outgroup? ");
1394    inpnum(&i, &ok);
1395    ok = (ok && in_tree[i - 1] && i >= 1 && i <= nonodes &&
1396          i != root->index);
1397    if (ok)
1398      outgrno = i;
1399  } while (!ok);
1400  if (in_tree[outgrno - 1])
1401    reroot(treenode[outgrno - 1]);
1402  changed = true;
1403  lastop = reroott;
1404  move_printree();
1405  oldwritten = written;
1406  written = false;
1407}  /* changeoutgroup */
1408
1409
1410void redisplay()
1411{
1412  boolean done=false;
1413  waswritten = false;
1414  do {
1415    printf("\nNEXT? (Options: R # + - S . T U W O F H J K L C ? X Q) ");
1416    printf("(? for Help) ");
1417#ifdef WIN32
1418    phyFillScreenColor();
1419#endif
1420    scanf("%c%*[^\n]", &ch);
1421    getchar();
1422    if (ch == '\n')
1423      ch = ' ';
1424    uppercase(&ch);
1425    if (strchr("R#+-S.TUWOFHJKLC?XQ",ch) != NULL){
1426      switch (ch) {
1427
1428      case 'R':
1429        rearrange();
1430        break;
1431
1432      case '#':
1433        nextinc(&dispchar, &dispword, &dispbit, chars, bits, &display,
1434                  numsteps, weight);
1435        move_printree();
1436        break;
1437
1438      case '+':
1439        nextchar(&dispchar, &dispword, &dispbit, chars, bits, &display);
1440        move_printree();
1441        break;
1442
1443      case '-':
1444        prevchar(&dispchar, &dispword, &dispbit, chars, bits, &display);
1445        move_printree();
1446        break;
1447
1448      case 'S':
1449        show(&dispchar, &dispword, &dispbit, chars, bits, &display);
1450        move_printree();
1451        break;
1452
1453      case '.':
1454        move_printree();
1455        break;
1456
1457      case 'T':
1458        try();
1459        break;
1460
1461      case 'U':
1462        undo();
1463        break;
1464
1465      case 'W':
1466        treewrite(done);
1467        break;
1468
1469      case 'O':
1470        changeoutgroup();
1471        break;
1472
1473      case 'F':
1474        flip();
1475        break;
1476
1477      case 'H':
1478        window(left, &leftedge, &topedge, hscroll, vscroll, treelines,
1479                 screenlines, screenwidth, farthest, subtree);
1480        move_printree();
1481        break;
1482
1483      case 'J':
1484        window(downn, &leftedge, &topedge, hscroll, vscroll, treelines,
1485                 screenlines, screenwidth, farthest, subtree);
1486        move_printree();
1487        break;
1488
1489      case 'K':
1490        window(upp, &leftedge, &topedge, hscroll, vscroll, treelines,
1491                 screenlines, screenwidth, farthest, subtree);
1492        move_printree();
1493        break;
1494
1495      case 'L':
1496        window(right, &leftedge, &topedge, hscroll, vscroll, treelines,
1497                 screenlines, screenwidth, farthest, subtree);
1498        move_printree();
1499        break;
1500
1501      case 'C':
1502        clade();
1503        break;
1504
1505      case '?':
1506        help("character");
1507        move_printree();
1508        break;
1509
1510      case 'X':
1511        done = true;
1512        break;
1513
1514      case 'Q':
1515        done = true;
1516        break;
1517      }
1518    }
1519  } while (!done);
1520  if (!written) {
1521    do {
1522      printf("Do you want to write out the tree to a file? (Y or N) ");
1523#ifdef WIN32
1524      phyFillScreenColor();
1525#endif
1526      scanf("%c%*[^\n]", &ch);
1527      getchar();
1528      if (ch == '\n')
1529        ch = ' ';
1530    } while (ch != 'Y' && ch != 'y' && ch != 'N' && ch != 'n');
1531  }
1532  if (ch == 'Y' || ch == 'y')
1533    treewrite(done);
1534}  /* redisplay */
1535
1536
1537void treeconstruct()
1538{
1539  /* constructs a binary tree from the pointers in treenode. */
1540
1541  restoring = false;
1542  subtree = false;
1543  display = false;
1544  dispchar = 0;
1545  fullset = (1L << (bits + 1)) - (1L << 1);
1546  earlytree = true;
1547  buildtree();
1548  waswritten = false;
1549  printf("\nComputing steps needed for compatibility in characters...\n\n");
1550  newtree = true;
1551  earlytree = false;
1552  move_printree();
1553  bestyet = -like;
1554  gotlike = -like;
1555  lastop = none;
1556  newtree = false;
1557  written = false;
1558  redisplay();
1559}  /* treeconstruct */
1560
1561
1562int main(int argc, Char *argv[])
1563{  /* Interactive mixed parsimony                                      */
1564   /* reads in spp, chars, and the data. Then calls treeconstruct to   */
1565   /*  construct the tree and query the user                           */
1566#ifdef MAC
1567  argc = 1;                /* macsetup("Move","");                */
1568  argv[0] = "Move";
1569#endif
1570  init(argc, argv);
1571  progname = argv[0];
1572  strcpy(infilename,INFILE);
1573  strcpy(intreename,INTREE);
1574  strcpy(outtreename,OUTTREE);
1575  openfile(&infile,infilename,"input file", "r",argv[0],infilename);
1576
1577  screenlines = 24;
1578  scrollinc = 20;
1579  screenwidth = 80;
1580  topedge = 1;
1581  leftedge = 1;
1582  ibmpc = IBMCRT;
1583  ansi = ANSICRT;
1584  root = NULL;
1585  bits = 8*sizeof(long) - 1;
1586  doinput();
1587  configure();
1588  treeconstruct();
1589  FClose(outtree);
1590#ifdef MAC
1591  fixmacfile(outtreename);
1592#endif
1593#ifdef WIN32
1594  phyRestoreConsoleAttributes();
1595#endif
1596  return 0;
1597}  /* Interactive mixed parsimony */
Note: See TracBrowser for help on using the repository browser.