source: branches/nameserver/GDE/CLUSTALW/calctree.c

Last change on this file was 1754, checked in by westram, 21 years ago

updated to version 1.83

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