source: trunk/GDE/PHYLIP/move.c

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