source: tags/initial/GDE/CLUSTALW/calctree.c

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.1 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <math.h>
5#include <stdarg.h>
6#include <ctype.h>
7#include "clustalw.h"
8
9/*
10 *   Prototypes
11 */
12static void create_tree(treeptr ptree, treeptr parent);
13static void create_node(treeptr pptr, treeptr parent);
14static treeptr insert_node(treeptr pptr);
15static void skip_space(FILE *fd);
16static treeptr avail(void);
17static void set_info(treeptr p, treeptr parent, sint pleaf, char *pname, float pdist);
18static treeptr reroot(treeptr ptree, sint nseqs);
19static treeptr insert_root(treeptr p, float diff);
20static float calc_root_mean(treeptr root, float *maxdist);
21static float calc_mean(treeptr nptr, float *maxdist, sint nseqs);
22static void order_nodes(void);
23static sint calc_weight(sint leaf);
24static void group_seqs(treeptr p, sint *next_groups, sint nseqs);
25static void mark_group1(treeptr p, sint *groups, sint n);
26static void mark_group2(treeptr p, sint *groups, sint n);
27static void save_set(sint n, sint *groups);
28static void clear_tree_nodes(treeptr p);
29
30
31/*
32 *   Global variables
33 */
34extern Boolean interactive;
35extern Boolean distance_tree;
36extern Boolean usemenu;
37extern sint debug;
38extern double **tmat;
39extern sint **sets;
40extern sint nsets;
41extern char **names;
42extern sint *seq_weight;
43
44char ch;
45FILE *fd;
46treeptr *lptr;
47treeptr *olptr;
48treeptr *nptr;
49treeptr *ptrs;
50sint nnodes = 0;
51sint ntotal = 0;
52Boolean rooted_tree = TRUE;
53static treeptr seq_tree,root;
54static sint *groups, numseq;
55
56void calc_seq_weights(sint first_seq, sint last_seq, sint *sweight)
57{
58  sint   i, nseqs;
59  sint   temp, sum, *weight;
60
61
62/*
63  If there are more than three sequences....
64*/
65  nseqs = last_seq-first_seq;
66  if ((nseqs > 3) && (distance_tree == TRUE))
67     {
68/*
69  Calculate sequence weights based on Phylip tree.
70*/
71      weight = (sint *)ckalloc((last_seq+1) * sizeof(sint));
72
73      for (i=first_seq; i<last_seq; i++)
74           weight[i] = calc_weight(i);
75
76/*
77  Normalise the weights, such that the sum of the weights = INT_SCALE_FACTOR
78*/
79
80         sum = 0;
81         for (i=first_seq; i<last_seq; i++)
82            sum += weight[i];
83
84         if (sum == 0)
85          {
86            for (i=first_seq; i<last_seq; i++)
87               weight[i] = 1;
88            sum = i;
89          }
90
91         for (i=first_seq; i<last_seq; i++)
92           {
93              sweight[i] = (weight[i] * INT_SCALE_FACTOR) / sum;
94              if (sweight[i] < 1) sweight[i] = 1;
95           }
96
97       weight=ckfree((void *)weight);
98
99     }
100
101   else
102     {
103/*
104  Otherwise, use identity weights.
105*/
106        temp = INT_SCALE_FACTOR / nseqs;
107        for (i=first_seq; i<last_seq; i++)
108           sweight[i] = temp;
109     }
110
111}
112
113void create_sets(sint first_seq, sint last_seq)
114{
115  sint   i, j, nseqs;
116
117  nsets = 0;
118  nseqs = last_seq-first_seq;
119  if (nseqs > 3)
120     {
121/*
122  If there are more than three sequences....
123*/
124       groups = (sint *)ckalloc((nseqs+1) * sizeof(sint));
125       group_seqs(root, groups, nseqs);
126       groups=ckfree((void *)groups);
127
128     }
129
130   else
131     {
132       groups = (sint *)ckalloc((nseqs+1) * sizeof(sint));
133       for (i=0;i<nseqs-1;i++)
134         {
135           for (j=0;j<nseqs;j++)
136              if (j<=i) groups[j] = 1;
137              else if (j==i+1) groups[j] = 2;
138              else groups[j] = 0;
139           save_set(nseqs, groups);
140         }
141       groups=ckfree((void *)groups);
142     }
143
144}
145
146sint read_tree(char *treefile, sint first_seq, sint last_seq)
147{
148
149  char c;
150  char name1[MAXNAMES+1], name2[MAXNAMES+1];
151  sint i, j, k;
152  Boolean found;
153
154  numseq = 0;
155  nnodes = 0;
156  ntotal = 0;
157  rooted_tree = TRUE;
158
159#ifdef VMS
160  if ((fd = fopen(treefile,"r","rat=cr","rfm=var")) == NULL)
161#else
162  if ((fd = fopen(treefile, "r")) == NULL)
163#endif
164    {
165      error("cannot open %s", treefile);
166      return((sint)0);
167    }
168
169  skip_space(fd);
170  ch = (char)getc(fd);
171  if (ch != '(')
172    {
173      error("Wrong format in tree file %s", treefile);
174      return((sint)0);
175    }
176  rewind(fd);
177
178  distance_tree = TRUE;
179
180/*
181  Allocate memory for tree
182*/
183  nptr = (treeptr *)ckalloc(3*(last_seq-first_seq+1) * sizeof(treeptr));
184  ptrs = (treeptr *)ckalloc(3*(last_seq-first_seq+1) * sizeof(treeptr));
185  lptr = (treeptr *)ckalloc((last_seq-first_seq+1) * sizeof(treeptr));
186  olptr = (treeptr *)ckalloc((last_seq+1) * sizeof(treeptr));
187 
188  seq_tree = avail();
189  set_info(seq_tree, NULL, 0, "", 0.0);
190
191  create_tree(seq_tree,NULL);
192  fclose(fd);
193
194
195  if (numseq != last_seq-first_seq)
196     {
197         error("tree not compatible with alignment\n(%d sequences in alignment and %d in tree", (pint)last_seq-first_seq,(pint)numseq);
198         return((sint)0);
199     }
200
201/*
202  If the tree is unrooted, reroot the tree - ie. minimise the difference
203  between the mean root->leaf distances for the left and right branches of
204  the tree.
205*/
206
207  if (distance_tree == FALSE)
208     {
209        if (rooted_tree == FALSE)
210          {
211             error("input tree is unrooted and has no distances.\nCannot align sequences");
212             return((sint)0);
213          }
214     }
215
216  if (rooted_tree == FALSE)
217     {
218        root = reroot(seq_tree, last_seq-first_seq+1);
219     }
220  else
221     {
222        root = seq_tree;
223     }
224
225/*
226  calculate the 'order' of each node.
227*/
228  order_nodes();
229
230  if (numseq > 3)
231     {
232/*
233  If there are more than three sequences....
234*/
235/*
236  assign the sequence nodes (in the same order as in the alignment file)
237*/
238      for (i=first_seq; i<last_seq; i++)
239       {
240         if (strlen(names[i+1]) > MAXNAMES)
241             warning("name %s is too long for PHYLIP tree format (max %d chars)", names[i+1],MAXNAMES);
242
243         for (k=0; k< strlen(names[i+1]) && k<MAXNAMES ; k++)
244           {
245             c = names[i+1][k];
246             if ((c>0x40) && (c<0x5b)) c=c | 0x20;
247             if (c == ' ') c = '_';
248             name2[k] = c;
249           }
250         name2[k]='\0';
251         found = FALSE;
252         for (j=0; j<numseq; j++)
253           {
254            for (k=0; k< strlen(lptr[j]->name) && k<MAXNAMES ; k++)
255              {
256                c = lptr[j]->name[k];
257                if ((c>0x40) && (c<0x5b)) c=c | 0x20;
258                name1[k] = c;
259              }
260            name1[k]='\0';
261            if (strcmp(name1, name2) == 0)
262              {
263                olptr[i] = lptr[j];
264                found = TRUE;
265              }
266           }
267         if (found == FALSE)
268           {
269             error("tree not compatible with alignment:\n%s not found", name2);
270             return((sint)0);
271           }
272       }
273
274     }
275   return((sint)1);
276}
277
278static void create_tree(treeptr ptree, treeptr parent)
279{
280   treeptr p;
281
282   sint i, type;
283   float dist;
284   char name[MAXNAMES+1];
285
286/*
287  is this a node or a leaf ?
288*/
289  skip_space(fd);
290  ch = (char)getc(fd);
291  if (ch == '(')
292    { 
293/*
294   this must be a node....
295*/
296      type = NODE;
297      name[0] = '\0';
298      ptrs[ntotal] = nptr[nnodes] = ptree;
299      nnodes++;
300      ntotal++;
301
302      create_node(ptree, parent);
303
304      p = ptree->left;
305      create_tree(p, ptree);
306           
307      if ( ch == ',')
308       {
309          p = ptree->right;
310          create_tree(p, ptree);
311          if ( ch == ',')
312            {
313               ptree = insert_node(ptree);
314               ptrs[ntotal] = nptr[nnodes] = ptree;
315               nnodes++;
316               ntotal++;
317               p = ptree->right;
318               create_tree(p, ptree);
319               rooted_tree = FALSE;
320            }
321       }
322
323      skip_space(fd);
324      ch = (char)getc(fd);
325    }
326/*
327   ...otherwise, this is a leaf
328*/
329  else
330    {
331      type = LEAF;
332      ptrs[ntotal++] = lptr[numseq++] = ptree;
333/*
334   get the sequence name
335*/
336      name[0] = ch;
337      ch = (char)getc(fd);
338      i = 1;
339      while ((ch != ':') && (ch != ',') && (ch != ')'))
340        {
341          if (i < MAXNAMES) name[i++] = ch;
342          ch = (char)getc(fd);
343        }
344      name[i] = '\0';
345      if (ch != ':')
346         {
347           distance_tree = FALSE;
348           dist = 0.0;
349         }
350    }
351
352/*
353   get the distance information
354*/
355  dist = 0.0;
356  if (ch == ':')
357     {
358       skip_space(fd);
359       fscanf(fd,"%f",&dist);
360       skip_space(fd);
361       ch = (char)getc(fd);
362     }
363   set_info(ptree, parent, type, name, dist);
364
365
366}
367
368static void create_node(treeptr pptr, treeptr parent)
369{
370  treeptr t;
371
372  pptr->parent = parent;
373  t = avail();
374  pptr->left = t;
375  t = avail();
376  pptr->right = t;
377   
378}
379
380static treeptr insert_node(treeptr pptr)
381{
382
383   treeptr newnode;
384
385   newnode = avail();
386   create_node(newnode, pptr->parent);
387
388   newnode->left = pptr;
389   pptr->parent = newnode;
390
391   set_info(newnode, pptr->parent, NODE, "", 0.0);
392
393   return(newnode);
394}
395
396static void skip_space(FILE *fd)
397{
398  int   c;
399 
400  do
401     c = getc(fd);
402  while(isspace(c));
403
404  ungetc(c, fd);
405}
406
407static treeptr avail(void)
408{
409   treeptr p;
410   p = ckalloc(sizeof(stree));
411   p->left = NULL;
412   p->right = NULL;
413   p->parent = NULL;
414   p->dist = 0.0;
415   p->leaf = 0;
416   p->order = 0;
417   p->name[0] = '\0';
418   return(p);
419}
420
421void clear_tree(treeptr p)
422{
423   clear_tree_nodes(p);
424     
425   nptr=ckfree((void *)nptr);
426   ptrs=ckfree((void *)ptrs);
427   lptr=ckfree((void *)lptr);
428   olptr=ckfree((void *)olptr);
429}
430
431static void clear_tree_nodes(treeptr p)
432{
433   if (p==NULL) p = root;
434   if (p->left != NULL)
435     {
436       clear_tree_nodes(p->left);
437     }
438   if (p->right != NULL)
439     {
440       clear_tree_nodes(p->right);
441     }
442   p->left = NULL;
443   p->right = NULL;
444   p=ckfree((void *)p);   
445}
446
447static void set_info(treeptr p, treeptr parent, sint pleaf, char *pname, float pdist)
448{
449   p->parent = parent;
450   p->leaf = pleaf;
451   p->dist = pdist;
452   p->order = 0;
453   strcpy(p->name, pname);
454   if (p->leaf == TRUE)
455     {
456        p->left = NULL;
457        p->right = NULL;
458     }
459}
460
461static treeptr reroot(treeptr ptree, sint nseqs)
462{
463
464   treeptr p, rootnode, rootptr;
465   float   diff, mindiff = 0.0, mindepth = 1.0, maxdist;
466   sint   i;
467   Boolean first = TRUE;
468
469/*
470  find the difference between the means of leaf->node
471  distances on the left and on the right of each node
472*/
473   rootptr = ptree;
474   for (i=0; i<ntotal; i++)
475     {
476        p = ptrs[i];
477        if (p->parent == NULL)
478           diff = calc_root_mean(p, &maxdist);
479        else
480           diff = calc_mean(p, &maxdist, nseqs);
481
482        if ((diff == 0) || ((diff > 0) && (diff < 2 * p->dist)))
483          {
484              if ((maxdist < mindepth) || (first == TRUE))
485                 {
486                    first = FALSE;
487                    rootptr = p;
488                    mindepth = maxdist;
489                    mindiff = diff;
490                 }
491           }
492
493     }
494
495/*
496  insert a new node as the ancestor of the node which produces the shallowest
497  tree.
498*/
499   if (rootptr == ptree)
500     {
501        mindiff = rootptr->left->dist + rootptr->right->dist;
502        rootptr = rootptr->right;
503     }
504   rootnode = insert_root(rootptr, mindiff);
505 
506   diff = calc_root_mean(rootnode, &maxdist);
507
508   return(rootnode);
509}
510
511static treeptr insert_root(treeptr p, float diff)
512{
513   treeptr newp, prev, q, t;
514   float dist, prevdist,td;
515
516   newp = avail();
517
518   t = p->parent;
519   prevdist = t->dist;
520
521   p->parent = newp;
522
523   dist = p->dist;
524
525   p->dist = diff / 2;
526   if (p->dist < 0.0) p->dist = 0.0;
527   if (p->dist > dist) p->dist = dist;
528
529   t->dist = dist - p->dist; 
530
531   newp->left = t;
532   newp->right = p;
533   newp->parent = NULL;
534   newp->dist = 0.0;
535   newp->leaf = NODE;
536
537   if (t->left == p) t->left = t->parent;
538   else t->right = t->parent;
539
540   prev = t;
541   q = t->parent;
542
543   t->parent = newp;
544
545   while (q != NULL)
546     {
547        if (q->left == prev)
548           {
549              q->left = q->parent;
550              q->parent = prev;
551              td = q->dist;
552              q->dist = prevdist;
553              prevdist = td;
554              prev = q;
555              q = q->left;
556           }
557        else
558           {
559              q->right = q->parent;
560              q->parent = prev;
561              td = q->dist;
562              q->dist = prevdist;
563              prevdist = td;
564              prev = q;
565              q = q->right;
566           }
567    }
568
569/*
570   remove the old root node
571*/
572   q = prev;
573   if (q->left == NULL)
574      {
575         dist = q->dist;
576         q = q->right;
577         q->dist += dist;
578         q->parent = prev->parent;
579         if (prev->parent->left == prev)
580            prev->parent->left = q;
581         else
582            prev->parent->right = q;
583         prev->right = NULL;
584      }
585   else
586      {
587         dist = q->dist;
588         q = q->left;
589         q->dist += dist;
590         q->parent = prev->parent;
591         if (prev->parent->left == prev)
592            prev->parent->left = q;
593         else
594            prev->parent->right = q;
595         prev->left = NULL;
596      }
597
598   return(newp);
599}
600
601static float calc_root_mean(treeptr root, float *maxdist)
602{
603   float dist , lsum = 0.0, rsum = 0.0, lmean,rmean,diff;
604   treeptr p;
605   sint i;
606   sint nl, nr;
607   sint direction;
608/*
609   for each leaf, determine whether the leaf is left or right of the root.
610*/
611   dist = (*maxdist) = 0;
612   nl = nr = 0;
613   for (i=0; i< numseq; i++)
614     {
615         p = lptr[i];
616         dist = 0.0;
617         while (p->parent != root)
618           {
619               dist += p->dist;
620               p = p->parent;
621           }
622         if (p == root->left) direction = LEFT;
623         else direction = RIGHT;
624         dist += p->dist;
625
626         if (direction == LEFT)
627           {
628             lsum += dist;
629             nl++;
630           }
631         else
632           {
633             rsum += dist;
634             nr++;
635           }
636        if (dist > (*maxdist)) *maxdist = dist;
637     }
638
639   lmean = lsum / nl;
640   rmean = rsum / nr;
641
642   diff = lmean - rmean;
643   return(diff);
644}
645
646
647static float calc_mean(treeptr nptr, float *maxdist, sint nseqs)
648{
649   float dist , lsum = 0.0, rsum = 0.0, lmean,rmean,diff;
650   treeptr p, *path2root;
651   float *dist2node;
652   sint depth = 0, i,j , n = 0;
653   sint nl , nr;
654   sint direction, found;
655
656        path2root = (treeptr *)ckalloc(nseqs * sizeof(treeptr));
657        dist2node = (float *)ckalloc(nseqs * sizeof(float));
658/*
659   determine all nodes between the selected node and the root;
660*/
661   depth = (*maxdist) = dist = 0;
662   nl = nr = 0;
663   p = nptr;
664   while (p != NULL)
665     {
666         path2root[depth] = p;
667         dist += p->dist;
668         dist2node[depth] = dist;
669         p = p->parent;
670         depth++;
671     }
672 
673/*
674   *nl = *nr = 0;
675   for each leaf, determine whether the leaf is left or right of the node.
676   (RIGHT = descendant, LEFT = not descendant)
677*/
678   for (i=0; i< numseq; i++)
679     {
680       p = lptr[i];
681       if (p == nptr)
682         {
683            direction = RIGHT;
684            dist = 0.0;
685         }
686       else
687         {
688         direction = LEFT;
689         dist = 0.0;
690/*
691   find the common ancestor.
692*/
693         found = FALSE;
694         n = 0;
695         while ((found == FALSE) && (p->parent != NULL))
696           {
697               for (j=0; j< depth; j++)
698                 if (p->parent == path2root[j])
699                    { 
700                      found = TRUE;
701                      n = j;
702                    }
703               dist += p->dist;
704               p = p->parent;
705           }
706         if (p == nptr) direction = RIGHT;
707         }
708
709         if (direction == LEFT)
710           {
711             lsum += dist;
712             lsum += dist2node[n-1];
713             nl++;
714           }
715         else
716           {
717             rsum += dist;
718             nr++;
719           }
720
721        if (dist > (*maxdist)) *maxdist = dist;
722     }
723
724        dist2node=ckfree((void *)dist2node);
725        path2root=ckfree((void *)path2root);
726       
727   lmean = lsum / nl;
728   rmean = rsum / nr;
729   
730   diff = lmean - rmean;
731   return(diff);
732}
733
734static void order_nodes(void)
735{
736   sint i;
737   treeptr p;
738
739   for (i=0; i<numseq; i++)
740     {
741        p = lptr[i];
742        while (p != NULL)
743          {
744             p->order++;
745             p = p->parent;
746          }
747     }
748}
749
750
751static sint calc_weight(sint leaf)
752{
753
754  treeptr p;
755  float weight = 0.0;
756
757  p = olptr[leaf];
758  while (p->parent != NULL)
759    {
760       weight += p->dist / p->order;
761       p = p->parent;
762    }
763
764  weight *= 100.0;
765
766  return((sint)weight);
767
768}
769
770static void group_seqs(treeptr p, sint *next_groups, sint nseqs)
771{
772    sint i;
773    sint *tmp_groups;
774
775    tmp_groups = (sint *)ckalloc((nseqs+1) * sizeof(sint));
776    for (i=0;i<nseqs;i++)
777         tmp_groups[i] = 0;
778
779    if (p->left != NULL)
780      {
781         if (p->left->leaf == NODE)
782            {
783               group_seqs(p->left, next_groups, nseqs);
784               for (i=0;i<nseqs;i++)
785                 if (next_groups[i] != 0) tmp_groups[i] = 1;
786            }
787         else
788            {
789               mark_group1(p->left, tmp_groups, nseqs);
790            }
791               
792      }
793
794    if (p->right != NULL)
795      {
796         if (p->right->leaf == NODE)
797            {
798               group_seqs(p->right, next_groups, nseqs);
799               for (i=0;i<nseqs;i++)
800                    if (next_groups[i] != 0) tmp_groups[i] = 2;
801            }
802         else 
803            {
804               mark_group2(p->right, tmp_groups, nseqs);
805            }
806         save_set(nseqs, tmp_groups);
807      }
808    for (i=0;i<nseqs;i++)
809      next_groups[i] = tmp_groups[i];
810
811    tmp_groups=ckfree((void *)tmp_groups);
812
813}
814
815static void mark_group1(treeptr p, sint *groups, sint n)
816{
817    sint i;
818
819    for (i=0;i<n;i++)
820       {
821         if (olptr[i] == p)
822              groups[i] = 1;
823         else
824              groups[i] = 0;
825       }
826}
827
828static void mark_group2(treeptr p, sint *groups, sint n)
829{
830    sint i;
831
832    for (i=0;i<n;i++)
833       {
834         if (olptr[i] == p)
835              groups[i] = 2;
836         else if (groups[i] != 0)
837              groups[i] = 1;
838       }
839}
840
841static void save_set(sint n, sint *groups)
842{
843    sint i;
844
845    for (i=0;i<n;i++)
846      sets[nsets+1][i+1] = groups[i];
847    nsets++;
848}
849
850
851
852sint calc_similarities(sint nseqs)
853{
854   sint depth = 0, i,j, k, n;
855   sint found;
856   sint nerrs, *seq1,*seq2;
857   treeptr p, *path2root;
858   float dist;
859   float *dist2node, *bad_dist;
860   double **dmat;
861   char err_mess[MAXLINE],err1[MAXLINE],reply[MAXLINE];
862
863   path2root = (treeptr *)ckalloc((nseqs) * sizeof(treeptr));
864   dist2node = (float *)ckalloc((nseqs) * sizeof(float));
865   dmat = (double **)ckalloc((nseqs) * sizeof(double *));
866   for (i=0;i<nseqs;i++)
867     dmat[i] = (double *)ckalloc((nseqs) * sizeof(double));
868   seq1 = (sint *)ckalloc((nseqs) * sizeof(sint));
869   seq2 = (sint *)ckalloc((nseqs) * sizeof(sint));
870   bad_dist = (float *)ckalloc((nseqs) * sizeof(float));
871
872   if (nseqs > 3)
873    {
874/*
875   for each leaf, determine all nodes between the leaf and the root;
876*/
877      for (i = 0;i<nseqs; i++)
878       { 
879          depth = dist = 0;
880          p = olptr[i];
881          while (p != NULL)
882            {
883                path2root[depth] = p;
884                dist += p->dist;
885                dist2node[depth] = dist;
886                p = p->parent;
887                depth++;
888            }
889 
890/*
891   for each pair....
892*/
893          for (j=0; j < i; j++)
894            {
895              p = olptr[j];
896              dist = 0.0;
897/*
898   find the common ancestor.
899*/
900              found = FALSE;
901              n = 0;
902              while ((found == FALSE) && (p->parent != NULL))
903                {
904                    for (k=0; k< depth; k++)
905                      if (p->parent == path2root[k])
906                         { 
907                           found = TRUE;
908                           n = k;
909                         }
910                    dist += p->dist;
911                    p = p->parent;
912                }
913   
914              dmat[i][j] = dist + dist2node[n-1];
915            }
916        }
917
918                nerrs = 0;
919        for (i=0;i<nseqs;i++)
920          {
921             dmat[i][i] = 0.0;
922             for (j=0;j<i;j++)
923               {
924                  if (dmat[i][j] < 0.01) dmat[i][j] = 0.01;
925                  if (dmat[i][j] > 1.0) {
926                        if (dmat[i][j] > 1.1) {
927                                seq1[nerrs] = i;
928                                seq2[nerrs] = j;
929                                bad_dist[nerrs] = dmat[i][j];
930                                nerrs++;
931                        }
932                    dmat[i][j] = 1.0;
933                  }
934               }
935          }
936        if (nerrs>0) 
937          {
938             strcpy(err_mess,"The following sequences are too divergent to be aligned:\n");
939             for (i=0;i<nerrs && i<5;i++)
940              {
941                sprintf(err1,"           %s and %s (distance %1.3f)\n",
942                                        names[seq1[i]+1],
943                                        names[seq2[i]+1],bad_dist[i]);
944                strcat(err_mess,err1);
945              }
946             strcat(err_mess,"(All distances should be between 0.0 and 1.0)\n");
947             strcat(err_mess,"This may not be fatal but you have been warned!\n");
948             strcat(err_mess,"SUGGESTION: Remove one or more problem sequences and try again");
949             if(interactive) 
950                    (*reply)=prompt_for_yes_no(err_mess,"Continue ");
951             else (*reply) = 'y';
952             if ((*reply != 'y') && (*reply != 'Y'))
953                    return((sint)0);
954          }
955     }
956   else
957     {
958        for (i=0;i<nseqs;i++)
959          {
960             for (j=0;j<i;j++)
961               {
962                  dmat[i][j] = tmat[i+1][j+1];
963               }
964          }
965     }
966
967   path2root=ckfree((void *)path2root);
968   dist2node=ckfree((void *)dist2node);
969   for (i=0;i<nseqs;i++)
970     {
971        tmat[i+1][i+1] = 0.0;
972        for (j=0;j<i;j++)
973          {
974             tmat[i+1][j+1] = 100.0 - (dmat[i][j]) * 100.0;
975             tmat[j+1][i+1] = tmat[i+1][j+1];
976          }
977     }
978
979   for (i=0;i<nseqs;i++) dmat[i]=ckfree((void *)dmat[i]);
980   dmat=ckfree((void *)dmat);
981
982   return((sint)1);
983}
984
Note: See TracBrowser for help on using the repository browser.