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

Last change on this file was 19480, checked in by westram, 21 months ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.3 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, const 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         {
247             int currNameLen = strlen(names[i+1]);
248             for (k=0; k<currNameLen && k<MAXNAMES ; k++)
249             {
250                 c = names[i+1][k];
251                 if ((c>0x40) && (c<0x5b)) c=c | 0x20;
252                 if (c == ' ') c = '_';
253                 name2[k] = c;
254             }
255         }
256         name2[k]='\0';
257         found = FALSE;
258         for (j=0; j<numseq; j++)
259         {
260             {
261                 int lptrJNameLen = strlen(lptr[j]->name);
262                 for (k=0; k<lptrJNameLen && k<MAXNAMES ; k++)
263                 {
264                     c = lptr[j]->name[k];
265                     if ((c>0x40) && (c<0x5b)) c=c | 0x20;
266                     name1[k] = c;
267                   }
268               }
269               name1[k]='\0';
270            if (strcmp(name1, name2) == 0)
271              {
272                olptr[i] = lptr[j];
273                found = TRUE;
274              }
275           }
276         if (found == FALSE)
277           {
278             error("tree not compatible with alignment:\n%s not found", name2);
279             return((sint)0);
280           }
281       }
282
283     }
284   return((sint)1);
285}
286
287static void create_tree(treeptr ptree, treeptr parent)
288{
289   treeptr p;
290
291   sint i, type;
292   float dist;
293   char name[MAXNAMES+1];
294
295/*
296  is this a node or a leaf ?
297*/
298  skip_space(fd);
299  ch = (char)getc(fd);
300  if (ch == '(')
301    { 
302/*
303   this must be a node....
304*/
305      type = NODE;
306      name[0] = '\0';
307      ptrs[ntotal] = nptr[nnodes] = ptree;
308      nnodes++;
309      ntotal++;
310
311      create_node(ptree, parent);
312
313      p = ptree->left;
314      create_tree(p, ptree);
315           
316      if ( ch == ',')
317       {
318          p = ptree->right;
319          create_tree(p, ptree);
320          if ( ch == ',')
321            {
322               ptree = insert_node(ptree);
323               ptrs[ntotal] = nptr[nnodes] = ptree;
324               nnodes++;
325               ntotal++;
326               p = ptree->right;
327               create_tree(p, ptree);
328               rooted_tree = FALSE;
329            }
330       }
331
332      skip_space(fd);
333      ch = (char)getc(fd);
334    }
335/*
336   ...otherwise, this is a leaf
337*/
338  else
339    {
340      type = LEAF;
341      ptrs[ntotal++] = lptr[numseq++] = ptree;
342/*
343   get the sequence name
344*/
345      name[0] = ch;
346      ch = (char)getc(fd);
347      i = 1;
348      while ((ch != ':') && (ch != ',') && (ch != ')'))
349        {
350          if (i < MAXNAMES) name[i++] = ch;
351          ch = (char)getc(fd);
352        }
353      name[i] = '\0';
354      if (ch != ':')
355         {
356           distance_tree = FALSE;
357           dist = 0.0;
358         }
359    }
360
361/*
362   get the distance information
363*/
364  dist = 0.0;
365  if (ch == ':')
366     {
367       skip_space(fd);
368       fscanf(fd,"%f",&dist);
369       skip_space(fd);
370       ch = (char)getc(fd);
371     }
372   set_info(ptree, parent, type, name, dist);
373
374
375}
376
377static void create_node(treeptr pptr, treeptr parent)
378{
379  treeptr t;
380
381  pptr->parent = parent;
382  t = avail();
383  pptr->left = t;
384  t = avail();
385  pptr->right = t;
386   
387}
388
389static treeptr insert_node(treeptr pptr)
390{
391
392   treeptr newnode;
393
394   newnode = avail();
395   create_node(newnode, pptr->parent);
396
397   newnode->left = pptr;
398   pptr->parent = newnode;
399
400   set_info(newnode, pptr->parent, NODE, "", 0.0);
401
402   return(newnode);
403}
404
405static void skip_space(FILE *local_fd)
406{
407  int   c;
408 
409  do
410     c = getc(local_fd);
411  while(isspace(c));
412
413  ungetc(c, local_fd);
414}
415
416static treeptr avail(void)
417{
418   treeptr p;
419   p = ckalloc(sizeof(stree));
420   p->left = NULL;
421   p->right = NULL;
422   p->parent = NULL;
423   p->dist = 0.0;
424   p->leaf = 0;
425   p->order = 0;
426   p->name[0] = '\0';
427   return(p);
428}
429
430void clear_tree(treeptr p)
431{
432   clear_tree_nodes(p);
433     
434   nptr=ckfree((void *)nptr);
435   ptrs=ckfree((void *)ptrs);
436   lptr=ckfree((void *)lptr);
437   olptr=ckfree((void *)olptr);
438}
439
440static void clear_tree_nodes(treeptr p)
441{
442   if (p==NULL) p = root;
443   if (p->left != NULL)
444     {
445       clear_tree_nodes(p->left);
446     }
447   if (p->right != NULL)
448     {
449       clear_tree_nodes(p->right);
450     }
451   p->left = NULL;
452   p->right = NULL;
453   p=ckfree((void *)p);   
454}
455
456static void set_info(treeptr p, treeptr parent, sint pleaf, const char *pname, float pdist)
457{
458   p->parent = parent;
459   p->leaf = pleaf;
460   p->dist = pdist;
461   p->order = 0;
462   strcpy(p->name, pname);
463   if (p->leaf == TRUE)
464     {
465        p->left = NULL;
466        p->right = NULL;
467     }
468}
469
470static treeptr reroot(treeptr ptree, sint nseqs)
471{
472
473   treeptr p, rootnode, rootptr;
474   float   diff, mindiff = 0.0, mindepth = 1.0, maxdist;
475   sint   i;
476   Boolean first = TRUE;
477
478/*
479  find the difference between the means of leaf->node
480  distances on the left and on the right of each node
481*/
482   rootptr = ptree;
483   for (i=0; i<ntotal; i++)
484     {
485        p = ptrs[i];
486        if (p->parent == NULL)
487           diff = calc_root_mean(p, &maxdist);
488        else
489           diff = calc_mean(p, &maxdist, nseqs);
490
491        if ((diff == 0) || ((diff > 0) && (diff < 2 * p->dist)))
492          {
493              if ((maxdist < mindepth) || (first == TRUE))
494                 {
495                    first = FALSE;
496                    rootptr = p;
497                    mindepth = maxdist;
498                    mindiff = diff;
499                 }
500           }
501
502     }
503
504/*
505  insert a new node as the ancestor of the node which produces the shallowest
506  tree.
507*/
508   if (rootptr == ptree)
509     {
510        mindiff = rootptr->left->dist + rootptr->right->dist;
511        rootptr = rootptr->right;
512     }
513   rootnode = insert_root(rootptr, mindiff);
514 
515   diff = calc_root_mean(rootnode, &maxdist);
516
517   return(rootnode);
518}
519
520static treeptr insert_root(treeptr p, float diff)
521{
522   treeptr newp, prev, q, t;
523   float dist, prevdist,td;
524
525   newp = avail();
526
527   t = p->parent;
528   prevdist = t->dist;
529
530   p->parent = newp;
531
532   dist = p->dist;
533
534   p->dist = diff / 2;
535   if (p->dist < 0.0) p->dist = 0.0;
536   if (p->dist > dist) p->dist = dist;
537
538   t->dist = dist - p->dist; 
539
540   newp->left = t;
541   newp->right = p;
542   newp->parent = NULL;
543   newp->dist = 0.0;
544   newp->leaf = NODE;
545
546   if (t->left == p) t->left = t->parent;
547   else t->right = t->parent;
548
549   prev = t;
550   q = t->parent;
551
552   t->parent = newp;
553
554   while (q != NULL)
555     {
556        if (q->left == prev)
557           {
558              q->left = q->parent;
559              q->parent = prev;
560              td = q->dist;
561              q->dist = prevdist;
562              prevdist = td;
563              prev = q;
564              q = q->left;
565           }
566        else
567           {
568              q->right = q->parent;
569              q->parent = prev;
570              td = q->dist;
571              q->dist = prevdist;
572              prevdist = td;
573              prev = q;
574              q = q->right;
575           }
576    }
577
578/*
579   remove the old root node
580*/
581   q = prev;
582   if (q->left == NULL)
583      {
584         dist = q->dist;
585         q = q->right;
586         q->dist += dist;
587         q->parent = prev->parent;
588         if (prev->parent->left == prev)
589            prev->parent->left = q;
590         else
591            prev->parent->right = q;
592         prev->right = NULL;
593      }
594   else
595      {
596         dist = q->dist;
597         q = q->left;
598         q->dist += dist;
599         q->parent = prev->parent;
600         if (prev->parent->left == prev)
601            prev->parent->left = q;
602         else
603            prev->parent->right = q;
604         prev->left = NULL;
605      }
606
607   return(newp);
608}
609
610static float calc_root_mean(treeptr local_root, float *maxdist)
611{
612   float dist , lsum = 0.0, rsum = 0.0, lmean,rmean,diff;
613   treeptr p;
614   sint i;
615   sint nl, nr;
616   sint direction;
617/*
618   for each leaf, determine whether the leaf is left or right of the root.
619*/
620   dist = (*maxdist) = 0;
621   nl = nr = 0;
622   for (i=0; i< numseq; i++)
623     {
624         p = lptr[i];
625         dist = 0.0;
626         while (p->parent != local_root)
627           {
628               dist += p->dist;
629               p = p->parent;
630           }
631         if (p == local_root->left) direction = LEFT;
632         else direction = RIGHT;
633         dist += p->dist;
634
635         if (direction == LEFT)
636           {
637             lsum += dist;
638             nl++;
639           }
640         else
641           {
642             rsum += dist;
643             nr++;
644           }
645        if (dist > (*maxdist)) *maxdist = dist;
646     }
647
648   lmean = lsum / nl;
649   rmean = rsum / nr;
650
651   diff = lmean - rmean;
652   return(diff);
653}
654
655
656static float calc_mean(treeptr local_nptr, float *maxdist, sint nseqs)
657{
658   float dist , lsum = 0.0, rsum = 0.0, lmean,rmean,diff;
659   treeptr p, *path2root;
660   float *dist2node;
661   sint depth = 0, i,j , n = 0;
662   sint nl , nr;
663   sint direction, found;
664
665        path2root = (treeptr *)ckalloc(nseqs * sizeof(treeptr));
666        dist2node = (float *)ckalloc(nseqs * sizeof(float));
667/*
668   determine all nodes between the selected node and the root;
669*/
670   depth = (*maxdist) = dist = 0;
671   nl = nr = 0;
672   p = local_nptr;
673   while (p != NULL)
674     {
675         path2root[depth] = p;
676         dist += p->dist;
677         dist2node[depth] = dist;
678         p = p->parent;
679         depth++;
680     }
681 
682/*
683   *nl = *nr = 0;
684   for each leaf, determine whether the leaf is left or right of the node.
685   (RIGHT = descendant, LEFT = not descendant)
686*/
687   for (i=0; i< numseq; i++)
688     {
689       p = lptr[i];
690       if (p == local_nptr)
691         {
692            direction = RIGHT;
693            dist = 0.0;
694         }
695       else
696         {
697         direction = LEFT;
698         dist = 0.0;
699/*
700   find the common ancestor.
701*/
702         found = FALSE;
703         n = 0;
704         while ((found == FALSE) && (p->parent != NULL))
705           {
706               for (j=0; j< depth; j++)
707                 if (p->parent == path2root[j])
708                    { 
709                      found = TRUE;
710                      n = j;
711                    }
712               dist += p->dist;
713               p = p->parent;
714           }
715         if (p == local_nptr) direction = RIGHT;
716         }
717
718         if (direction == LEFT)
719           {
720             lsum += dist;
721             lsum += dist2node[n-1];
722             nl++;
723           }
724         else
725           {
726             rsum += dist;
727             nr++;
728           }
729
730        if (dist > (*maxdist)) *maxdist = dist;
731     }
732
733        dist2node=ckfree((void *)dist2node);
734        path2root=ckfree((void *)path2root);
735       
736   lmean = lsum / nl;
737   rmean = rsum / nr;
738   
739   diff = lmean - rmean;
740   return(diff);
741}
742
743static void order_nodes(void)
744{
745   sint i;
746   treeptr p;
747
748   for (i=0; i<numseq; i++)
749     {
750        p = lptr[i];
751        while (p != NULL)
752          {
753             p->order++;
754             p = p->parent;
755          }
756     }
757}
758
759
760static sint calc_weight(sint leaf)
761{
762
763  treeptr p;
764  float weight = 0.0;
765
766  p = olptr[leaf];
767  while (p->parent != NULL)
768    {
769       weight += p->dist / p->order;
770       p = p->parent;
771    }
772
773  weight *= 100.0;
774
775  return((sint)weight);
776
777}
778
779static void group_seqs(treeptr p, sint *next_groups, sint nseqs)
780{
781    sint i;
782    sint *tmp_groups;
783
784    tmp_groups = (sint *)ckalloc((nseqs+1) * sizeof(sint));
785    for (i=0;i<nseqs;i++)
786         tmp_groups[i] = 0;
787
788    if (p->left != NULL)
789      {
790         if (p->left->leaf == NODE)
791            {
792               group_seqs(p->left, next_groups, nseqs);
793               for (i=0;i<nseqs;i++)
794                 if (next_groups[i] != 0) tmp_groups[i] = 1;
795            }
796         else
797            {
798               mark_group1(p->left, tmp_groups, nseqs);
799            }
800               
801      }
802
803    if (p->right != NULL)
804      {
805         if (p->right->leaf == NODE)
806            {
807               group_seqs(p->right, next_groups, nseqs);
808               for (i=0;i<nseqs;i++)
809                    if (next_groups[i] != 0) tmp_groups[i] = 2;
810            }
811         else 
812            {
813               mark_group2(p->right, tmp_groups, nseqs);
814            }
815         save_set(nseqs, tmp_groups);
816      }
817    for (i=0;i<nseqs;i++)
818      next_groups[i] = tmp_groups[i];
819
820    tmp_groups=ckfree((void *)tmp_groups);
821
822}
823
824static void mark_group1(treeptr p, sint *local_groups, sint n)
825{
826    sint i;
827
828    for (i=0;i<n;i++)
829       {
830         if (olptr[i] == p)
831              local_groups[i] = 1;
832         else
833              local_groups[i] = 0;
834       }
835}
836
837static void mark_group2(treeptr p, sint *local_groups, sint n)
838{
839    sint i;
840
841    for (i=0;i<n;i++)
842       {
843         if (olptr[i] == p)
844              local_groups[i] = 2;
845         else if (local_groups[i] != 0)
846              local_groups[i] = 1;
847       }
848}
849
850static void save_set(sint n, sint *local_groups)
851{
852    sint i;
853
854    for (i=0;i<n;i++)
855      sets[nsets+1][i+1] = local_groups[i];
856    nsets++;
857}
858
859
860
861sint calc_similarities(sint nseqs)
862{
863   sint depth = 0, i,j, k, n;
864   sint found;
865   sint nerrs, seq1[MAXERRS],seq2[MAXERRS];
866   treeptr p, *path2root;
867   float dist;
868   float *dist2node, bad_dist[MAXERRS];
869   double **dmat;
870   char err_mess[1024],err1[MAXLINE],reply[MAXLINE];
871
872   path2root = (treeptr *)ckalloc((nseqs) * sizeof(treeptr));
873   dist2node = (float *)ckalloc((nseqs) * sizeof(float));
874   dmat = (double **)ckalloc((nseqs) * sizeof(double *));
875   for (i=0;i<nseqs;i++)
876     dmat[i] = (double *)ckalloc((nseqs) * sizeof(double));
877
878   if (nseqs >= 2)
879    {
880/*
881   for each leaf, determine all nodes between the leaf and the root;
882*/
883      for (i = 0;i<nseqs; i++)
884       { 
885          depth = dist = 0;
886          p = olptr[i];
887          while (p != NULL)
888            {
889                path2root[depth] = p;
890                dist += p->dist;
891                dist2node[depth] = dist;
892                p = p->parent;
893                depth++;
894            }
895 
896/*
897   for each pair....
898*/
899          for (j=0; j < i; j++)
900            {
901              p = olptr[j];
902              dist = 0.0;
903/*
904   find the common ancestor.
905*/
906              found = FALSE;
907              n = 0;
908              while ((found == FALSE) && (p->parent != NULL))
909                {
910                    for (k=0; k< depth; k++)
911                      if (p->parent == path2root[k])
912                         { 
913                           found = TRUE;
914                           n = k;
915                         }
916                    dist += p->dist;
917                    p = p->parent;
918                }
919   
920              dmat[i][j] = dist + dist2node[n-1];
921            }
922        }
923
924                nerrs = 0;
925        for (i=0;i<nseqs;i++)
926          {
927             dmat[i][i] = 0.0;
928             for (j=0;j<i;j++)
929               {
930                  if (dmat[i][j] < 0.01) dmat[i][j] = 0.01;
931                  if (dmat[i][j] > 1.0) {
932                        if (dmat[i][j] > 1.1 && nerrs<MAXERRS) {
933                                seq1[nerrs] = i;
934                                seq2[nerrs] = j;
935                                bad_dist[nerrs] = dmat[i][j];
936                                nerrs++;
937                        }
938                    dmat[i][j] = 1.0;
939                  }
940               }
941          }
942        if (nerrs>0) 
943          {
944             strcpy(err_mess,"The following sequences are too divergent to be aligned:\n");
945             for (i=0;i<nerrs && i<5;i++)
946              {
947                sprintf(err1,"           %s and %s (distance %1.3f)\n",
948                                        names[seq1[i]+1],
949                                        names[seq2[i]+1],bad_dist[i]);
950                strcat(err_mess,err1);
951              }
952             strcat(err_mess,"(All distances should be between 0.0 and 1.0)\n");
953             strcat(err_mess,"This may not be fatal but you have been warned!\n");
954             strcat(err_mess,"SUGGESTION: Remove one or more problem sequences and try again");
955             if(interactive) 
956                    (*reply)=prompt_for_yes_no(err_mess,"Continue ");
957             else (*reply) = 'y';
958             if ((*reply != 'y') && (*reply != 'Y'))
959                    return((sint)0);
960          }
961     }
962   else
963     {
964        for (i=0;i<nseqs;i++)
965          {
966             for (j=0;j<i;j++)
967               {
968                  dmat[i][j] = tmat[i+1][j+1];
969               }
970          }
971     }
972
973   path2root=ckfree((void *)path2root);
974   dist2node=ckfree((void *)dist2node);
975   for (i=0;i<nseqs;i++)
976     {
977        tmat[i+1][i+1] = 0.0;
978        for (j=0;j<i;j++)
979          {
980             tmat[i+1][j+1] = 100.0 - (dmat[i][j]) * 100.0;
981             tmat[j+1][i+1] = tmat[i+1][j+1];
982          }
983     }
984
985   for (i=0;i<nseqs;i++) dmat[i]=ckfree((void *)dmat[i]);
986   dmat=ckfree((void *)dmat);
987
988   return((sint)1);
989}
990
Note: See TracBrowser for help on using the repository browser.