JWS-109 Fixed the links in the navbar header and footer to match the new documentatio...
[jabaws.git] / binaries / src / tcoffee / t_coffee_source / aln_convertion_util.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <stdarg.h>
5 #include <string.h>
6 #include <ctype.h> 
7 #include "io_lib_header.h"
8 #include "util_lib_header.h"
9 #include "dp_lib_header.h"
10 #include "define_header.h"
11
12 int aln_has_stockholm_structure (Alignment *A)
13 {
14   return name_is_in_list ("#=GC SS_cons", A->name, A->nseq, 100);
15 }
16
17 int get_aln_stockholm_structure (Alignment *A)
18 {
19   int i;
20   if ((i=aln_has_stockholm_structure(A))==-1)
21     A=add_alifold2aln (A, NULL);
22   return aln_has_stockholm_structure(A);
23 }
24 int ** update_RNAfold_list (Alignment *A, int **pos, int s, int **l)
25 {
26   int a=0;
27   while (l[a])
28     {
29       if (!is_gap(A->seq_al[s][l[a][0]]) && !is_gap (A->seq_al[s][l[a][1]]))
30         {
31           l[a][2]=pos[s][l[a][0]];
32           l[a][3]=pos[s][l[a][1]];
33         }
34       else
35         {
36           l[a][2]=l[a][3]=-1;
37         }
38       a++;
39     }
40   return l;
41 }
42
43 Alignment *compare_RNA_fold ( Alignment *A, Alignment *B)
44 {
45   int i1, i2, i;
46   int **l1, **l2;
47   int **pos1, **pos2;
48   int a, b;
49   int tot_ol=0, tot_l=0;
50   
51   i1=get_aln_stockholm_structure (A);
52   i2=get_aln_stockholm_structure (B);
53   
54   l1=vienna2list (A->seq_al[i1]);
55   l2=vienna2list (B->seq_al[i2]);
56   
57   pos1=aln2pos_simple(A, A->nseq);
58   pos2=aln2pos_simple(B, B->nseq);
59     
60   
61                         
62   for (a=0; a< A->nseq; a++)
63     {
64       char **lu;
65       int ol=0, ll1=0, ll2=0;
66       if ( A->name[a][0]=='#')continue;
67       i=name_is_in_list (A->name[a], B->name, B->nseq, 100);
68       if (i!=-1)
69         {
70           l1=update_RNAfold_list (A,pos1,a, l1);
71           l2=update_RNAfold_list (B,pos2,i, l2);
72           lu=declare_char (A->len_aln, B->len_aln);
73           
74           b=0;
75           while (l2[b])
76             {
77              
78               if (l2[b][2]==-1 || l2[b][3]==-1);
79               else
80                 {
81                   ll2++;
82                   lu[l2[b][2]][l2[b][3]]=1;
83                  
84                 }
85               b++;
86             }
87           b=0;
88           
89           while (l1[b])
90             {
91               
92               if (l1[b][2]==-1 || l1[b][3]==-1);
93               else
94                 {
95                   ll1++;
96                   if (lu[l1[b][2]][l1[b][3]]==1)
97                     {
98                       A->seq_al[a][l1[b][0]]='6';
99                       A->seq_al[a][l1[b][1]]='6';
100                       ol++;
101                     }
102                   else
103                     {
104                       A->seq_al[a][l1[b][0]]='0';
105                       A->seq_al[a][l1[b][1]]='0';
106                     }
107                 }
108               b++;
109             }
110           
111           free_char (lu, -1);
112         }
113       tot_ol+=ol;
114       tot_l+=ll1;
115       tot_l+=ll2;
116       fprintf ( stdout, "@@ Seq: %s Overalp: %.2f Al1: %.2f Al2: %.2f \n", A->name[a], (float)(ol*200)/(ll1+ll2), (float)(ol*100)/ll1,(float)(ol*100)/ll2);
117     }
118   
119   fprintf ( stdout, "@@ Seq: Tot Overalp: %.2f \n", (float)(tot_ol*200)/(tot_l));
120   
121   return A;
122 }
123 int is_neutral(char c1, char c2);
124 int is_watson (char c1, char c2);
125 int is_watson2 (char c1, char c2);
126 int is_watson (char c1, char c2)
127 {
128   c1=tolower (c1);
129   c2=tolower (c2);
130   if ( is_watson2 (c1, c2)) return 1;
131   else return is_watson2 (c2, c1);
132 }
133 int is_watson2 (char c1, char c2)
134 {
135
136   if ( c1=='g' && c2=='c')return 1;
137   else if (c1=='a' && (c2=='t' || c2=='u'))return 1;
138   return 0;
139 }
140 int is_neutral (char c1, char c2)
141 {
142   
143   c1=tolower (c1);
144   c2=tolower (c2);
145   if (is_watson (c1, c2)) return 1;
146   else if (c1=='g' && (c2=='t' || c2=='u'))return 1;
147   else if ((c1=='t' || c1=='u') && c2=='g')return 1;
148   return 0;
149 }
150
151 int ** vienna2list ( char *seq)
152 {
153   int a, b, i, i2,l;
154   int **list;
155   l=strlen (seq);
156   list=declare_int (l+1, 8);
157   for (i=0,a=0; a<l; a++)
158     {
159       if ( seq[a]=='(')
160         {
161           list[i][0]=a;
162           for (i2=0,b=a+1; b<l && i2>=0; b++)
163             {
164               if (seq[b]=='(')i2++;
165               else if (seq[b]==')')i2--;
166             }
167           list[i][1]=b-1;
168           i++;
169         }
170     }
171   
172   list[i]=NULL;
173   return list;
174 }
175 Alignment *aln2alifold(Alignment *A)
176 {
177   char *tmp1;
178   char *tmp2;
179   
180   print_aln (A);
181   tmp1=vtmpnam (NULL);
182   tmp2=vtmpnam (NULL);
183   output_clustal_aln (tmp1,A);
184   printf_system ("RNAalifold %s >%s 2>/dev/null", tmp1, tmp2);
185   return alifold2aln (tmp2);
186 }
187
188 Alignment *add_alifold2aln  (Alignment *A, Alignment *ST)
189 {
190   int a,b,c,d,p1,p2;
191   int r1, rr1, r2, rr2;
192   int watson, comp,tot; 
193   int **compmat;
194   int max, p,k;
195   int minseq=3;
196   int **list;
197   int ncomp=0, nwatson=0;
198   int cons_l, fold_l;
199   int i,l;
200  
201   if (!ST)
202     {
203       char *tmp1, *tmp2;
204       int f;
205       Alignment *T;
206       T=copy_aln (A, NULL);
207       tmp1=vtmpnam (NULL);
208       tmp2=vtmpnam (NULL);
209       cons_l=A->len_aln;
210       for (a=0; a<A->len_aln; a++)
211         {
212           for (f=0,b=0; b<A->nseq && f==0; b++)
213             {
214               if (is_gap (A->seq_al[b][a]))f=1;
215               
216             }
217           if (f)
218             {
219               cons_l--;
220               for (b=0; b<A->nseq; b++)T->seq_al[b][a]='-';
221             }
222         }
223       ST=aln2alifold (T);
224     }
225   //add or Replace the structure
226   l=strlen (ST->seq_al[1]);
227   for (a=0; a< l; a++)if (ST->seq_al[1][a]==STOCKHOLM_CHAR)ST->seq_al[1][a]='.';
228   if ((i=name_is_in_list ("#=GC SS_cons", A->name, A->nseq, 100))!=-1)
229     {
230        sprintf (A->seq_al[i], "%s", ST->seq_al[1]);
231     }
232   else
233     {
234       A=realloc_aln2 ( A, A->nseq+1, A->len_aln+1);
235       sprintf (A->name[A->nseq], "#=GC SS_cons");
236       sprintf (A->seq_al[A->nseq], "%s", ST->seq_al[1]);
237       A->nseq++;
238     }
239   return A;
240 }
241 Alignment * alifold2analyze (Alignment *A, Alignment *ST, char *mode)
242 {
243   int s;
244   int **list;
245   int usegap;
246   
247   s=name_is_in_list ("#=GC SS_cons", A->name,A->nseq, 100);
248   
249   if (s==-1)
250     {
251       A=add_alifold2aln (A,ST);
252       s=name_is_in_list ("#=GC SS_cons", A->name,A->nseq, 100);
253     }
254     
255   list=vienna2list (A->seq_al[s]);
256   list=alifold_list2cov_list (A, list);
257  
258   usegap=0; //do not use gaped positions by default
259   if (mode && strstr (mode, "usegap"))usegap=1;//count positions with gaps
260   
261   if (!mode)
262     {
263       A=alifold2cov_stat   (A, list,usegap);
264     }
265   else
266     {
267       if ( strstr (mode, "stat"))  A=alifold2cov_stat   (A, list, usegap);
268       if ( strstr (mode, "list"))  A=alifold2cov_list   (A, list, usegap);
269       if ( strstr (mode, "aln"))   A=alifold2cov_aln    (A, list, usegap);
270       if ( strstr (mode, "color") )
271         {
272           Alignment *C;
273           C=copy_aln (A, NULL);
274           C=alifold2cov_cache (C, list, usegap);
275           A=alifold2cov_aln (A, list, usegap);
276           if ( strstr ( mode, "ps"))
277             output_color_ps (A, C, "stdout");
278           else
279             output_color_html (A, C, "stdout");
280           myexit (EXIT_SUCCESS);
281         }
282     }
283   return A;
284 }
285
286
287 int **    alifold_list2cov_list (Alignment *A, int **list)
288 {
289    int a,b,c,d,p1,p2,s;
290   int r1, rr1, r2, rr2;
291   int neutral,watson, comp,tot, occupancy; 
292   int **compmat;
293   int max, p,k;
294   int minseq=3;
295   
296   int ncomp=0, nwatson=0, nneutral=0, ncomp_wc=0;
297   int cons_l, fold_l;
298   int nseq;
299  
300   
301   for (nseq=0,a=0; a< A->nseq; a++)if ( A->name[a][0]!='#')nseq++;
302   max=((nseq*(nseq-1))/2);
303   a=0;
304   while (list[a])
305     {
306       p1=list[a][0];
307       p2=list[a][1];
308       watson=0;
309       comp=0;
310       neutral=0;
311       tot=0;
312       occupancy=0;
313       for (c=0; c<A->nseq-1; c++)
314         {
315           if (A->name[c][0]=='#')continue;
316           r1=tolower(A->seq_al[c][p1]);
317           r2=tolower(A->seq_al[c][p2]); 
318           if (is_gap(r1) || is_gap(r2))continue;
319           for (d=c+1; d<A->nseq; d++)
320             {
321               if (A->name[d][0]=='#')continue;
322               rr1=tolower(A->seq_al[d][p1]);
323               rr2=tolower(A->seq_al[d][p2]);
324               if (is_gap(rr1) || is_gap(rr2))continue;
325               if (is_watson (r1, r2))watson++;
326               if (is_watson (rr1, rr2))watson++;
327               if (is_neutral (r1, r2))neutral++;
328               if (is_neutral (rr1, rr2))neutral++;
329               if (r1!=rr1 && r2!=rr2)comp++;
330               occupancy++;
331             }
332         }
333       if (occupancy==0)
334         {
335           a++;
336           continue;
337         }
338       watson=(watson*100)/(occupancy*2);
339       comp=(comp*100)/occupancy;
340       neutral=(neutral*100)/(occupancy*2);
341       occupancy=(occupancy*100)/max;
342       list[a][3]=neutral;
343       list[a][4]=watson;
344       list[a][5]=comp;
345       list[a][6]=occupancy;
346       
347       if (list[a][3]<100)list[a][7]='I';//incompatible pair
348       else
349         {
350           list[a][7]='N';//Neutral pair
351           if (list[a][4]==100)
352             {
353               list[a][7]='W';//Watson and Crick
354               if ( list[a][5]>0)list[a][7]='C'; //Watson and crick compensated
355             }
356           else if ( list[a][5]>0)
357             {
358               list[a][7]='c';//compensated
359             }
360         }
361       a++;
362     }
363   
364   return list;
365 }
366 Alignment *alifold2cov_aln (Alignment *inA,int **list, int ug)
367 {
368   int a=0;
369   a=0;
370   Alignment *A;
371
372   A=copy_aln (inA, NULL);
373   A=realloc_aln2 ( A, A->nseq+1, A->len_aln+1);
374   sprintf (A->name[A->nseq], "#=GC SS_analyze");
375   sprintf (A->seq_al[A->nseq], "%s", A->seq_al[A->nseq-1]);
376   A->nseq++;
377   while (list[a])
378     {
379       char s;
380       if (list[a][6]<100 && !ug);
381       else
382         {
383           s=list[a][7];
384           A->seq_al[A->nseq-1][list[a][0]]=s;
385           A->seq_al[A->nseq-1][list[a][1]]=s;
386         }
387       a++;
388     }
389   return A;
390 }
391 Alignment *alifold2cov_stat (Alignment *A,int **list, int ug)
392 {
393   int fold=0,watson=0, comp=0, compwc=0, incomp=0, neutral=0;
394   int a;
395   
396   a=0;
397   while (list[a])
398     {
399       int s;
400       fold++;
401       if (list[a][6]<100 && !ug);
402       else
403         {
404           s=list[a][7];
405           watson +=(s=='W')?1:0;
406           compwc +=(s=='C')?1:0;
407           comp   +=(s=='c')?1:0;
408           neutral+=(s=='N')?1:0;
409           incomp +=(s=='I')?1:0;
410         }
411       a++;
412     }
413   fprintf ( stdout, "@@ TOT Nseq:%d tot_len: %d  fold: %d neutral: %d watson: %d CorWC: %d cor: %d Incompatible: %d\n",A->nseq-1, A->len_aln,fold, neutral,watson, compwc,comp,incomp);
414   return A;
415 }
416 Alignment *alifold2cov_cache (Alignment *inA, int **list, int ug)
417 {
418   int a,b, c;
419   Alignment *A;
420
421   A=copy_aln (inA, NULL);
422   a=0;
423   while (list[a])
424     {
425       int v, s;
426       if (list[a][6]<100 && !ug);
427       else
428         {
429           s=list[a][7];
430           if (s=='C')v=9; //red
431           else if ( s=='c')v=7; //orange
432           else if ( s=='W')v=5; //Yellow
433           else if ( s=='N')v=2; //green
434           else if ( s=='I')v=0; //blue;
435           for (b=0;b<A->nseq; b++)
436             {
437               if (A->name[b][0]=='#');
438               else
439                 {
440                   for (c=0; c<2; c++)
441                     {
442                       A->seq_al[b][list[a][c]]='0'+v;
443                     }
444                 }
445             }
446         }
447       a++;
448     }
449   return A;
450 }
451
452 Alignment *alifold2cov_list (Alignment *A,int **list, int ug)
453 {
454   int a,b, s;
455   
456   a=0;
457   while (list[a])
458     {
459       s=list[a][7];
460       if (list[a][6]<100 && !ug);
461       else if (s=='C')
462         {
463           fprintf ( stdout, "@@ WC Compensated pair: %4d %4d =>", list[a][0]+1, list [a][1]+1);
464           for (b=0; b<A->nseq; b++)if (A->name[b][0]!='#')fprintf ( stdout, "[%c%c]", toupper (A->seq_al[b][list[a][0]]), toupper(A->seq_al[b][list[a][1]]));
465           fprintf (stdout,"\n");
466         }
467       else if (s=='c')
468         {
469           fprintf ( stdout, "@@ Neural Compensated pair: %4d %4d =>", list[a][0]+1, list [a][1]+1);
470           for (b=0; b<A->nseq; b++)if (A->name[b][0]!='#')fprintf ( stdout, "[%c%c]", toupper (A->seq_al[b][list[a][0]]), toupper(A->seq_al[b][list[a][1]]));
471           fprintf (stdout,"\n");
472         }
473       else if (s=='W')
474         {
475           fprintf ( stdout, "@@ WC pair: %4d %4d =>", list[a][0]+1, list [a][1]+1);
476           for (b=0; b<A->nseq; b++)if (A->name[b][0]!='#')fprintf ( stdout, "[%c%c]", toupper (A->seq_al[b][list[a][0]]), toupper(A->seq_al[b][list[a][1]]));
477           fprintf (stdout,"\n");
478         }
479       else if (s=='N')
480          {
481           fprintf ( stdout, "@@ Neutral pair: %4d %4d =>", list[a][0]+1, list [a][1]+1);
482           for (b=0; b<A->nseq; b++)if (A->name[b][0]!='#')fprintf ( stdout, "[%c%c]", toupper (A->seq_al[b][list[a][0]]), toupper(A->seq_al[b][list[a][1]]));
483           fprintf (stdout,"\n");
484         }
485       else if (s=='I')
486         {
487           fprintf ( stdout, "@@ incompatible pair: %4d %4d =>", list[a][0]+1, list [a][1]+1);
488           for (b=0; b<A->nseq; b++)if (A->name[b][0]!='#')fprintf ( stdout, "[%c%c]", toupper (A->seq_al[b][list[a][0]]), toupper(A->seq_al[b][list[a][1]]));
489           fprintf (stdout,"\n");
490         }
491       a++;
492     }
493   
494   return A;
495 }
496
497             
498 Alignment *aln2sample (Alignment *A, int n)
499 {
500   Alignment *B;
501   int a, b, p;
502   int **pos;
503   
504   B=copy_aln (A, NULL);
505     
506   vsrand(0);
507  
508   pos=declare_int (A->len_aln, 2);
509   for (a=0; a<A->len_aln; a++){pos[a][0]=a;pos[a][1]=rand()%(1000*A->len_aln);}
510   
511   sort_int (pos, 2, 1, 0, A->len_aln-1);
512  
513   n=(n==0)?A->len_aln:(MIN (n, (A->len_aln)));
514   for (a=0; a<n; a++)
515     for (b=0; b<A->nseq; b++)
516       A->seq_al[b][a]=B->seq_al[b][pos[a][0]];
517   for (b=0; b<A->nseq; b++)
518     A->seq_al[b][n]='\0';
519   A->len_aln=n;
520   
521   free_aln (B);
522   free_int (pos, -1);
523   return A;
524 }
525 Alignment *aln2bootstrap (Alignment *A, int n)
526 {
527   Alignment *B;
528   int a, b, p;
529   
530   if (n==0)n=A->len_aln;
531   else A=realloc_aln (A, n+1);
532   vsrand(0);
533   B=copy_aln (A, NULL);
534   for (a=0; a<n; a++)
535     {
536       p=rand ()%A->len_aln;
537       for (b=0; b<A->nseq; b++)
538         A->seq_al[b][a]=B->seq_al[b][p];
539     }
540   for ( b=0; b<A->nseq; b++)A->seq_al[b][n]='\0';
541   A->len_aln=n;
542   
543   free_aln (B);
544   return A;
545
546 }
547   
548
549 Alignment * aln2random_aln (Alignment *A, char *smode)
550
551 {
552   int a, b, n, **res;
553   int max;
554   
555  
556   
557   if ( smode==NULL)
558     {
559       smode=vcalloc (4, sizeof (char));
560       sprintf ( smode, "SCR");//Sequences, Column Residues
561     }
562   else if ( strm (smode, "NO"))return A;
563   
564   vsrand(0);
565   max=A->nseq*1000;
566   
567   if ( strstr ( smode, "S"))
568     {
569       A=aln2scramble_seq (A);
570     }
571   if ( strstr ( smode, "C"))
572     {
573       
574       res=declare_int (A->nseq, 2);
575       for (a=0; a< A->len_aln; a++)
576           {
577             for (n=0,b=0;b<A->nseq; b++)
578               {
579                 if ( !is_gap(A->seq_al[b][a]))
580                   {
581                     res[n][0]=A->seq_al[b][a];
582                     res[n][1]=rand()%max;
583                     n++;
584                   }
585                 sort_int (res, 2, 1, 0, n-1);
586               }
587             for (n=0,b=0;b<A->nseq; b++)
588               {
589                 if ( !is_gap(A->seq_al[b][a]))A->seq_al[b][a]=res[n++][0];
590               }
591           }
592       free_int (res, -a);
593     }
594   
595     
596   //Redistributes the residues randomly without changing the gap pattern
597   if ( strstr ( smode, "R"))
598     {
599       max=A->len_aln*A->nseq;
600       res=declare_int (max, 2);
601       
602       for (n=0,a=0; a< A->len_aln; a++)
603         {
604           for (b=0;b<A->nseq; b++)
605             {
606               if ( !is_gap(A->seq_al[b][a]))
607                 {
608                   res[n][0]=A->seq_al[b][a];
609                   res[n][1]=rand()%max;
610                   n++;
611                 }
612               
613             }
614         }
615       sort_int (res, 2, 1, 0, n-1);
616       for (n=0,a=0; a< A->len_aln; a++)
617         {
618           for (b=0;b<A->nseq; b++)
619             {
620               if ( !is_gap(A->seq_al[b][a]))
621                 {
622                   A->seq_al[b][a]=res[n++][0];
623                 }
624               
625             }
626         }
627       
628       free_int (res, -1);
629     }
630
631   return A;
632 }
633 Alignment *score_aln2score_ascii_aln (Alignment *A, Alignment *C)
634 {
635   //Convert the output of T-Coffee evaluate into a printable score_ascii alignment*/
636   //A and C must be sorted 
637   //sets to 0 lone residues
638   int a, b;
639   
640   for (a=0; a<A->nseq; a++)
641     for (b=0; b<A->len_aln; b++)
642       {
643         
644         int rC=C->seq_al[a][b];
645         int rA=A->seq_al[a][b];
646         if ( !strm (A->name[a], C->name[a])){HERE ("Unsorted aln in score_aln2score_ascii"); myexit (EXIT_FAILURE);}
647         
648         if ( rA=='x' || rA=='X')C->seq_al[a][b]='9';
649         else if ( rC >='0' && rC<='9');
650         else if ( rC<10)C->seq_al[a][b]='0'+rC;
651         else if ( rC==NO_COLOR_RESIDUE && !is_gap(rA)) C->seq_al[a][b]='0';
652         else if ( rC==NO_COLOR_RESIDUE && is_gap(rA))C->seq_al[a][b]='-';
653       }
654   return C;
655 }
656 Alignment*aln2gap_cache (Alignment *A, int val)
657 {
658   Alignment *B;
659   int a, b, c, nr;
660   
661   B=copy_aln (A, NULL);
662   for (b=0; b<A->len_aln; b++)
663     {
664       for (nr=0,a=0; a<A->nseq; a++)nr+=!is_gap (A->seq_al[a][b]);
665       for (a=0; a<A->nseq; a++)if (!is_gap(A->seq_al[a][b]))B->seq_al[a][b]=(nr==1)?'0'+val:'1';
666     }
667   return B;
668 }
669         
670 Alignment* aln2case_aln (Alignment *B, char *upper, char *lower)
671 {
672   int a, b, c, up, lo;
673   Alignment *A;
674
675   A=copy_aln (B, NULL);
676   
677   up=(upper)?upper[0]:'u';
678   lo=(lower)?lower[0]:'l';
679   
680   for (a=0; a<A->nseq; a++)
681     for (b=0; b<A->len_aln; b++)
682       {
683         c=A->seq_al[a][b];
684         
685         if ( is_gap(c));
686         else A->seq_al[a][b]=(isupper (c))?up:lo;
687       }
688   return A;
689 }
690 Alignment *aln2scale (Alignment *A, char *coffset)
691 {
692   int a, b, t, v, n;
693   char *s1, *s2;
694   char s[1000];
695   int offset;
696   
697   if (coffset)offset=atoi(coffset);
698   else offset=0;
699
700   sprintf (s, "%d", A->len_aln+offset);
701   n=strlen (s);
702   
703   A=realloc_aln2 (A, A->nseq+n, A->len_aln+1);
704   s1=vcalloc ( n+1, sizeof (char));
705   s2=vcalloc ( n+1, sizeof (char));
706   
707   for (a=0; a<n; a++)
708     {
709       if (a==0)s2[a]='1';
710       else strcat (s2, "0");
711       sprintf (A->name[A->nseq+a], "%s", s2);
712     }
713   
714   for (a=0; a<A->len_aln; a++)
715     {
716       sprintf (s1, "%d", a+1+offset);
717       s2=invert_string (s1);
718       t=strlen (s2);
719       
720       for (b=0; b<=n; b++)
721         {
722           if (b>=t) v='0';
723           else v=s2[b];
724
725           A->seq_al[A->nseq+b][a]=v;
726         }
727     }
728   
729   A->nseq+=n;
730   return A;
731 }
732
733   
734         
735       
736 int * pos2list (int * pos, int len, int *nl)
737 {
738   int *list;
739   int a;
740   nl[0]=0;
741   list=vcalloc (len, sizeof (int));
742   for (a=0; a<len; a++)if (pos[a])list[nl[0]++]=a;
743   return list;
744 }
745 int *list2pos (int *list, int nl, int len)
746 {
747   int *pos, a;
748   pos=vcalloc (len, sizeof (int));
749   for (a=0; a<nl; a++)pos[list[a]]=1;
750   return pos;
751 }
752
753 int **aln2resindex ( Alignment *A, Alignment *B, FILE *fp)
754 {
755   int *list, **pos;
756   int a, b, n, s;
757   
758   
759   list=vcalloc (A->nseq+((B)?B->nseq:0), sizeof (int));
760   pos=aln2pos_simple_2 (A);
761   if (B)
762     {
763       n=B->nseq;
764       for ( a=0; a<B->nseq; a++)
765         {
766           list[a]=name_is_in_list(B->name[a], A->name, A->nseq, 100);
767         }
768     }
769   else
770     {
771       for ( a=0; a<A->nseq; a++)
772         list[a]=a;
773       n=A->nseq;
774     }
775
776   
777   fprintf ( fp, "#");
778   for ( b=0; b<n; b++)
779     {
780       s=list[b];
781       if ( s!=-1)fprintf (fp, " %s",A->name[s]);
782     }
783   fprintf (fp, "\n");
784            
785   for ( a=0; a<A->len_aln; a++)
786     {
787       for ( b=0; b<n; b++)
788         {
789           s=list[b];
790           if ( s==-1);
791           else if (pos[s][a]<0)
792             fprintf (fp, "%4d", -1);
793           else
794             fprintf (fp, "%4d", pos[s][a]);
795         }
796       fprintf (fp, "\n");
797     }
798   return pos;
799 }
800         
801 int **index_seq_res      ( Sequence *S1, Sequence *S2, int **name_index)
802 {
803   /*Index the residues of S1 according to S2
804     index[seq1 of S1][z]->x, where x is the position of residue z of seq1/S1 in S2->seq[index[Seq1/S1]] 
805   */ 
806   int a;
807   int **index;
808   char *seq1=NULL, *seq2=NULL;
809   Alignment *Profile;
810    
811   index=vcalloc ( S1->nseq, sizeof (int*));
812   
813   for (a=0; a< S1->nseq; a++)
814     {
815       int  len1, len2, b, c;
816       
817       seq1=S1->seq[a];
818       
819       if (name_index[a][0]==-1)
820         seq2=NULL;
821       else if (name_index[a][1]==-1)
822         {
823           seq2=S2->seq[name_index[a][0]];
824         }
825       else if ((Profile=seq2R_template_profile (S2, name_index[a][0])) !=NULL)
826         {
827           seq2=Profile->seq_al[name_index[a][1]];
828         }
829       
830       len1=(seq1)?strlen (seq1):0;
831       len2=(seq2)?strlen (seq2):0;
832       index[a]=vcalloc (len2, sizeof(int));
833
834       
835       for (c=0,b=0; b<len2; b++)if( !is_gap(seq2[b]))index[a][c++]=b;
836       //index[a]=get_res_index ( seq1, seq2);
837     }
838   return index;
839 }
840
841 int **index_seq_name ( Sequence *S1, Sequence *S2)
842 {
843   /*Index the names of S1 according to S2
844     index[seq1 of S1][0]->x  if seq1 is the xth sequence of S2
845                         ->-1 if seq1 is nowhere to be found
846     index[seq1 of S1][1]->z if seq1 is the zth sequence within the xth profile of S2
847   */
848   int **index;
849   int a, b, x, z;
850   Alignment *Profile;
851   index=declare_int (S1->nseq, 2);
852
853   
854   for ( a=0; a<S1->nseq; a++)
855     {
856       index[a][0]=index[a][1]=-1;
857       x=name_is_in_list (S1->name[a],S2->name,S2->nseq,100);
858       if ( x!=-1){index[a][0]=x;index[a][1]=-1;}
859       for ( b=0; b<S2->nseq; b++)
860             {
861               if ((Profile=seq2R_template_profile (S2,b)))
862                 {
863                   z=name_is_in_list (S1->name[a],Profile->name,Profile->nseq,100);
864                   if ( z!=-1){index[a][0]=b;index[a][1]=z;b=S2->nseq;}
865                 }
866             }
867     }
868   return index;
869 }
870                   
871                   
872             
873           
874 int *get_name_index (char **l1, int n1, char **l2, int n2)
875 {
876   int *r;
877   int a;
878   /*return Array[Index_L1]=Index_L2 */
879   r=vcalloc ( n1, sizeof (int));
880   for ( a=0; a< n1; a++)
881     r[a]=name_is_in_list (l1[a],l2,n2,100);
882   return r;
883 }
884
885 int* get_res_index (char *seq0, char *seq1)
886 {
887   int *coor, a;
888
889   if ( !seq0 || !seq1) return NULL;
890   
891
892   coor=vcalloc ( strlen (seq0)+1, sizeof (int));
893   if (!strm (seq0, seq1))
894     {
895       int r0, r1 , isr0, isr1;
896       int l0=0, l1=0;
897       Alignment *A;
898       A=align_two_sequences (seq0,seq1,"pam250mt",-5,-1, "myers_miller_pair_wise");
899       
900       for ( a=0; a< A->len_aln; a++)
901         {
902           r0=A->seq_al[0][a];r1=A->seq_al[1][a];
903           isr0=!is_gap(r0);
904           isr1=!is_gap(r1);
905           l0+= isr0;
906           l1+= isr1;
907           if (isr0 && isr1)coor[l0-1]=l1-1;
908           else if (isr0)  coor[l0-1]=-1;
909         }
910       free_aln (A);
911     }
912   else
913     {
914       int l0;
915       
916       l0=strlen (seq0);
917       for ( a=0;a< l0; a++)
918         coor[a]=a;
919     }
920   
921   return coor;
922 }
923
924 int change_residue_coordinate ( char *in_seq1, char *in_seq2, int v)
925 {
926   /*Expresses the coordinate of a residue in seq1, in the coordinate system of seq2*/
927
928   
929   static char *seq1, *seq2;
930   static int *coor;
931  
932
933   if ( seq1 !=in_seq1 || seq2 !=in_seq2)
934     {
935       int r0, r1 , isr0, isr1;
936       int l0=0, l1=0;
937       Alignment *A;
938       int a;
939       
940       vfree (coor);
941       seq1=in_seq1, seq2=in_seq2;
942       A=align_two_sequences (seq1,seq2,"pam250mt", -14, -2, "myers_miller_pair_wise");
943       
944       coor=vcalloc ( A->len_aln, sizeof (int));
945       for ( a=0; a< A->len_aln; a++)
946         {
947           r0=A->seq_al[0][a];r1=A->seq_al[1][a];
948           
949           isr0=!is_gap(r0);
950           isr1=!is_gap(r1);
951           l0+= isr0;
952           l1+= isr1;
953
954           if (isr0 && isr1)coor[l0-1]=l1-1;
955           else if (isr0)  coor[l0-1]=-1;
956         }
957       free_aln (A);
958     }
959   return coor[v];
960 }
961           
962    
963 int ** minimise_repeat_coor (int **coor, int nseq, Sequence *S)
964     {
965     int **new_coor;
966     int a, min;
967     new_coor=declare_int ( nseq, 3);
968     min=return_min_int (coor, nseq, 2);
969     for ( a=0; a< nseq; a++)
970         {
971         new_coor[a][0]=coor[a][0];
972         new_coor[a][1]=coor[a][1];
973         new_coor[a][2]=min;
974         }
975     return new_coor;
976     }
977 int ** get_nol_seq ( Constraint_list *CL, int **coor, int nseq, Sequence *S)
978     {
979     int a, s, p, l, nl;
980     int **buf;
981     int **new_coor;
982     
983     new_coor=declare_int ( nseq+1, 3);
984     
985     
986     buf=get_undefined_list ( CL);
987     
988     
989
990     for ( a=0; a< nseq; a++)buf[coor[a][0]][coor[a][1]]=1;
991
992     
993     for ( a=0; a< nseq; a++)
994         {
995         s=coor[a][0];
996         p=coor[a][1]+1;
997         l=strlen(S->seq[s]);
998         nl=0;
999         while ( p<=l && !buf[s][p++])nl++;
1000         new_coor[a][0]=s;
1001         new_coor[a][1]=coor[a][1];
1002         new_coor[a][2]=nl;
1003         }
1004     free_int ( buf, -1);
1005     return new_coor;
1006     }
1007
1008
1009
1010 int compare_pos_column( int **pos1,int p1, int **pos2,int p2, int nseq)
1011     {
1012     int a,v1, v2;
1013     int identical=0;
1014     
1015     for ( a=0; a< nseq; a++)
1016         {
1017         
1018         v1=pos1[a][p1];
1019         v2=pos2[a][p2];
1020         
1021         if (v1>0 || v2>0) 
1022             {
1023             if ( v1!=v2)return 0;
1024             else identical=1;
1025             }
1026         }
1027     
1028     return identical;
1029     }
1030
1031 char *seq2alphabet (Sequence *S)
1032 {
1033   return array2alphabet (S->seq, S->nseq, "");
1034 }
1035
1036 char *aln2alphabet (Alignment *A)
1037 {
1038   return array2alphabet (A->seq_al, A->nseq, "");
1039 }  
1040
1041 char *array2alphabet (char **array, int n, char *forbiden)
1042 {
1043   int a, b, l;
1044   int *hasch;
1045   char *alphabet;
1046
1047   hasch=vcalloc (256, sizeof (int));
1048   alphabet=vcalloc ( 257, sizeof (char));
1049   
1050   
1051   for ( a=0; a<n; a++)
1052     {
1053       l=strlen (array[a]);
1054       for ( b=0; b<l; b++)
1055         hasch[tolower(array[a][b])]++;
1056     }
1057   
1058   for ( a=0, b=0; a< 256; a++)
1059     {
1060       if (hasch[a] && !strrchr(forbiden,a))alphabet[b++]=a;
1061     }
1062   
1063   alphabet[b]='\0';
1064   vfree (hasch);
1065   return alphabet;
1066 }
1067
1068
1069 //***************************************************************
1070 //
1071   //                          TM PRED
1072 //***************************************************************
1073
1074 char* alnpos2hmmtop_pred (Alignment *A,Alignment *Pred, int pos, int mode)
1075 {
1076   static char *result;
1077   static Alignment *Cache;
1078   static int *score;
1079   int a, tot, cons;
1080   
1081   if (!score)
1082     {
1083       score=vcalloc (256, sizeof (int));
1084       result=vcalloc (100, sizeof (char));
1085     }
1086
1087   if (!Pred && !Cache)
1088     {
1089       Cache=aln2hmmtop_pred (A);
1090     }
1091   if (!Pred) Pred=Cache;
1092   
1093
1094   for (tot=0,a=0; a<A->nseq; a++)
1095     {
1096       char s;
1097       s=Pred->seq_al[a][pos];
1098       if (!is_gap(s))
1099         {
1100           score[tolower(s)]++;
1101           tot++;
1102         }
1103     }
1104
1105   if ( score['h']>score['i'] && score['h']>score['o'])cons='h';
1106   
1107   else if ( score['i']>score['o'])cons='i';
1108   else cons='o';
1109   if (tot==0) return "";
1110
1111   
1112   if (mode==VERBOSE)sprintf (result, " H: %3d I: %3d O: %3d P: %c", (score['h']*100)/tot, (score['i']*100)/tot, (score['o']*100)/tot, cons);
1113   else if (mode == SHORT)sprintf ( result, "%c", cons);
1114   score['h']=score['o']=score['i']=0;
1115   return result;
1116 }
1117   
1118   
1119 Alignment * aln2hmmtop_pred (Alignment *A)
1120   {
1121     int a, b, c;
1122     char *buf, *pred;
1123     Alignment *PA;
1124
1125     PA=copy_aln (A, NULL);
1126     buf=vcalloc ( A->len_aln+1, sizeof (char));
1127     
1128     for ( a=0; a< A->nseq; a++)
1129       {
1130         sprintf (buf, "%s", A->seq_al[a]);
1131         pred=seq2tmstruc (buf);
1132         for (c=0,b=0; b<A->len_aln; b++)
1133           {
1134             if (!is_gap (PA->seq_al[a][b]))PA->seq_al[a][b]=pred[c++];
1135           }
1136         vfree (pred);
1137       }
1138     vfree (buf);
1139     return PA;
1140   }
1141  
1142 char * seq2tmstruc ( char *seq)
1143    {
1144      static Sequence *S;
1145      char *seqfile, *predfile, *buf;
1146      FILE *fp;
1147      
1148      seqfile=vtmpnam (NULL);
1149      predfile=vtmpnam (NULL);
1150      
1151      fp=vfopen (seqfile, "w");
1152      fprintf ( fp, ">seq1\n%s", seq);
1153      vfclose (fp);
1154      
1155      
1156      printf_system ( "fasta_seq2hmmtop_fasta.pl -in=%s -out=%s -arch=%s/%s -psv=%s/%s", seqfile, predfile, get_mcoffee_4_tcoffee(), "hmmtop.arch", get_mcoffee_4_tcoffee(), "hmmtop.psv");
1157      S=get_fasta_sequence (predfile, NULL);
1158      buf=vcalloc ( strlen (S->seq[0])+1, sizeof (char));
1159      sprintf ( buf, "%s", S->seq[0]);
1160      
1161      free_sequence (S, S->nseq);
1162      
1163      return buf;
1164    }
1165   
1166 char * set_blast_default_values()
1167 {
1168   set_string_variable ("blast_server", (getenv ("blast_server_4_TCOFFEE"))?getenv ("blast_server_4_TCOFFEE"):"EBI");
1169   set_string_variable ("pdb_db", (getenv ("pdb_db_4_TCOFFEE"))?getenv ("pdb_db_4_TCOFFEE"):"pdb");
1170   set_string_variable ("prot_db", (getenv ("prot_db_4_TCOFFEE"))?getenv ("prot_db_4_TCOFFEE"):"uniprot");
1171   set_int_variable ("prot_min_sim", 0);
1172   set_int_variable ("prot_max_sim", 100);
1173   
1174   set_int_variable ("prot_min_cov", 0);
1175   set_int_variable ("prot_max_cov", 100);
1176
1177   set_int_variable ("pdb_min_sim", 0);
1178   set_int_variable ("pdb_max_sim", 100);
1179   set_int_variable ("pdb_min_cov", 0);
1180   set_int_variable ("pdb_max_cov", 100);
1181   
1182   return;
1183 }
1184   
1185 char * seq2pdb   (Sequence *S)
1186 {
1187   set_blast_default_values();
1188   S->nseq=1;
1189   S=seq2template_seq (S, "PDB", NULL);
1190   return seq2P_pdb_id(S,0);
1191 }
1192
1193 Alignment * seq2blast ( Sequence *S)
1194 {
1195   Alignment *A;
1196   set_blast_default_values();
1197   
1198   if (S->nseq==1)
1199     {
1200       S=seq2template_seq (S, "BLAST", NULL);
1201       A=seq2R_template_profile(S,0);
1202       sprintf ( A->name[0], "%s", S->name[0]);
1203     }
1204   else
1205     {
1206       int a;
1207       for (a=0; a< S->nseq; a++)
1208         {
1209           Sequence *NS;
1210           char name[1000];
1211           NS=fill_sequence_struc(1, &(S->seq[a]), &(S->name[a]));
1212           NS=seq2template_seq (NS, "BLAST", NULL);
1213           A=seq2R_template_profile(NS,0);
1214           sprintf ( name, "%s.prf", S->name[a]);
1215           
1216           output_fasta_aln (name,A); 
1217           fprintf (stdout, "\nOUTPUT %s\n", name);
1218         }
1219       myexit (EXIT_SUCCESS);
1220     }
1221   return A;
1222 }
1223             
1224       
1225           
1226
1227 Sequence * seq2unique_name_seq ( Sequence *S)
1228 {
1229   int a;
1230   if ((a=name_list2unique_name_list (S->nseq, S->name)))
1231     {
1232       add_warning ( stderr, "\nWarning: Sequence %s is duplicated in file %s. The sequence will be renamed", S->name[a-1], S->file[a-1]);
1233     }
1234   return S;
1235 }
1236 Alignment * aln2unique_name_aln ( Alignment *S)
1237 {
1238   int a;
1239   if ((a=name_list2unique_name_list (S->nseq, S->name)))
1240     {
1241       add_warning ( stderr, "\nWarning: Sequence %s is duplicated in file %s. The sequence will be renamed", S->name[a-1], S->file[a-1]);
1242     }
1243   return S;
1244 }
1245
1246     
1247 int name_list2unique_name_list (int n, char **name)
1248 {
1249   int duplicate=0;  
1250   int a, b;
1251           
1252   for (a=0; a<n-1; a++)
1253     for (b=a+1; b<n; b++)
1254       {
1255         if ( strm (name[a], name[b]))
1256           {duplicate=a+1;b=a=n;}
1257       }
1258   
1259   if (duplicate)
1260     {
1261       char *tmp1, *tmp2;
1262       Sequence *S;
1263       FILE *fp;
1264       
1265       tmp1=vtmpnam (NULL);
1266       tmp2=vtmpnam (NULL);
1267       fp=vfopen (tmp1, "w");
1268       for (a=0; a< n; a++)fprintf ( fp, ">%s\naggggg\n", name[a]);
1269       vfclose (fp);
1270       printf_system ("fasta_aln2fasta_aln_unique_name.pl %s > %s", tmp1, tmp2);
1271       S=get_fasta_sequence (tmp2, NULL);
1272       for (a=0; a<n; a++)
1273         {
1274           name[a]=vrealloc (name [a], sizeof (int)*(strlen (S->name[a])+1));
1275           sprintf ( name[a], "%s", S->name [a]);
1276         }
1277       free_sequence(S, -1);
1278     }
1279   return duplicate;
1280 }
1281 char**gene2exons    (char **seq, int nseq)
1282 {
1283
1284   int a, b, c,r;
1285   for (a=0; a<nseq; a++)
1286     {
1287       int in_exon=0, flag=0,l;
1288       l=strlen (seq[a]);
1289       for ( b=0; b<l; b++)
1290         {
1291           r=seq[a][b];
1292           if (isupper (r))
1293             {
1294               in_exon=1;
1295               seq[a][b]=(flag)?r:tolower(r);
1296             }
1297           else if (in_exon)
1298             {
1299               in_exon=0;
1300               flag=1-flag;
1301               seq[a][b]='-';
1302             }
1303           else seq[a][b]='-';
1304         }
1305     }
1306   return seq;
1307 }
1308 Sequence* seq2clean_seq (Sequence *S, char *alp)
1309 {
1310   int a, b, c, d, l;
1311   
1312   for (a=0; a< S->nseq; a++)
1313     {
1314       l=strlen (S->seq[a]);
1315       for (d=0,b=0; b<l; b++)
1316         {
1317           c=S->seq[a][b];
1318           if ( alp==NULL && !strchr (AA_ALPHABET, c) && !strchr (DNA_ALPHABET, c));
1319           else if (alp && strchr (alp, c));
1320           else S->seq[a][d++]=c;
1321         }
1322       S->seq[a][d]='\0';
1323       S->len[a]=strlen (S->seq[a]);
1324     }
1325   return S;
1326 }    
1327 int ** seq2aln_pos      (Alignment *A, int *ns, int **l_s)
1328     {
1329     int **code;
1330     int a, b,c, d,l, p , g;
1331     
1332
1333     l=MAX(strlen (A->seq_al[l_s[0][0]]), strlen (A->seq_al[l_s[1][0]]));
1334     code=declare_int ((A->S)->nseq,l+1);
1335     
1336     for (c=0; c<2; c++)
1337         {
1338         l=strlen (A->seq_al[l_s[c][0]]);
1339         for (d=0; d<ns[c]; d++)
1340             {
1341             a=A->order[l_s[c][d]][0];
1342             for (p=0, b=0; b<l; b++)
1343                 {
1344                     g=is_gap (A->seq_al[l_s[c][d]][b]);
1345                     if (!g){p++; code[a][p]=b+1;}
1346                 }
1347             }
1348         }
1349     return code;
1350     }
1351
1352 Alignment *local_maln2global_maln (char *seq, Alignment *A)
1353     {
1354       /*inputs a BLAST alignmnent where the master sequence may be partila
1355         outputs the same alignment, while amkeing sure the profile is perfectly in sink with its master sequence
1356       */
1357
1358       int a, b, c;
1359       int start, end, rend;
1360       char qname[100], *p;
1361       Alignment *B=NULL;
1362       
1363       sprintf ( qname, "%s", A->name[0]);
1364       p=strtok (qname, "_");
1365       if ( !strm (p, "QUERY"))
1366            {
1367              fprintf ( stderr, "\nUnappropriate format for the alignment [%s:FATAL]", PROGRAM);
1368              myexit (EXIT_FAILURE);
1369            }
1370              
1371       start=atoi(strtok (NULL, "_"));
1372       end=atoi(strtok (NULL, "_"));
1373       rend=strlen (seq);
1374       
1375       B=copy_aln (A,NULL);
1376       if ( start>1 || end<rend )A=realloc_aln (A,rend+1);
1377
1378       for (a=0; a<start-1; a++)
1379         {
1380           A->seq_al[0][a]=seq[a];
1381           for ( b=1; b< A->nseq; b++)A->seq_al[b][a]='-';
1382         }
1383       
1384       for (c=0,a=start-1; a< end; a++, c++)
1385         {
1386           A->seq_al[0][a]=seq[a];
1387           for ( b=1; b< A->nseq; b++)
1388             {
1389               A->seq_al[b][a]=B->seq_al[b][c];
1390             }
1391         }
1392       for ( a=end; a<rend; a++)
1393         {
1394           A->seq_al[0][a]=seq[a];
1395           for ( b=1; b< A->nseq; b++)A->seq_al[b][a]='-';
1396         }
1397       for ( a=0; a< A->nseq; a++) A->seq_al[a][rend]='\0';
1398       free_aln (B);
1399       
1400       A->len_aln=rend;
1401       return A;
1402     }
1403
1404 int ** aln2inv_pos ( Alignment *A)
1405 {
1406   int **pos,a;
1407   pos=vcalloc (A->nseq, sizeof (char*));
1408   for (a=0; a< A->nseq; a++)pos[a]=seq2inv_pos (A->seq_al[a]);
1409   return pos;
1410 }
1411 int *  seq2inv_pos ( char *seq)
1412 {
1413   /*returns a list where each value gives the index of the corresponding residue in seq*/
1414   /*Numbering: 1 to L : Analogy to the aln2pos*/
1415   
1416   int a,l1, l2;
1417   int *pos;
1418   
1419   l1=strlen ( seq);
1420   for ( l2=a=0; a< l1; a++)l2+=1-is_gap(seq[a]);
1421   pos=vcalloc (l2+1, sizeof (int));
1422   for ( l2=a=0; a< l1; a++)if (!is_gap(seq[a]))pos[++l2]=a+1;
1423   return pos;
1424 }
1425   
1426   
1427 int ** aln2pos_simple_2 (Alignment *A)
1428     {
1429     int **pos1;
1430     int **pos2;
1431     pos1=aln2pos_simple (A, A->nseq);
1432     pos2=duplicate_int  (pos1, A->nseq,read_size_int (pos1[0],sizeof (int)));
1433     pos1=aln2pos_simple (NULL, 0);
1434     return pos2;
1435     }
1436 int ** aln2pos_simple (Alignment *A, int n_nseq, ...)
1437     {
1438     /*
1439     function documentation: start
1440     int ** aln2pos_simple (Alignment *A, int n_nseq, ...)
1441
1442 ####with two parameter only: Alignment *A, int n_nseq
1443
1444     this function turns A into pos, a matrix where each residue is replace by its index according to the complete sequence.
1445     the indices in pos are computed using A->order[x][1] that contains the indice of the first residue of seq x of A
1446     
1447     n_nseq MUST not be null
1448
1449 ####with more than two param:
1450      int ** aln2pos_simple (Alignment *A, int n_nseq, int *ns, int **ls)
1451      n_nseq must be set to 0 for the param 3 and four to be read
1452      
1453      ns[x]=number seq in group 
1454      ls[x]=list of the sequences in group x ( size=ns[x])
1455      
1456     The computation of the indices is only carried out on the scpecified residues
1457
1458 ####IMPORTANT
1459       in pos, the numbering of the residues goes from 1 to L:
1460         pos[0][0]=3, means that the first position of the first sequence 
1461         in the alignmnet contains residue #3 from sequence A->order[0][0];
1462         
1463     function documentation: end
1464     */
1465
1466     int a, b,c, p, g,l;
1467     int **T;
1468
1469     int max_nseq;
1470     int n_len=0;
1471
1472     int *list=NULL;
1473     int *ns=NULL;
1474     int **ls=NULL;
1475
1476
1477
1478     va_list ap;
1479     
1480     
1481     if ( A==NULL)
1482        {
1483          return NULL;
1484        }
1485     else
1486        {
1487        if ( n_nseq>0)
1488           {
1489           list=vcalloc(n_nseq, sizeof (int));
1490           for ( a=0; a< n_nseq; a++)list[a]=a;
1491           }
1492        else
1493           { 
1494           va_start (ap, n_nseq);
1495           ns=va_arg(ap, int * );
1496           ls=va_arg(ap, int **);
1497           va_end(ap);
1498           list=vcalloc ( ns[0]+ns[1], sizeof (int));
1499           n_nseq=0;
1500           for ( a=0; a< ns[0]; a++)list[n_nseq++]=ls[0][a];
1501           for ( a=0; a< ns[1]; a++)list[n_nseq++]=ls[1][a];
1502           
1503           }
1504        max_nseq=MAX(read_size_int(A->order,sizeof (int*)),return_max_int (A->order, read_size_int(A->order,sizeof (int*)),0))+1;
1505        n_len=get_longest_string ( A->seq_al,A->max_n_seq, NULL, NULL)+1;  
1506        
1507
1508        T=declare_int (max_nseq, n_len);
1509        for ( c=0; c< n_nseq; c++)
1510            {
1511            a=list[c];          
1512            l=strlen ( A->seq_al[a]);
1513            
1514            for ( p=A->order[a][1],b=0; b<l; b++)
1515                {
1516                g=1-is_gap(A->seq_al[a][b]);
1517                p+=g;
1518                T[a][b]=(g==1)?p:-(1+p);
1519                if ( A->seq_al[a][b]==UNDEFINED_RESIDUE)T[a][b]=0;
1520                if ( A->seq_cache && T[a][b]>0)T[a][b]=A->seq_cache[A->order[a][0]][T[a][b]];
1521                } 
1522            }
1523        vfree (list);
1524        }
1525    
1526    return T;
1527    }
1528 Alignment ** split_seq_in_aln_list ( Alignment **aln, Sequence *S, int n_seq, char **seq_list)
1529         {
1530         int a, b, c;
1531         char * long_seq=NULL;
1532         int    len,l;
1533         int  **translation;
1534         int  **table;
1535
1536
1537         
1538
1539         if ( aln==NULL)return NULL;
1540         translation=declare_int ( S->nseq,2);
1541         
1542         for (len=0,a=0; a< S->nseq; a++)
1543             {
1544             if((b=name_is_in_list (S->name[a],seq_list, n_seq, 100))!=-1)
1545                {
1546                l=strlen(S->seq[a])+1;
1547                long_seq=vrealloc(long_seq,(len+l+1)*sizeof(char));
1548                long_seq=strcat(long_seq, S->seq[a]);
1549                long_seq=strcat(long_seq, "*");   
1550                
1551                translation[a][0]=b;
1552                translation[a][1]=len;
1553                len+=l;
1554                }
1555             else translation[a][0]=-1;
1556             }
1557
1558         long_seq[len-1]='\0';
1559         len--;
1560
1561         table=declare_int ( len+1, 2);
1562
1563         for ( b=0,a=0; a< S->nseq; a++)
1564             {
1565             if ( translation[a][0]!=-1)
1566                {
1567                c=1;
1568                while (long_seq[b]!='\0' && long_seq[b]!='*')
1569                    {
1570                    table[b+1][1]=c++;
1571                    table[b+1][0]=translation[a][0];
1572                    b++;
1573                    }
1574                table[b][1]=c++;
1575                table[b][0]=translation[a][0];
1576                b++;
1577                }
1578             }
1579
1580         for ( a=0; a< (aln[-1])->nseq; a++)
1581             {
1582             for ( b=0; b< (aln[a])->nseq; b++)
1583                 {
1584                 
1585                 (aln[a])->order[b][0]=table[(aln[a])->order[b][1]][0];
1586                 (aln[a])->order[b][1]=table[(aln[a])->order[b][1]][1];
1587                 sprintf ( (aln[a])->name[b],"%s_%d_%d", S->name[(aln[a])->order[b][0]],a+1,b+1); 
1588                 }
1589             }
1590         free_int (translation, -1);
1591         free_int (table,       -1);
1592         return aln;
1593         }
1594
1595
1596
1597 Sequence  *  fill_sequence_struc ( int nseq, char **sequences, char **seq_name)
1598         {
1599         int a;
1600         Sequence *S;
1601         int shortest, longuest;
1602
1603         if (!sequences)
1604           {
1605             shortest=longuest=0;
1606           }
1607         else if ( nseq>1)
1608           {
1609             shortest=get_shortest_string( sequences, nseq, NULL, NULL);
1610             longuest=get_longest_string (sequences, nseq, NULL, NULL);
1611           }
1612         else if ( nseq==1)
1613           {
1614             shortest=longuest=strlen (sequences[0]);
1615           }
1616         else
1617           {
1618             return NULL;
1619           }
1620         
1621
1622         S=declare_sequence (shortest, longuest,nseq);
1623         S->nseq=nseq;
1624         
1625         if (sequences)S->seq=copy_char ( sequences, S->seq, nseq, -1);
1626         else S->seq=declare_char (S->nseq, 1);
1627         
1628         S->name=copy_char ( seq_name, S->name,nseq, -1);
1629         
1630         ungap_array (S->seq,nseq);
1631         for ( a=0; a< S->nseq; a++)S->len[a]=strlen(S->seq[a]);
1632         return S;
1633         }
1634
1635
1636 Alignment * thread_profile_files2aln (Alignment *A, char *template_file, Fname *F)
1637 {
1638  
1639   Alignment *P;
1640   int a;
1641   
1642   if (!A->S)A->S=aln2seq (A);
1643   if (template_file)A->S=seq2template_seq (A->S, template_file,F);
1644   for ( a=0; a< A->nseq; a++)
1645     {
1646       P=seq2R_template_profile (A->S, a);
1647       if ( P)
1648         {
1649           P->expand=1;
1650           sprintf ( P->name[0], "%s", A->name[a]);
1651         }
1652     }
1653   
1654   return expand_aln (A);
1655 }
1656   
1657   
1658
1659
1660 Alignment * expand_aln (Alignment *A)
1661   {
1662   /*This function expands the profiles within an alignment*/
1663   
1664   
1665   int a, b, d, e;
1666   Alignment *MAIN=NULL, *SUB=NULL;
1667   int n_sub_seq=0;
1668   int new_nseq=0;
1669   int *list;
1670   Alignment *Profile;
1671   
1672   if ( !A)return A;
1673
1674
1675   
1676   list=vcalloc (A->nseq, sizeof (int)); 
1677   for ( a=0; a< A->nseq; a++)
1678     {
1679       Profile=seq2R_template_profile (A->S, A->order[a][0]);
1680       if (Profile && Profile->expand)
1681         {
1682           new_nseq+=Profile->nseq;
1683         }
1684       else 
1685         {
1686           new_nseq++;
1687           list[n_sub_seq++]=a;
1688         }      
1689     }
1690   
1691   if ( n_sub_seq==A->nseq){vfree(list);return A;}
1692   else if (n_sub_seq==0){MAIN=copy_aln (A, MAIN);MAIN->nseq=0;}
1693   else
1694     {
1695       MAIN=extract_sub_aln (A, n_sub_seq, list);
1696     }
1697   vfree(list);
1698   
1699   
1700   for ( a=0; a< A->nseq; a++)
1701     {
1702       Profile=seq2R_template_profile (A->S, A->order[a][0]);
1703       if ( Profile && Profile->expand)
1704         {
1705          
1706           SUB=copy_aln (Profile,SUB);
1707         
1708           SUB=realloc_aln2(SUB, SUB->nseq, A->len_aln+1);
1709           
1710           for ( e=0,b=0; b< A->len_aln; b++)
1711             {
1712               if ( is_gap(A->seq_al[a][b]))
1713                 {for (d=0; d< SUB->nseq; d++)SUB->seq_al[d][b]='-';}
1714               else 
1715                  {
1716                    for(d=0; d<SUB->nseq; d++)SUB->seq_al[d][b]=Profile->seq_al[d][e];
1717                    e++;
1718                  }
1719                    
1720             }
1721           MAIN=stack_aln(MAIN, SUB);
1722         }
1723     }
1724   free_aln (A);
1725   free_aln (SUB);
1726   return MAIN;
1727   }
1728 Alignment * expand_number_aln (Alignment *A,Alignment *EA)
1729   {
1730   /*This function expands the profiles within an alignment*/
1731   
1732     
1733   int a, b, d, e;
1734   Alignment *MAIN=NULL, *SUB=NULL, *C=NULL;
1735   int n_sub_seq=0;
1736   int new_nseq=0;
1737   int *list;
1738   Alignment *Profile;
1739
1740   if ( !EA || !A)return EA;
1741
1742   if ( EA->nseq<A->nseq)
1743     {
1744       fprintf (stderr, "\n[ERROR:expand_number_aln] Using as a master an expanded aln (%d %d) [FATAL:%s]", EA->nseq, A->nseq,PROGRAM);
1745       EA->A=A->A=NULL;
1746       print_aln (EA);
1747       print_aln (A);
1748       myexit (EXIT_FAILURE);
1749     }
1750   
1751
1752   list=vcalloc (EA->nseq, sizeof (int)); 
1753   for ( a=0; a< EA->nseq; a++)
1754     {
1755       Profile=seq2R_template_profile (EA->S, EA->order[a][0]);
1756       if (Profile && Profile->expand)new_nseq+=Profile->nseq;
1757       else 
1758         {
1759           new_nseq++;
1760           list[n_sub_seq++]=a;
1761         }      
1762     }
1763   
1764   if ( n_sub_seq==EA->nseq){vfree(list);return EA;}
1765   else if (n_sub_seq==0){MAIN=copy_aln (EA, MAIN);MAIN->nseq=0;}
1766   else
1767     {
1768       MAIN=extract_sub_aln (EA, n_sub_seq, list);      
1769     }
1770   
1771   
1772   list[0]=EA->nseq;
1773   C=extract_sub_aln (EA,1, list);  
1774   vfree(list);
1775   
1776   
1777   
1778   for ( a=0; a< EA->nseq; a++)
1779     {
1780       Profile=seq2R_template_profile (EA->S, EA->order[a][0]);
1781       if ( Profile && Profile->expand)
1782         {
1783           SUB=copy_aln (Profile,SUB);
1784           SUB=realloc_aln2(SUB, SUB->nseq, EA->len_aln+1);
1785           
1786           for ( e=0,b=0; b<= EA->len_aln; b++)
1787             {
1788               if (is_gap(A->seq_al[a][b]))
1789                 {
1790                 for ( d=0; d<SUB->nseq; d++)
1791                   SUB->seq_al[d][b]=NO_COLOR_RESIDUE;
1792                 }
1793               else
1794                 {
1795                   for ( d=0; d<SUB->nseq; d++)
1796                     {
1797
1798                       if ( is_gap (Profile->seq_al[d][e]))
1799                         {
1800                           SUB->seq_al[d][b]=NO_COLOR_RESIDUE;
1801                         }
1802                       else SUB->seq_al[d][b]=EA->seq_al[a][b];
1803                     }
1804                   e++;
1805                 }
1806             }
1807           for (d=0; d< SUB->nseq; d++)SUB->score_seq[d]=EA->score_seq[a];
1808           
1809           MAIN=stack_aln(MAIN, SUB);
1810         }
1811     }
1812   
1813   MAIN=stack_aln(MAIN, C);
1814   MAIN->nseq--;
1815   MAIN->score=MAIN->score_aln=EA->score_aln;
1816   
1817   free_aln (SUB);
1818   free_aln (EA);
1819   
1820   free_aln (C);
1821   
1822   return MAIN;
1823   }
1824
1825 Alignment * probabilistic_rm_aa ( Alignment *A, int pos, int len)
1826 {
1827   int random_len=0;
1828   int a, b;
1829   int left, right;
1830
1831   if ( len<0)
1832     {
1833       random_len=1;
1834       len=-len;
1835     }
1836   
1837   vsrand(0);
1838
1839   if (pos==0)pos= (rand()%(A->len_aln-(2*len+len))) +len;
1840   
1841    
1842   for ( a=0; a< A->nseq; a++)
1843         {
1844           if (random_len)left =rand()%len;
1845           else left=len;
1846           if (random_len)right=rand()%len;
1847           else right=len;
1848           if ( (pos-right)<0 || (pos+left)>A->len_aln)
1849             {
1850               add_warning ( stderr, "\nWarning: probabilistic_rm_aa, pos out of range [%s]\n", PROGRAM);
1851             }
1852           else
1853             for ( b=pos-right; b<pos+left; b++)A->seq_al[a][b]=(b==pos)?'~':'*';
1854         }
1855
1856   ungap_aln (A);
1857   free_sequence ( A->S, A->nseq);
1858   A->S=aln2seq (A);
1859   return A;
1860   
1861 }
1862           
1863 Alignment * remove_gap_column ( Alignment *A, char *mode)
1864   {
1865     int   a, b;
1866     char *p;
1867     int  *seq_list;
1868     int   nseq=0;
1869     int keep_col, cl;
1870
1871
1872     seq_list =vcalloc ( A->nseq, sizeof (int));
1873     while (  (p=strtok(mode, ":")))
1874       {
1875         mode=NULL;
1876         if (p[0]=='#')
1877           {
1878             seq_list[nseq++]=atoi(p+1)-1;
1879           }
1880         else if ( (a=name_is_in_list (p, A->name, A->nseq, 100))!=-1)
1881           {
1882             seq_list[nseq++]=a;
1883           }
1884       }
1885     
1886     if ( nseq==0)
1887       {
1888         for ( a=0; a< A->nseq; a++)seq_list[a]=a;
1889         nseq=A->nseq;
1890       }
1891
1892     for ( cl=0,a=0; a<=A->len_aln; a++)
1893       {
1894         for (keep_col=1, b=0; b< nseq && keep_col; b++)
1895           {
1896             keep_col=(is_gap(A->seq_al[seq_list[b]][a]))?0:keep_col;
1897           }
1898         
1899         if ( keep_col)
1900           {
1901             for ( b=0; b< A->nseq; b++)
1902               {
1903                 A->seq_al[b][cl]=A->seq_al[b][a];
1904               }
1905             cl++;
1906           }
1907         else
1908           {
1909             for ( b=0; b< A->nseq; b++)
1910               {
1911                 A->seq_al[b][cl]='-';
1912               }
1913             cl++;
1914           }
1915       }
1916     A->len_aln=cl;
1917     vfree (seq_list);
1918     
1919     return A;
1920   }
1921
1922
1923 Alignment * ungap_sub_aln (Alignment *A, int ns, int *ls)
1924         {
1925
1926         int a, b, c,t;
1927         int len;
1928
1929         len=strlen ( A->seq_al[ls[0]]);
1930
1931         for ( c=0,a=0; a<len; a++)
1932                 {
1933                 for ( t=0,b=0; b<ns; b++)
1934                         t+=is_gap(A->seq_al[ls[b]][a]);
1935                 if (t==ns);
1936                 else
1937                     {
1938                     for ( b=0; b<ns; b++)
1939                         A->seq_al[ls[b]][c]=A->seq_al[ls[b]][a];
1940                     c++;
1941                     }
1942                 }
1943          for ( b=0; b<ns; b++)A->seq_al[ls[b]][c]='\0';  
1944          return A;
1945         }
1946
1947 Sequence * ungap_seq ( Sequence *S)
1948         {
1949           int a;
1950           
1951           if ( !S)return NULL;
1952           ungap(S->seq[0]);
1953           S->max_len=S->min_len=strlen (S->seq[0]);
1954           for ( a=0; a< S->nseq; a++)
1955             {
1956               ungap(S->seq[a]);
1957               S->len[a]=strlen (S->seq[a]);
1958               S->max_len=MAX(S->max_len,S->len[a]);
1959               S->min_len=MAX(S->min_len,S->len[a]);
1960             }
1961           return S;
1962           
1963         }
1964 Alignment* shift_column (Alignment *A, int from, int to);
1965 int max_shift (Alignment *A, int p);
1966 int column_is_lower (Alignment *A, int p);
1967
1968 Alignment * unalign_aln_2 (Alignment *A, Alignment *C, int t)
1969 {
1970   int a, b, pos, len;
1971   Sequence *S;
1972   int n, insert;
1973   if (C)
1974     {
1975       for (a=0; a<A->nseq; a++)
1976         for (b=0; b<A->len_aln; b++)
1977           {
1978             int res=C->seq_al[a][b];
1979             A->seq_al[a][b]=toupper(A->seq_al[a][b]);
1980             if ((isdigit (res) && (res-'0')<=t))
1981               A->seq_al[a][b]=tolower(A->seq_al[a][b]);
1982           }
1983     }
1984   
1985   n=0;
1986   while ( A->seq_al[0][n])
1987     {
1988       insert=0;
1989       for (b=0; b<A->nseq; b++)if (islower (A->seq_al[b][n]))insert=1;
1990       if (insert)
1991         {
1992           insert_gap_col (A,n,1);
1993           for (b=0; b<A->nseq; b++)
1994             {
1995               if ( islower (A->seq_al[b][n+1]))
1996                 {
1997                   A->seq_al[b][n]=A->seq_al[b][n+1];
1998                   A->seq_al[b][n+1]='-';
1999                 }
2000             }
2001         }
2002       n++;
2003     }
2004   for (a=A->len_aln-1; a>=0; a--)
2005     {
2006       if (column_is_lower (A,a))
2007         {
2008           int s;
2009           s=max_shift (A,a);
2010           shift_column (A,a, a+s);
2011         }
2012     }
2013   return A;
2014 }
2015 Alignment* shift_column (Alignment *A, int from, int to)
2016 {
2017   char *buf;
2018   int a;
2019   
2020   buf=vcalloc (A->nseq, sizeof (char));
2021   for (a=0; a<A->nseq; a++)
2022     {
2023       buf[a]=A->seq_al[a][from];
2024       A->seq_al[a][from]='-';
2025     }
2026   to++;
2027   insert_gap_col (A, to, 1);
2028   for ( a=0; a<A->nseq; a++)A->seq_al[a][to]=buf[a];
2029   vfree (buf);
2030   ungap_aln (A);
2031   return A;
2032 }
2033 int max_shift (Alignment *A, int p)
2034 {
2035   int shift, max_shift, a;
2036   for (max_shift=A->len_aln,a=0; a< A->nseq; a++)
2037     {
2038       shift=0;
2039       
2040       if (!islower (A->seq_al[a][p]) || A->seq_al[a][p]=='-')continue;
2041       while (A->seq_al[a][p+shift+1]=='-')shift++;
2042       max_shift=MIN(shift,max_shift);
2043     }
2044   return max_shift;
2045 }
2046 int column_is_lower (Alignment *A, int p)
2047 {
2048   int a;
2049   
2050   for ( a=0; a<A->nseq; a++)
2051     if ( !is_gap (A->seq_al[a][p]) && !islower(A->seq_al[a][p]))return 0;
2052   return 1;
2053 }
2054
2055 Alignment * unalign_aln (Alignment *A, Alignment *C, int t)
2056 {
2057   int a, b, pos, len;
2058   Sequence *S;
2059   
2060   for (a=0; a<A->nseq; a++)
2061     for (b=0; b<A->len_aln; b++)
2062       {
2063         int res=C->seq_al[a][b];
2064         A->seq_al[a][b]=toupper(A->seq_al[a][b]);
2065         if ((isdigit (res) && (res-'0')<=t))
2066           A->seq_al[a][b]=tolower(A->seq_al[a][b]);
2067       }
2068   
2069   
2070   for (pos=-1, a=0; a<C->nseq; a++)
2071     {
2072       b=0;
2073       while ( C->seq_al[a][b])
2074         {
2075           int res=C->seq_al[a][b];
2076           if ((isdigit (res) && (res-'0')<=t))
2077             {
2078               if (pos==-1){pos=b;len=1;}
2079               else len++;
2080             }
2081           else if (pos!=-1)
2082             {
2083               
2084               C=unalign_aln_pos(C,a,pos, len);
2085               pos=-1;
2086             }
2087           b++;
2088         }
2089       if ( pos!=-1){C=unalign_aln_pos(C,a,pos, len);pos=-1;}
2090     }
2091   S=aln2seq (A);
2092   thread_seq_struc2aln (C, S);
2093   A=realloc_aln2 (A, A->nseq, C->len_aln+1);
2094   A->len_aln=C->len_aln;
2095   for (a=0; a<A->nseq; a++)sprintf ( A->seq_al[a], "%s", C->seq_al[a]);
2096   ungap_aln (A);
2097  
2098   free_sequence (S, -1);
2099   return A;
2100 }
2101 Alignment * unalign_aln_pos (Alignment *A, int s, int p, int l)
2102 {
2103   int a;
2104   char *buf;
2105   int unalign=0;
2106  
2107   
2108   buf=vcalloc (l+1, sizeof (char));
2109   for (a=0; a<l; a++)
2110     {
2111       buf[a]=A->seq_al[s][p+a];
2112       A->seq_al[s][p+a]='-';
2113     }
2114   
2115   
2116   A=insert_gap_col (A,p, l);
2117   for (a=0; a<l; a++)
2118     {
2119       A->seq_al[s][p+a]=buf[a];
2120     }
2121   vfree (buf);
2122   return A;
2123 }       
2124 Alignment * insert_gap_col (Alignment *A, int p, int l)
2125 {
2126   int a, c;
2127   char *buf;
2128   char *gap;
2129
2130   gap=generate_null(l);
2131   if ( !A || p>=A->len_aln || p<0)return A;
2132   
2133   buf=vcalloc (A->len_aln+l+1, sizeof (char));
2134   A=realloc_aln2(A,A->nseq, A->len_aln+l+1);
2135   for (a=0; a<A->nseq; a++)
2136     {
2137       c=A->seq_al[a][p];
2138       A->seq_al[a][p]='\0';
2139       sprintf ( buf, "%s%s%c%s", A->seq_al[a],gap,c,A->seq_al[a]+p+1);
2140       sprintf (A->seq_al[a], "%s", buf);
2141     }
2142   vfree (buf);
2143   A->len_aln+=l;
2144   return A;
2145 }
2146 Alignment * unalign_residues (Alignment *A, int si1, int si2)
2147 {
2148   char *s1, *s2, *ns1, *ns2; 
2149   int l, a, b,r1, r2;
2150   
2151   s1=A->seq_al[si1];s2=A->seq_al[si2];
2152   l=strlen (s1);
2153   
2154   ns1=vcalloc (2*l+1, sizeof (char));
2155   ns2=vcalloc (2*l+1, sizeof (char));
2156   
2157   for (b=a=0; a< l; a++)
2158     {
2159       r1=s1[a]; r2=s2[a];
2160       if (is_gap(r1) || is_gap(r2) || isupper (r1) || isupper(r2))
2161         {
2162           ns1[b]=(r1=='.')?'-':r1;
2163           ns2[b]=(r2=='.')?'-':r2;
2164           b++;
2165         }
2166       else
2167         {
2168           ns1[b]=r1;
2169           ns2[b]='-';
2170           b++;
2171           ns2[b]=r2;
2172           ns1[b]='-';
2173           b++;
2174         }
2175     }
2176   ns1[b]='\0';
2177   ns2[b]='\0';
2178   A->seq_al[si1]=ns1;
2179   A->seq_al[si2]=ns2;
2180   
2181
2182   A->len_aln=strlen (ns1);
2183   return A;
2184 }
2185 Alignment *degap_aln (Alignment *A)
2186 {
2187   //Reomove all the gaps
2188   int a;
2189   for ( a=0; a< A->nseq; a++)ungap (A->seq_al[a]);
2190   return A;
2191 }
2192
2193 Alignment *ungap_aln_n ( Alignment *A, int p)
2194         {
2195 /*remove all the columns of gap-only within an alignment*/  
2196         int a, b, c;
2197         int t;
2198         int gp;
2199
2200         if ( A->nseq==0)return A;
2201
2202         for ( c=0,a=0; a< A->len_aln; a++)
2203                 {
2204                 for ( t=0,b=0; b<A->nseq; b++)
2205                         t+=is_gap(A->seq_al[b][a]);
2206                 gp=(t*100)/A->nseq;
2207                 if (p>0 && (gp>=p || (t==A->nseq && p==100) || (t && p==1)));//Remove columns containing more than p% gaps
2208                 else if (p<0 && (gp<=p || (t==0 && p==-100) ||(t && p==-1)));//remove columns containing less than p% gaps
2209                 else
2210                   {
2211                     for ( b=0; b<A->nseq; b++)
2212                       A->seq_al[b][c]=A->seq_al[b][a];
2213                     c++;
2214                   }
2215                 }
2216         for ( b=0; b<A->nseq; b++)A->seq_al[b][c]='\0';
2217         A->len_aln=c; 
2218         return A;
2219         }
2220
2221 Alignment *ungap_aln ( Alignment *A)
2222 {
2223   return ungap_aln_n (A, 100);
2224 }
2225 /*
2226 Alignment *ungap_aln ( Alignment *A)
2227         {
2228         int a, b, c,t;
2229         
2230         for ( c=0,a=0; a< A->len_aln; a++)
2231                 {
2232                 for ( t=0,b=0; b<A->nseq; b++)
2233                         t+=is_gap(A->seq_al[b][a]);
2234                 if (t==A->nseq);
2235                 else
2236                     {
2237                     for ( b=0; b<A->nseq; b++)
2238                         A->seq_al[b][c]=A->seq_al[b][a];
2239                     c++;
2240                     }
2241                 }
2242          for ( b=0; b<A->nseq; b++)A->seq_al[b][c]='\0';
2243          A->len_aln=c; 
2244          return A;
2245
2246          }
2247 */
2248
2249
2250 Alignment *remove_end (Alignment *A)
2251         {
2252         int a, b, d;
2253         int left, right;
2254
2255         for (a=0; a< A->len_aln; a++)
2256             {
2257             for ( b=0, d=0; b< A->nseq; b++)
2258                 if ( !is_gap(A->seq_al[b][a]))d++;
2259             if ( d>1)break;
2260             }
2261         left=a;
2262         for (a=A->len_aln-1; a>0; a--)
2263             {
2264             for ( b=0, d=0; b< A->nseq; b++)
2265                 if ( !is_gap(A->seq_al[b][a]))d++;
2266             if ( d>1)break;
2267             }
2268         right=a;
2269
2270         return extract_aln(A, left, right+1);
2271         }
2272
2273 Alignment* condense_aln (Alignment *A)
2274 {
2275   /* condense complementarz columns:
2276      X-       X
2277      -X  ....>X
2278      X-       X
2279
2280   */
2281   int a, b, plen, n,m, r1, r2;
2282   
2283   plen=0;
2284   while ( A->len_aln !=plen)
2285     {
2286       plen=A->len_aln;
2287       for ( a=0; a< A->len_aln-1; a++)
2288         {
2289           for ( n=m=b=0; b< A->nseq; b++)
2290             {
2291               r1=is_gap(A->seq_al[b][a]);
2292               r2=is_gap(A->seq_al[b][a+1]);
2293               n+=(r1 || r2);
2294               m+=r1;
2295             }
2296         
2297           if ( n==A->nseq && m!=A->nseq)
2298             {
2299               for (b=0; b< A->nseq; b++)
2300                 {
2301                   if (!is_gap(A->seq_al[b][a+1]))
2302                       {
2303                         A->seq_al[b][a]=A->seq_al[b][a+1];
2304                         A->seq_al[b][a+1]='-';
2305                         }
2306                 }
2307               a++;
2308             }
2309         }
2310     }
2311   A=ungap_aln(A);  
2312   return A;
2313 }
2314                     
2315                       
2316                   
2317
2318 void compress_aln ( Alignment *A)
2319         {
2320
2321           /*remove all the columns of gap-only within an alignment*/  
2322         int a, b, c, d;
2323         
2324         
2325
2326         for (c=0, a=0; a< A->len_aln; a++)
2327           {
2328             for ( b=0, d=0; b< A->nseq; b++)
2329                 if ( A->seq_al[b][a]!='-'){d=1; break;}
2330             if ( d==0);
2331             else
2332               {
2333                 for (b=0; b< A->nseq; b++)
2334                   A->seq_al[b][c]=A->seq_al[b][a];
2335               c++;
2336               }
2337           }
2338          A->len_aln=c;
2339         
2340         for ( a=0; a< A->nseq; a++)
2341           A->seq_al[a][c]='\0';
2342         }
2343
2344 Alignment *seq_coor2aln ( Sequence *S, Alignment *A, int **coor, int nseq)
2345         {
2346         int a;
2347         char *buf;
2348
2349         A=realloc_alignment2(A, nseq, return_maxlen ( S->seq, S->nseq)+1);
2350         for ( a=0; a< S->nseq; a++)sprintf ( A->file[a], "%s", S->file[a]);
2351         for ( a=0; a< nseq; a++)
2352             {
2353             sprintf (A->name[a], "Repeat_%d_%d", a, coor[a][0]);
2354             buf=extract_char ( S->seq[coor[a][0]], coor[a][1]-1, coor[a][2]);
2355             sprintf ( A->seq_al[a],"%s", buf);
2356             vfree(buf);
2357             A->order[a][0]=0;
2358             A->order[a][1]=coor[a][1]-1;
2359             }
2360         A->nseq=nseq;
2361         return A;
2362         }
2363
2364 Alignment *strings2aln (int nseq,...)
2365         {
2366           /*strings2aln(nseq, <name1>, <seq1>, <name2>, <seq2>....)*/
2367           va_list ap;
2368           char **list, **list2;
2369           char **name, **name2;
2370           Sequence *S;
2371           Alignment *A;
2372           int a, max;
2373
2374           va_start(ap, nseq);
2375           list=vcalloc (nseq, sizeof (char*));
2376           name=vcalloc (nseq, sizeof (char*));
2377           for ( a=0; a< nseq; a++)
2378             {
2379               name[a]=va_arg(ap,char*);
2380               list[a]=va_arg(ap,char*);
2381               
2382             }
2383           va_end(ap);
2384           
2385           for ( max=0,a=0; a< nseq; a++)
2386             {
2387               max=(strlen (list[a])>max)?strlen(list[a]):max;
2388             }
2389           list2=declare_char (nseq, max+1);
2390           name2=declare_char (nseq, MAXNAMES+1);
2391           
2392           for ( a=0; a< nseq; a++)
2393             {
2394               sprintf ( list2[a], "%s", list[a]);
2395               sprintf ( name2[a], "%s", name[a]);
2396             }
2397
2398           
2399           S=fill_sequence_struc(nseq,list2,name2);
2400           
2401           free_char (list2, -1);
2402           free_char (name2, -1);
2403           vfree (list);
2404           vfree(name);
2405           A=seq2aln(S,NULL, 1); 
2406           return A;
2407         }
2408 Alignment *seq2aln ( Sequence *S, Alignment *A,int rm_gap)
2409         {
2410         int a;
2411
2412         A=realloc_alignment2(A, S->nseq, S->max_len+1);         
2413         for ( a=0; a< S->nseq; a++)sprintf ( A->file[a], "%s", S->file[a]);
2414         A->nseq=S->nseq;
2415         A->max_len=S->max_len;
2416         A->min_len=S->min_len;
2417
2418         for ( a=0; a< S->nseq; a++)
2419                 {
2420                 A->order[a][0]=a;
2421                 A->order[a][1]=0;
2422
2423                 sprintf ( A->seq_comment[a], "%s", S->seq_comment[a]);
2424                 sprintf ( A->aln_comment[a], "%s", S->aln_comment[a]);
2425                 
2426                 sprintf ( A->name[a], "%s", S->name[a]);
2427                 sprintf ( A->seq_al[a], "%s", S->seq[a]);
2428                 
2429                 ungap ( A->seq_al[a]);
2430                 A->len[a]=strlen ( A->seq_al[a]); 
2431                 
2432                 if ( rm_gap==0 || rm_gap==NO_PAD)sprintf ( A->seq_al[a], "%s", S->seq[a]);
2433                 
2434                 }
2435         if (rm_gap!=NO_PAD)padd_aln (A);
2436         A->S=S;
2437         return A;
2438         }
2439
2440 Alignment *padd_aln ( Alignment *A)
2441 {
2442   A->seq_al=padd_string (A->seq_al, A->nseq, '-');
2443   A->len_aln=strlen (A->seq_al[0]);
2444   return A;
2445 }
2446
2447 char **padd_string ( char **string, int n,char pad)
2448 {
2449   /*Pads a the strings so that they all have the same length*/
2450   
2451   int max_len, a;
2452   char *buf;
2453   
2454   max_len=get_longest_string  (string,n, NULL, NULL);
2455   for (a=0; a<n; a++)
2456             {
2457             buf=generate_null (max_len-strlen (string[a]));
2458             strcat ( string[a], buf);   
2459             vfree (buf);            
2460             }   
2461   return string;
2462 }
2463
2464 Alignment * trim_aln_with_seq ( Alignment *S, Alignment *P)
2465 {
2466   Alignment *A, *R;
2467   int a, b, c;
2468   static int seqindex;
2469   P=aln2profile (P);
2470   S=aln2profile (S);
2471   
2472   A=align_two_aln (S,P, "blosum62mt",-8,-1, "myers_miller_pair_wise");
2473   for (a=0; a<A->nseq; a++) sprintf (A->name[a], "tmpname_%d", seqindex++);
2474   
2475   R=copy_aln (A, NULL);
2476   for (c=0, a=0; a< A->len_aln; a++)
2477     {
2478       if ( is_gap (A->seq_al[0][a]));
2479       else
2480         {
2481           for ( b=0; b<A->nseq; b++)
2482             R->seq_al[b][c]=A->seq_al[b][a];
2483           c++;
2484         }
2485     }
2486   for ( a=0; a< A->nseq; a++)R->seq_al[a][c]='\0';
2487   R->len_aln=c;
2488   R->S=aln2seq (R);
2489   
2490   free_aln (S);
2491   free_aln (P);
2492   free_aln (A);
2493
2494   return R;
2495 }
2496
2497 Alignment * add_align_seq2aln ( Alignment *A, char *seq, char *seq_name)
2498         {
2499           if ( !A)
2500             {
2501               A=declare_aln (NULL);
2502               A=realloc_aln2 ( A, 1, strlen (seq)+1);
2503               A->nseq=0;
2504               sprintf ( A->name[A->nseq], "%s", seq_name);
2505               sprintf ( A->seq_al[A->nseq], "%s", seq);
2506               A->nseq++;
2507               
2508             }     
2509           else if ( strlen (seq)!=A->len_aln)
2510             {
2511               fprintf ( stderr, "\nError: Attempt to stack incompatible aln and aligned sequence[FATAL]\n");
2512               myexit (EXIT_FAILURE);
2513               A=NULL;
2514             }
2515           else
2516             {
2517
2518               A=realloc_aln2 ( A, A->nseq+1, A->len_aln+1);
2519               sprintf ( A->name[A->nseq], "%s", seq_name);
2520               sprintf ( A->seq_al[A->nseq], "%s", seq);
2521               A->nseq++;
2522             }
2523           return A;
2524         }
2525   
2526
2527 Alignment *aln2number (Alignment *A)
2528         {
2529         A->seq_al=char_array2number(A->seq_al, A->nseq);
2530         return A;
2531         }
2532 Sequence *seq2number (Sequence *A)
2533         {
2534         A->seq=char_array2number(A->seq, A->nseq);
2535         return A;
2536         }
2537
2538 Sequence * aln2seq (Alignment *A)
2539 {
2540   return aln2seq_main(A, RM_GAP);
2541 }
2542 Sequence * aln2seq_main (Alignment *A, int mode)
2543         {
2544         Sequence *LS;
2545         int a;
2546         int maxlen;
2547         
2548         if ( !A) return NULL;
2549         else if ( A->nseq==0)return NULL;
2550         for (maxlen=0,a=0; a<A->nseq; a++)maxlen=MAX(maxlen, strlen (A->seq_al[a]));
2551
2552         
2553         LS=declare_sequence ( maxlen+1, maxlen+1, A->nseq);
2554         LS->nseq=A->nseq;
2555         for ( a=0; a< LS->nseq; a++)
2556                 {
2557                   sprintf (LS->file[a],"%s", A->file[a]); 
2558                 
2559                   sprintf ( LS->seq[a], "%s", A->seq_al[a]);
2560                 
2561                   if (mode==RM_GAP)ungap ( LS->seq[a]);
2562                 
2563                 LS->len[a]=strlen ( LS->seq[a]);
2564
2565                 sprintf ( LS->seq_comment[a], "%s",A->seq_comment[a]);
2566                 sprintf ( LS->aln_comment[a], "%s",A->aln_comment[a]);
2567                 sprintf ( LS->name[a], "%s", A->name[a]);
2568                 }
2569         return LS;
2570         }
2571
2572 Sequence  *keep_residues_in_seq ( Sequence *S, char *list, char replacement)
2573 {
2574   Alignment *A=NULL;
2575   int a;
2576   
2577   A=seq2aln (S, A,1);
2578   A=keep_residues_in_aln ( A, list, replacement);
2579   for ( a=0; a< A->nseq; a++)
2580     {
2581       ungap (A->seq_al[a]);
2582       sprintf ( S->seq[a], "%s", A->seq_al[a]);
2583     }
2584   free_aln (A);
2585   return S;
2586 }
2587
2588
2589 Alignment *aln2short_aln ( Alignment *A, char *list, char *new, int spacer)
2590 {
2591   int a, b, r, cl, l;
2592   char *buf;
2593   
2594   for ( a=0; a< A->nseq; a++)
2595     {
2596       buf=vcalloc ( strlen (A->seq_al[a])+1, sizeof (char));
2597       
2598       for (l=0,cl=0, b=0; b< A->len_aln; b++)
2599         {
2600           r=A->seq_al[a][b];
2601           if ( is_gap(r));
2602           else if ( is_in_set (r, list))
2603             {
2604               if (cl){cl=0; buf[l++]=new[0];}
2605               buf[l++]=r;
2606             }
2607           else
2608             {
2609               if ( cl==spacer){buf[l++]=new[0];cl=0;}
2610               cl++;
2611             }
2612           
2613         }
2614       
2615       buf[l]='\0';
2616       sprintf (A->seq_al[a], "%s", buf);
2617       vfree (buf);
2618     }
2619   return A;
2620 }
2621   
2622 Alignment *keep_residues_in_aln ( Alignment *A, char *list, char replacement)
2623 {
2624   return filter_keep_residues_in_aln (A,NULL, 0, -1, list, replacement);
2625 }
2626 Alignment *filter_keep_residues_in_aln ( Alignment *A,Alignment *ST, int use_cons, int value, char *list, char replacement)
2627 {
2628   char **sl;
2629   int n, a;
2630   
2631   n=strlen (list);
2632   sl=declare_char (n+1, 256);
2633   for (a=0; a< n; a++)
2634     sprintf ( sl[a], "%c%c", list[a], list[a]);
2635   sprintf ( sl[a],"#%c", replacement);
2636   A=filter_aln_convert (A, ST,use_cons,value, n+1, sl);
2637   free_char (sl, -1);
2638   return A;
2639 }
2640   
2641
2642 Alignment *filter_convert_aln ( Alignment *A,Alignment *ST, int use_cons, int value, int n, ...)
2643 {
2644   va_list ap;
2645   char **sl;
2646   int a;
2647   va_start (ap, n);
2648   sl=vcalloc ( n,sizeof(char*));
2649   for ( a=0; a< n; a++)
2650     {
2651       sl[a]=va_arg(ap, char * );
2652     }
2653   va_end(ap);
2654   A=filter_aln_convert (A,ST,use_cons,value, n,sl);
2655   vfree(sl);
2656   return A;
2657 }
2658
2659 Alignment * filter_aln ( Alignment *A, Alignment *ST, int value)
2660         {
2661           return filter_aln_convert (A, ST,0,value,DELETE, NULL);
2662         }
2663 Alignment * filter_aln_switchcase ( Alignment *A, Alignment *ST,int use_cons, int value)
2664         {
2665           return filter_aln_convert (A, ST,0,value,SWITCHCASE, NULL);
2666         }
2667 Alignment * filter_aln_upper_lower ( Alignment *A, Alignment *ST,int use_cons, int value)
2668         {
2669           return filter_aln_convert (A, ST,use_cons,value, LOWER, NULL);
2670         }
2671 Alignment * filter_aln_lower_upper ( Alignment *A, Alignment *ST,int use_cons, int value)
2672         {
2673           
2674           return filter_aln_convert (A, ST,use_cons,value, UPPER, NULL);
2675         }
2676 Alignment * STseq2STaln ( Alignment *A, Alignment *ST)
2677         {
2678           int a, i=0;
2679           
2680           if  (ST && ST->len_aln !=A->len_aln)
2681                 {
2682                   Sequence *S_T, *S_A;
2683
2684                   S_T=aln2seq (ST);
2685                   S_A=aln2seq (A);
2686                   
2687                   for (a=0; a< A->nseq; a++)
2688                     {
2689                       i=name_is_in_list (A->name[a], S_T->name,S_T->nseq, 100);
2690                       if (i!=-1)
2691                         {
2692                           char *s1, *s2;
2693                           s1=(S_T)->seq[i];ungap(s1);
2694                           s2=(S_A)->seq[a];ungap(s2);
2695                           
2696                           if ( strlen (s1)!=strlen(s2))
2697                             {
2698                               fprintf ( stderr, "%s\n%s\n", s1, s2);
2699                               printf_exit (EXIT_FAILURE, stderr, "ERROR: Sequence %s has different length in the alignment and in the  structure Alignment [FATAL:%s]\n", A->name[a], PROGRAM);
2700                             }
2701                         }
2702                     }
2703                    ST=copy_aln (A, ST);
2704                    thread_seq_struc2aln (ST,S_T);
2705                 }
2706           
2707           return ST;
2708         }
2709 Alignment * merge_annotation   ( Alignment *A, Alignment *ST, char *seq)
2710 {
2711   int s, a, b;
2712   
2713   ST=STseq2STaln (A, ST);
2714   if ( seq==NULL)s=0;
2715   else
2716     s=name_is_in_list ( seq, A->name, A->nseq, 100);
2717   
2718   if (s==-1)
2719     {
2720       add_warning ( stderr, "\nERROR: %s is not in your MSA [FATAL: %s]", PROGRAM);
2721       myexit (EXIT_FAILURE);
2722     }
2723   
2724   for (a=0; a<A->len_aln; a++)
2725     {
2726       int t, r;
2727       
2728       t=A->seq_al[s][a];
2729       if (is_gap (t))continue;
2730       for (b=0; b<A->nseq; b++)
2731         {
2732           t=A->seq_al[s][a];
2733           r=ST->seq_al[b][a];
2734           if ( isdigit (r))
2735             {
2736               if (!isdigit(t) || (isdigit (t) && t<r))
2737                 A->seq_al[s][a]=r;
2738             }
2739         }
2740     }
2741   return A;
2742 }
2743            
2744   
2745
2746 Alignment * filter_aln_convert ( Alignment *A, Alignment *ST,int use_cons, int value, int n_symbol,char **symbol_list)
2747         {
2748           int a, b, c;
2749           int st;
2750           int cons=0;
2751           
2752           
2753           ST=STseq2STaln (A, ST);
2754           if ( ST && use_cons)
2755             {
2756               cons=name_is_in_list ("con", ST->name,ST->nseq+1, 100);
2757               if ( cons==-1)cons=name_is_in_list ("cons", ST->name,ST->nseq+1, 100);
2758               if ( cons==-1)cons=name_is_in_list ("Cons", ST->name,ST->nseq+1, 100);
2759               if ( cons==-1)
2760                 {
2761                   use_cons=0;
2762                   fprintf (stderr, "WARNING: Could Not Use the Consensus Sequence [WARNING:%s]\n", PROGRAM);
2763                 }
2764             }
2765           
2766           A->residue_case=KEEP_CASE;
2767           for ( a=0; a< A->nseq; a++)
2768             {
2769               if(value!=10 && ST && !use_cons)
2770                 {
2771                   c=name_is_in_list (A->name[a], ST->name, ST->nseq,100);
2772                   if (c==-1)st=11;
2773                 }
2774               
2775               for ( b=0; b< A->len_aln; b++)
2776                 {
2777                   if ( value==10 || !ST)st=11;
2778                   else if ( ST && use_cons)
2779                     {
2780                       st=(isdigit(ST->seq_al[cons][b]))?ST->seq_al[cons][b]-'0':ST->seq_al[cons][b];
2781                     }
2782                   else st=(isdigit(ST->seq_al[c][b]))?ST->seq_al[c][b]-'0':ST->seq_al[c][b];
2783                   
2784                   
2785                   if ( st==value || value==-1 || st==NO_COLOR_RESIDUE) 
2786                     {
2787                       if      ( n_symbol==UPPER  && !symbol_list)A->seq_al[a][b]=toupper (A->seq_al[a][b]);
2788                       else if ( n_symbol==LOWER  && !symbol_list)A->seq_al[a][b]=tolower (A->seq_al[a][b]);
2789                       else if ( n_symbol==SWITCHCASE && !symbol_list)
2790                         {
2791                           if ( !isalpha(A->seq_al[a][b]));
2792                           else if (isupper (A->seq_al[a][b]))A->seq_al[a][b]=tolower (A->seq_al[a][b]);
2793                           else if (islower (A->seq_al[a][b]))A->seq_al[a][b]=toupper (A->seq_al[a][b]);
2794                         }
2795                       else if ( n_symbol==DELETE && !symbol_list)A->seq_al[a][b]='-';
2796                       else
2797                         {
2798                           A->seq_al[a][b]=convert(A->seq_al[a][b],n_symbol,symbol_list);
2799                         }
2800                     }
2801                   
2802                 }
2803             }
2804           return A;
2805         }
2806
2807
2808 char ** sar_aln2motif (Alignment *A, Alignment *B, int *pos, int c);
2809 char ** sar_aln2motif (Alignment *A, Alignment *B, int *pos, int c)
2810 {
2811   static Alignment *I;
2812   static Alignment *O;
2813   int a, b, o, i;
2814
2815   float tp,tn,fp,fn,best, sp, sn, sen2;
2816   float best_pred=-1;
2817   int best_motif=0;
2818
2819
2820   int n1;
2821   static char ***alp;
2822   static int *alp_size;
2823   
2824   char ***motif_list;
2825   int n;
2826   
2827
2828   if (!I)
2829     {
2830       I=copy_aln(A, NULL);
2831       O=copy_aln(A, NULL);
2832     }
2833   
2834
2835   
2836   I->nseq=O->nseq=I->len_aln=O->len_aln=0;
2837   for (a=0; a<A->len_aln; a++)
2838     {
2839       if (pos[a])
2840         {
2841           for (i=o=0,b=0; b<A->nseq; b++)
2842             {
2843               
2844               if ( is_gap(A->seq_al[b][a]))return 0;
2845               if (B->seq_al[b][c]=='I')I->seq_al[i++][I->len_aln]=A->seq_al[b][a];
2846               else O->seq_al[o++][O->len_aln]=A->seq_al[b][a];
2847             }
2848           I->len_aln++;
2849           O->len_aln++;
2850         }
2851     }
2852   
2853   if (O->len_aln==0 || I->len_aln==0) return 0;
2854   O->nseq=o;
2855   I->nseq=i;
2856   for (a=0; a<o; a++)O->seq_al[a][O->len_aln]='\0';
2857   for (a=0; a<i; a++)I->seq_al[a][I->len_aln]='\0';
2858
2859   alp=vcalloc ( sizeof (char**), I->len_aln);
2860   alp_size= vcalloc ( I->len_aln, sizeof (int));
2861   for (a=0; a<I->len_aln; a++)
2862     {
2863       char *col;
2864       alp[a]=string2alphabet ( (col=aln_column2string (I,a)),2, &alp_size[a]);
2865       vfree (col);
2866     }
2867
2868   
2869   
2870   motif_list=generate_array_string_list (I->len_aln, alp, alp_size, &n, NULL, OVERLAP);
2871   best_pred=best_motif=0;
2872   for (a=0; a<n; a++)
2873     {
2874       
2875       tp=tn=fp=fn=0;
2876       
2877       for (b=0; b<I->nseq; b++)
2878         {
2879           if (match_motif (I->seq_al[b], motif_list[a]))tp++;
2880           else fn++;
2881         }
2882       for (b=0; b<O->nseq; b++)
2883         {
2884           if (match_motif (O->seq_al[b], motif_list[a]))fp++;
2885           else tn++;
2886         }
2887       rates2sensitivity (tp, tn, fp, fn, &sp, &sn, &sen2, &best);
2888       
2889       if (best> best_pred)
2890         {
2891           best_pred=best;
2892           best_motif=a;
2893         }
2894     }
2895   
2896   output_Alignment_without_header ( I, stdout);
2897   fprintf ( stdout, "\n");
2898   output_Alignment_without_header ( O, stdout);
2899   
2900   
2901   fprintf ( stdout, "\nMotifCompound %d pred: %.2f motif: ", c, best_pred);
2902   for (n1=0, a=0; a<I->len_aln; a++) 
2903     {
2904       char *m;
2905       int l;
2906       m=motif_list[best_motif][a];
2907       fprintf ( stdout, "[%s]-", m);
2908       l=strlen (m);
2909       n1+=(l==1 && !strm ("*",m) )?1:0;
2910     }
2911   fprintf (stdout, "SCORE: %d", n1);
2912   
2913   for (a=0; a<n; a++)vfree (motif_list[a]);
2914   vfree (motif_list);
2915   free_arrayN((void ***) alp, 3);
2916   vfree (alp_size);
2917   
2918   return NULL;
2919 }
2920
2921
2922
2923
2924 void explore_weight_matrix (Alignment *A, Alignment *B, int range, int n, int *array);
2925 void explore_weight_matrix (Alignment *A, Alignment *B, int range, int n, int *array)
2926 {
2927   int a;
2928   if ( n==A->len_aln)
2929     {
2930       fprintf ( stdout, "\n W:");
2931       for (a=0; a<A->len_aln; a++)fprintf ( stdout, "%d", array[a]);
2932       fprintf ( stdout, " %.4f",(float)sar_aln2r(A,B,array,0));
2933       return;
2934     }
2935   else
2936     {
2937       for ( a=0; a<range; a++)
2938         {
2939           array[n]=a;
2940           explore_weight_matrix (A, B, range, n+1, array);
2941         }
2942     }
2943 }
2944 float search_best_combo(Alignment *A, Alignment *B);
2945 void search_best_combo_sar_aln(Alignment *A, Alignment *B);
2946 void search_best_combo_sar_aln(Alignment *A, Alignment *B)
2947 {
2948   int a,b,c;
2949   Alignment *S;
2950   float s;
2951   int w=5;
2952   
2953   S=copy_aln (B, NULL);
2954   S->len_aln=w;
2955   for ( a=0; a<B->len_aln-w;a++)
2956     {
2957       for (b=0; b<B->nseq; b++)
2958         {
2959           for (c=0; c<w; c++)
2960             {
2961               S->seq_al[b][c]=B->seq_al[b][a+c];
2962             }
2963           S->seq_al[b][c]='\0';
2964             }
2965           
2966       s=search_best_combo (A, S);
2967       fprintf ( stdout,"\nP: XXXX \nP: XXXXX A=%d / %d", a, B->len_aln);
2968    
2969     }
2970    
2971 }
2972
2973 float search_best_combo(Alignment *A, Alignment *B)
2974 {
2975   int a, b, c, d, best_pos,nl, max;
2976   float best_score, score;
2977   int *list, *pos;
2978  
2979   int  w;
2980   int combo_mode=1; //1: greedy 2: consider all thw w combinations;
2981   FILE *fp2;
2982   static int **M;
2983   max=2;
2984   int delta=0;
2985   w=1;
2986   
2987   pos=vcalloc ( A->len_aln, sizeof (int));
2988   list=vcalloc (A->len_aln, sizeof (int));
2989   nl=0;
2990   
2991   if ( combo_mode==1)
2992     {
2993       for (a=0; a< max; a++)
2994         {
2995           for (best_score=-9999,best_pos=0,b=0; b< A->len_aln-w; b++)
2996             {
2997               for (c=0; c<nl; c++)pos[list[c]]=1;
2998               for (c=0; c<w; c++)pos[b+c]=1;
2999               score=sar_aln2r(A,B,pos,0);
3000               if ( score>best_score)
3001                 {
3002                   best_score=score;
3003                   best_pos=b;
3004                 }
3005               for (c=0; c<w; c++)pos[b+c]=0;
3006             }
3007           if (best_pos==list[nl-1])break;
3008           list[nl++]=best_pos;
3009           for (b=0; b<nl; b++) pos[list[b]]=1;
3010           fprintf ( stdout, "\n%2d P: %d S:%.3f Delta= %d", nl,best_pos, best_score, (int)sar_aln2delta(A,B, pos,0));
3011           for (b=0; b<nl; b++) pos[list[b]]=0;    
3012          
3013
3014         }
3015       for (a=0; a<nl; a++) pos[list[a]]=1;
3016       fprintf ( stdout, "\nR: %3f " ,(float)sar_aln2r(A,B,pos,1));
3017    
3018     }
3019   else if ( combo_mode==2)
3020     {
3021       int  *array;
3022       char *tmpf;
3023       FILE *fp;
3024       char *buf=NULL;
3025       int *preset,  n_preset;
3026       
3027       tmpf=vtmpnam (NULL);
3028       max=1;
3029       generate_array_int_list (max, 0,A->len_aln-1, 1,NULL, tmpf);
3030       printf_system ( "cp %s testfile", tmpf);
3031       buf=vcalloc ( 1000, sizeof (char));
3032       fp=vfopen (tmpf, "r");
3033       best_score=-99999;
3034       
3035       n_preset=0;
3036       preset=vcalloc (A->len_aln, sizeof (int));
3037       preset[n_preset++]=353;
3038       preset[n_preset++]=361;
3039       //preset[n_preset++]=365;
3040       //preset[n_preset++]=187;
3041       //preset[n_preset++]=397;
3042       //preset[n_preset++]=492;
3043
3044       
3045       while ( (buf=vfgets ( buf, fp))!=NULL)
3046         {
3047
3048           array=string2num_list (buf);
3049
3050           for (a=1; a<=max; a++)
3051             {
3052               pos[array[a]]=1;
3053             }
3054           for ( a=0; a<n_preset; a++)pos[preset[a]]=1;
3055                                          
3056           score=sar_aln2r(A,B,pos,0);
3057           
3058           if ( score>best_score)
3059             {
3060               best_score=score;
3061               fprintf ( stdout, "\n");
3062               for (a=0; a<n_preset; a++)fprintf (stdout, "%2d ", preset[a]);
3063               for (a=1; a<=max; a++)fprintf (stdout, "%2d ", array[a]);
3064               fprintf ( stdout, " R: %.3f", best_score);
3065               for (nl=0,a=0; a<n_preset; a++)list[nl++]=preset[a];
3066               for (a=1; a<=max; a++)list[nl++]=array[a];
3067             }
3068           //if ( score!=0)HERE ("R=%.2f", score);
3069           for (b=1; b<=max; b++)
3070             pos[array[b]]=0;
3071           vfree (array);
3072         }
3073       fprintf ( stdout, "\n");
3074       vfclose (fp);
3075       //for (a=0; a<max; a++)fprintf (stdout, "%2d ", array[best_pos][a]);
3076       //fprintf ( stdout, " R: %.3f", best_score);
3077     }
3078   for (c=0; c<B->len_aln; c++)
3079     {
3080       sar_aln2motif (A,B,pos, c);
3081       
3082     }
3083   myexit (EXIT_FAILURE);
3084   HERE ("***************");
3085   fp2=vfopen ("aln.aln", "w");
3086   for (a=0; a<A->nseq; a++)
3087     {
3088       fprintf (fp2, ">%s\n", A->name[a]);
3089       for ( b=0; b<nl; b++)fprintf (fp2, "%c", A->seq_al[a][list[b]]);
3090       fprintf ( fp2, "\n");
3091     }
3092   vfclose (fp2);
3093   HERE ("Output aln.aln");
3094   if (1)
3095     {
3096       float tp=0, tn=0, fp=0, fn=0, pp2=0,pp=0, sn,sn2, sp;
3097       int **result,**result2,**compound_score, *ref_score,n2,n, s, p, c;
3098       Alignment *AI, *AO;
3099       int simI, simO;
3100       
3101       compound_score=declare_int (B->len_aln, 2);
3102       ref_score=vcalloc (nl, sizeof (int));
3103       
3104       result=declare_int (B->len_aln*A->nseq*A->nseq, 2);
3105       result2=declare_int (B->len_aln*A->nseq*A->nseq, 2);
3106                           
3107       for (n2=c=0; c< B->len_aln; c++)
3108         {
3109          
3110           int sar1, sar2;
3111           pp=tp=tn=fp=fn=0;
3112           if (!M)M=read_matrice ("blosum62mt");
3113           for (n=0,a=0; a<A->nseq-1; a++)
3114             {
3115               for (b=a+1; b<A->nseq;b++)
3116                 {
3117                   for (s=0,p=0; p<nl; p++)
3118                     {
3119                       char r1, r2;
3120                       
3121                       r1=A->seq_al[a][list[p]];
3122                       r2=A->seq_al[b][list[p]];
3123                       if ( !is_gap (r1) && !is_gap(r2))s+=M[r1-'A'][r2-'A'];
3124                     }
3125                   result2[n2][0]=result[n][0]=s;
3126                   
3127                   sar1=B->seq_al[a][c];sar2=B->seq_al[b][c];
3128                   
3129                   if (sar1=='I' && sar1==sar2)
3130                     {
3131                       result2[n2][1]=result[n][1]=1;
3132                       pp++;pp2++;
3133                       n++;n2++;
3134                     }
3135                   else if ( sar1==sar2 && sar1=='O')
3136                     {
3137                       ;
3138                     }
3139                   else
3140                     {
3141                       result2[n2][1]=result[n][1]=0;
3142                       n++;n2++;
3143                     }
3144                   //else if ( s1==s2=='O')result[n][1]=-1;
3145                 }
3146             }
3147         
3148           if (pp==0)continue;
3149           sort_int_inv (result, 2, 0, 0, n-1);
3150          
3151           
3152           for (tp=0,a=0; a<n; a++)
3153             {
3154               tp+=result[a][1];
3155               if ((pp-tp) == (a-tp))break;
3156             }
3157           fp=a-tp;
3158           fn=pp-tp;
3159           tn=n-pp;
3160           
3161           sn=(tp/(tp+fn));
3162           sn2=(tp/(tp+fp));
3163           sp=(tn/(tn+fp));
3164           fprintf ( stdout, "\nCompound %3d sn: %.3f sn2: %.3f sp: %.3f MIN: %.3f",c,sn, sn2,sp, MIN((MIN(sn,sn2)),sp));
3165           compound_score[c][0]=c;
3166           compound_score[c][1]=1000*MIN((MIN(sn,sn2)),sp);
3167         }
3168       
3169       sort_int_inv (compound_score,2, 1, 0, B->len_aln-1);
3170
3171       fp2=vfopen ("compound.fasta", "w");
3172       for (d=0; d<nl; d++)
3173         {
3174           int r1, r2;
3175           for (n=0,a=0;a<A->nseq; a++)
3176             for (b=0; b<A->nseq; b++)
3177               {
3178                 r1= A->seq_al[b][list[d]];
3179                 r2= A->seq_al[b][list[d]];
3180                 if (is_gap(r1) || is_gap(r2))continue;
3181                 else 
3182                   {
3183                     ref_score[d]+=M[r1-'A'][r2-'A'];
3184                     n++;
3185                   }
3186               }
3187           ref_score[d]/=n;
3188         }
3189       AO=copy_aln (A, NULL);
3190       AI=copy_aln (A,NULL);
3191       AO->len_aln=AI->len_aln=nl;
3192       for (a=0; a<A->nseq; a++)AO->seq_al[a][nl]=AI->seq_al[a][nl]='\0';
3193       
3194       for (a=0; a<B->len_aln; a++)
3195         {
3196           fprintf (stdout, "\n>%4d %4d ", compound_score[a][0], compound_score[a][1]);
3197           for (b=0; b<B->nseq; b++) fprintf (stdout, "%c", B->seq_al[b][compound_score[a][0]]);
3198           fprintf ( stdout, "\n");
3199           
3200           for (AI->nseq=0,b=0; b<B->nseq; b++)
3201             {
3202               if (B->seq_al[b][compound_score[a][0]]=='O')continue;
3203               fprintf ( stdout, "\n\t");
3204               for (c=0; c<nl; c++)
3205                 {
3206                   fprintf ( stdout, "%c", A->seq_al[b][list[c]]);
3207                   AI->seq_al[AI->nseq][c]=A->seq_al[b][list[c]];
3208                 }
3209               AI->nseq++;
3210             }
3211           fprintf ( stdout, "\n\t");
3212           for (d=0; d<nl; d++)
3213             {
3214               for (score=0,n=0,b=0; b<B->nseq; b++)
3215                 {
3216                   if (B->seq_al[b][compound_score[a][0]]=='O')continue;
3217                   for (c=0; c<B->nseq; c++)
3218                     {
3219                       if (B->seq_al[c][compound_score[a][0]]=='O')continue;
3220                       {
3221                         int r1, r2;
3222                         
3223                         r1= A->seq_al[b][list[d]];
3224                         r2= A->seq_al[b][list[d]];
3225                         if (is_gap(r1) || is_gap(r2))continue;
3226                         else score+=M[r1-'A'][r2-'A'];
3227                         n++;
3228                       }
3229                     }
3230                 }
3231               score/=n;
3232               if ((float)score/(float)ref_score[d]>1.2)fprintf ( stdout, "*");
3233               else fprintf ( stdout, " ");
3234             }
3235           for (AO->nseq=0,b=0; b<B->nseq; b++)
3236             {
3237               if (B->seq_al[b][compound_score[a][0]]=='I')continue;
3238               fprintf ( stdout, "\n\t");
3239               for (c=0; c<nl; c++)
3240                 {
3241                   AO->seq_al[AO->nseq][c]=A->seq_al[b][list[c]];
3242                   fprintf ( stdout, "%c", A->seq_al[b][list[c]]);
3243                 }
3244               AO->nseq++;
3245             }
3246           simI=aln2sim (AI, "blosum62mt"); simO=aln2sim (AO, "blosum62mt");
3247           fprintf ( stdout, "\nDELTA: I: %d O: %d %d",simI,simO, simI-simO);
3248           delta+=simI-simO;
3249         }
3250
3251       for ( a=0; a<B->nseq; a++)
3252         {
3253
3254           fprintf ( fp2, ">%s\n", B->name[a]);
3255           for (b=0; b<B->len_aln/2; b++)
3256             fprintf ( fp2, "%c", B->seq_al[a][compound_score[b][0]]);
3257           fprintf (fp2, "\n");
3258         }
3259       vfclose (fp2);
3260       HERE ("OUTPUT compound.fasta");
3261       result=result2;
3262       n=n2;
3263       pp=pp2;
3264       
3265       sort_int_inv (result, 2, 0, 0, n-1);
3266          
3267           
3268       for (tp=0,a=0; a<n; a++)
3269         {
3270           tp+=result[a][1];
3271           if ((pp-tp) == (a-tp))break;
3272         }
3273       fp=a-tp;
3274       fn=pp-tp;
3275       tn=n-pp;
3276       
3277       sn=(tp/(tp+fn));
3278       sn2=(tp/(tp+fp));
3279       sp=(tn/(tn+fp));
3280       fprintf ( stdout, "\nTOT:  sn: %.3f sn2: %.3f sp: %.3f MIN: %.3f",sn, sn2,sp, MIN((MIN(sn,sn2)),sp));
3281    
3282     }
3283   HERE ("Delta= %d", delta);
3284   
3285     
3286   /*
3287   C=copy_aln(A, NULL);
3288   for (a=0; a< nl; a++)
3289     for (b=0; b<A->nseq; b++)
3290       C->seq_al[b][a]=A->seq_al[b][list[a]];
3291   C->len_aln=nl;
3292   array=vcalloc (C->len_aln, sizeof (int));
3293   explore_weight_matrix (C, B, 6,0, array);
3294   */
3295   
3296   return best_score;
3297 }
3298
3299
3300 void count_misc (Alignment *A, Alignment *B)
3301 {
3302   int **done, a, b, c, d, e,f, g, *list, n, score;
3303   double **slist, *r;
3304   int *pos;
3305   int w=1;
3306   
3307   search_best_combo (A,B);
3308   myexit (EXIT_FAILURE);
3309   pos=vcalloc (A->len_aln+1, sizeof (int));
3310   /*
3311   pos[354]=1;
3312   pos[362]=1;
3313   pos[366]=1;
3314   pos[398]=1;
3315   pos[476]=1;
3316   
3317   
3318   fprintf ( stdout, "\nR: %3f " ,(float)sar_aln2r(A,B,pos,1));myexit (EXIT_FAILURE);
3319   */
3320   for (a=0; a< A->len_aln-w; a++)
3321     {
3322       for (c=0; c<w; c++)
3323         {
3324           pos[a+c]=1;
3325         }
3326       pos[398]=1;
3327       pos[362]=1;
3328       pos[354]=1;
3329       pos[366]=1;
3330       pos[419]=1;
3331       pos[494]=1;
3332       pos[476]=1;
3333       pos[337]=1;
3334       fprintf ( stdout, "\nP: %3d  W:2 R: %3f ",a+1, (float)sar_aln2r(A,B,pos,0));
3335       for (c=0; c<w; c++)
3336           {
3337             pos[a+c]=0;
3338           }
3339     }
3340   
3341   myexit (EXIT_FAILURE);
3342   for (a=0; a<w; a++) pos[a]=1;
3343   for (a=w; a< A->len_aln-1; a++)
3344     {
3345       pos[a-w]=0;
3346       pos[a]=1;
3347       fprintf ( stdout, "\nP: %3d W:2 R: %3f ",a, (float)sar_aln2r(A,B,pos,0));
3348     }
3349         
3350   myexit (EXIT_FAILURE);
3351   pos[2]=1;
3352   pos[3]=1;
3353   
3354   
3355   
3356   explore_weight_matrix (A, B,3, 0,pos);
3357   myexit (EXIT_FAILURE);
3358
3359   for (a=0; a<A->len_aln; a++)
3360     for ( b=0; b<A->len_aln; b++)
3361       for (c=0; c<A->len_aln; c++)
3362         for (d=0; d<A->len_aln; d++)
3363           for (f=0; f<A->len_aln; f++)
3364             for (g=0; g<A->len_aln; g++)
3365             {
3366               e=0;
3367               pos[e++]=a;
3368               pos[e++]=b;
3369               pos[e++]=c;
3370               pos[e++]=d;
3371               pos[e++]=f;
3372               pos[e++]=g;
3373               pos[e++]=-1;
3374               fprintf ( stdout, "\n%d %d %d %d %d %d %.3f", a, b,c,d,f, g, sar_aln2r(A,B, pos,0));
3375               
3376             }
3377   
3378   myexit (EXIT_FAILURE);
3379
3380
3381   slist=declare_double (A->nseq*A->nseq*10, 2);
3382   done=declare_int (256, 256);
3383   list=vcalloc ( A->nseq, sizeof (int));
3384   
3385   for (a=0; a<A->len_aln-1; a++)
3386     {
3387       for (b =0; b<256; b++)for (c=0; c<256; c++)done[b][c]=0;
3388       
3389       for (b=0; b<A->nseq-1; b++)
3390         {
3391           int r1, r2;
3392           r1=A->seq_al[b][a];
3393           r2=A->seq_al[b][a+1];
3394           if (done[r1][r2])continue;
3395           n=0;
3396           done[r1][r2]=1;
3397           list[n++]=b;
3398           fprintf ( stdout, "\n%3d %c%c: %s ",a+1, r1, r2, A->name[b]);
3399           for ( c=b+1; c<A->nseq; c++)
3400             {
3401               if (r1==A->seq_al[c][a] && r2==A->seq_al[c][a+1])
3402                 {
3403                   fprintf ( stdout, "%s ", A->name[c]);
3404                   list[n++]=c;
3405                 }
3406
3407             }
3408           if (B && n>1)
3409             {
3410               for (e=0,score=0,c=0; c<n-1; c++)
3411                 for (d=c+1; d<n; d++,e++)
3412                   score+=get_sar_sim2(B->seq_al[list[c]], B->seq_al[list[d]]);
3413               fprintf ( stdout, " Score=%d", score/e);
3414             }
3415         }
3416     }
3417   for (score=0,e=0,a=0; a<A->nseq-1; a++)
3418     for (b=a+1; b<A->nseq; b++,e++)
3419       {
3420         score+=get_sar_sim2(B->seq_al[a], B->seq_al[b]);
3421       }
3422   fprintf  (stdout,"AVG=%d", score/e);
3423   for (n=0,a=0; a< A->nseq-1; a++)
3424     {
3425       static int **M;
3426       int sim;
3427       if (!M)M=read_matrice ("blosum62mt");
3428       
3429       
3430       for (b=a+1; b<A->nseq; b++)
3431         {
3432           int n11, n01, n10, n00, n1;
3433           
3434           for (sim=d=0;d<A->len_aln; d++)
3435             {
3436               int r1, r2;
3437               r1=A->seq_al[a][d];
3438               r2=A->seq_al[b][d];
3439               sim+=(r1==r2)?1:0;
3440               //sim +=(M[r1-'A'][r2-'A']>0)?1:0;
3441             }
3442           
3443           sim=(100*sim)/(A->len_aln);//+rand()%10;
3444           for (n1=n00=n11=n10=n01=score=0, d=0; d<B->len_aln; d++)
3445             {
3446               int r1, r2;
3447               r1=B->seq_al[a][d];
3448               r2=B->seq_al[b][d];
3449               n11+=(r1=='I' && r2=='I');
3450               n00+=(r1=='O' && r2=='O');
3451               n10+=(r1=='I' && r2=='0');
3452               n01+=(r1=='O' && r2=='I');
3453               n1+=(r1=='I' || r2=='I');
3454             }
3455           score =((n11+n00)*100)/B->len_aln;
3456               
3457           //score=get_sar_sim2(B->seq_al[a], B->seq_al[b]);
3458           
3459           fprintf ( stdout, "\nSIM: %d SC: %d", sim, score);
3460           slist[n][0]=(double)sim;
3461           slist[n][1]=(double)score;
3462           n++;
3463         }
3464     }
3465   r=return_r(slist, n);
3466   fprintf ( stdout, "\nR= %.4f", (float)r[0]);
3467   myexit (EXIT_FAILURE);
3468 }
3469
3470 int aln2ngap ( Alignment *A)
3471 {
3472   int ngap=0, a, b;
3473   for (a=0; a< A->len_aln; a++)
3474     for (b=0; b<A->nseq; b++) ngap+=is_gap (A->seq_al[b][a]);
3475   return ngap;
3476 }
3477 int  * count_in_aln ( Alignment *A, Alignment *ST, int value, int n_symbol,char **symbol_list, int *table)
3478         {
3479           int a, b, c=0, d;
3480           int st;
3481           
3482           if (!table)table=vcalloc (n_symbol, sizeof (int));
3483
3484           A->residue_case=KEEP_CASE;
3485           for ( a=0; a< A->nseq; a++)
3486                 {
3487                 if(value!=10 && ST)for ( c=0; c< ST->nseq; c++)if ( strm(ST->name[c], A->name[a]))break;
3488                 for ( b=0; b< A->len_aln; b++)
3489                     {
3490                       if ( value==10 || !ST)st=11;
3491                       else st=(isdigit(ST->seq_al[c][b]))?ST->seq_al[c][b]-'0':ST->seq_al[c][b];
3492                       if ( st==value || value==-1) 
3493                         {
3494                           for ( d=0; d<n_symbol; d++)table[d]+=is_in_set ( A->seq_al[a][b], symbol_list[d]);
3495                         }
3496                     }
3497                 }
3498           return table;
3499         } 
3500
3501 char *dna_aln2cons_seq ( Alignment *A)
3502         {
3503         int a, b, best;
3504         static int **column_count;
3505         static int **old_tot_count;
3506         static int **new_tot_count;
3507         static char *string1, *string2;
3508         int **count_buf;
3509         char r1, r2,*seq;
3510         int NA=0, NG=1, NC=2, NT=3, IGAP=4;
3511         static int   MAX_EST_SIZE=10000;
3512         static int   size_increment=1000;
3513         static int first;
3514         int overlap=0, best_overlap=0;
3515         
3516
3517         seq=vcalloc ( A->len_aln+1, sizeof (char));
3518
3519         if (!column_count )
3520           {
3521             column_count=vcalloc(MAX_EST_SIZE, sizeof (int*));
3522             for ( a=0; a< MAX_EST_SIZE; a++)
3523               column_count[a]=vcalloc (5, sizeof (int));
3524           
3525             old_tot_count=vcalloc(MAX_EST_SIZE, sizeof (int*));
3526             new_tot_count=vcalloc(MAX_EST_SIZE, sizeof (int*));
3527             A->P=declare_profile( "agct-",MAX_EST_SIZE);
3528             string1=vcalloc (MAX_EST_SIZE, sizeof (char));
3529             string2=vcalloc (MAX_EST_SIZE, sizeof (char));
3530           }
3531         else if (A->len_aln>MAX_EST_SIZE)
3532           {
3533             if ( column_count)
3534               {
3535                 for ( a=0; a< MAX_EST_SIZE; a++)
3536                   vfree(column_count[a]);
3537                 vfree(column_count);
3538                 vfree(old_tot_count);
3539                 vfree(new_tot_count);
3540                 vfree(string1);
3541                 vfree(string2);
3542               }
3543             
3544           column_count=vcalloc(MAX_EST_SIZE+ size_increment, sizeof (int*));
3545           for ( a=0; a< MAX_EST_SIZE+ size_increment; a++)
3546               column_count[a]=vcalloc (5, sizeof (int));
3547           
3548           old_tot_count=vcalloc(MAX_EST_SIZE+ size_increment, sizeof (int*));
3549           new_tot_count=vcalloc(MAX_EST_SIZE+ size_increment, sizeof (int*));
3550           
3551           for (a=0; a< MAX_EST_SIZE; a++)
3552             {
3553               old_tot_count[a]=*(column_count++);
3554               for ( b=0; b<5; b++)old_tot_count[a][b]=(A->P)->count[b][a];
3555             }
3556           free_int ( (A->P)->count, -1);
3557           
3558           (A->P)->count=declare_int (5, MAX_EST_SIZE+ size_increment);
3559           (A->P)->max_len=MAX_EST_SIZE+ size_increment;
3560           MAX_EST_SIZE+= size_increment;
3561           string1=vcalloc (MAX_EST_SIZE, sizeof (char));
3562           string2=vcalloc (MAX_EST_SIZE, sizeof (char));
3563           }
3564         
3565         
3566         sprintf ( string1, "%s",A->seq_al[0]);
3567         sprintf ( string2, "%s",A->seq_al[1]);
3568         
3569
3570         string1=mark_internal_gaps(string1,'.');
3571         string2=mark_internal_gaps(string2,'.');
3572
3573         
3574         
3575         for (b=0,a=0; a< A->len_aln; a++)
3576           {
3577             r1=string1[a];
3578             r2=string2[a];
3579             
3580             if ( r1==r2)
3581               {
3582                 overlap++;
3583               }
3584             else
3585               {
3586                 best_overlap=MAX(overlap, best_overlap);
3587                 overlap=0;
3588               }
3589
3590
3591             if (!is_gap(r1) && first==1)new_tot_count[a]=old_tot_count[b++]; 
3592             else if (is_gap(r1) || first==0){new_tot_count[a]=*column_count;column_count++;};
3593             
3594             if ( first==0)
3595               {
3596                 if(r1=='a')       new_tot_count[a][NA]++;
3597                 else if ( r1=='g')new_tot_count[a][NG]++;
3598                 else if ( r1=='c')new_tot_count[a][NC]++;
3599                 else if ( r1=='t')new_tot_count[a][NT]++;       
3600                 else if (is_gap(r1));
3601                 else
3602                   {
3603                    new_tot_count[a][NA]++;
3604                    new_tot_count[a][NG]++;
3605                    new_tot_count[a][NC]++;
3606                    new_tot_count[a][NT]++;
3607                   }
3608               }
3609             if ( a> 0 && a<A->len_aln-1 && r1=='.')
3610               {
3611                 new_tot_count[a][IGAP]+=((new_tot_count[a-1][NA]+new_tot_count[a-1][NG]+new_tot_count[a-1][NC]+new_tot_count[a-1][NT]));
3612               }
3613             
3614
3615             if(r2=='a')       new_tot_count[a][NA]++;
3616             else if ( r2=='g')new_tot_count[a][NG]++;
3617             else if ( r2=='c')new_tot_count[a][NC]++;
3618             else if ( r2=='t')new_tot_count[a][NT]++;
3619             else if ( r2=='.')new_tot_count[a][IGAP]++;
3620             else if ( r2=='-');
3621             else 
3622               {
3623                 new_tot_count[a][NA]++;
3624                 new_tot_count[a][NG]++;
3625                 new_tot_count[a][NC]++;
3626                 new_tot_count[a][NT]++; 
3627               }
3628             (A->P)->count[0][a]=new_tot_count[a][NA];
3629             (A->P)->count[1][a]=new_tot_count[a][NG];
3630             (A->P)->count[2][a]=new_tot_count[a][NC];
3631             (A->P)->count[3][a]=new_tot_count[a][NT];
3632             (A->P)->count[4][a]=new_tot_count[a][IGAP];
3633
3634             best_int(4,1, &best,new_tot_count[a][NA], new_tot_count[a][NG],new_tot_count[a][NC],new_tot_count[a][NT]); 
3635             if( best==0)      seq[a]='a';
3636             else if ( best==1)seq[a]='g';
3637             else if ( best==2)seq[a]='c';
3638             else if ( best==3)seq[a]='t';
3639           }
3640
3641         first=1;
3642
3643         seq[a]='\0';
3644         fprintf ( stderr, "[Best Overlap: %d Residues]", best_overlap);
3645         count_buf=old_tot_count;
3646         old_tot_count=new_tot_count;
3647         new_tot_count=count_buf;
3648
3649         return seq;
3650         
3651         }
3652
3653 char *aln2cons_maj ( Alignment *A, int ns, int *ls, int n_groups, char **group_list)
3654         {
3655         char *seq;
3656         int a, b;
3657         int len;
3658         int clean_ls=0;
3659         static int *aa;
3660
3661         if ( !aa) aa=vcalloc (1000, sizeof (int));
3662         
3663         len=strlen  (A->seq_al[ls[0]]);
3664         seq=vcalloc (len+1, sizeof (char));
3665
3666         if ( ns==0)
3667           {
3668             ns=A->nseq;
3669             ls=vcalloc ( A->nseq, sizeof (int));
3670             for ( a=0; a< A->nseq; a++)ls[a]=a;
3671             clean_ls=1;
3672           }
3673         
3674         for ( a=0; a<len; a++)
3675             {
3676               int best_s=0, best_aa=0, r;
3677               for (b=0; b< ns; b++)
3678                     {
3679                       r=tolower(A->seq_al[ls[b]][a]);
3680                       aa[r]++;
3681                       if (!is_gap(r) && aa[r]>best_s)
3682                         {
3683                           best_s=aa[r];
3684                           best_aa=r;
3685                         }
3686                       seq[a]=best_aa;
3687                     }
3688                 for (best_s=0, best_aa=0,b=0; b< ns; b++)
3689                   {
3690                     aa[tolower(A->seq_al[ls[b]][a])]=0;
3691                   }
3692             }
3693         if ( clean_ls)vfree(ls);
3694         seq[a]='\0';
3695         
3696         return seq;
3697         }
3698
3699 char *aln2cons_seq ( Alignment *A, int ns, int *ls, int n_groups, char **group_list)
3700         {
3701         char *seq;
3702         int a, b, c;
3703         int best_group=0;
3704         int aa_group=0;
3705         int *group;
3706         int len;
3707         int clean_ls=0;
3708         
3709         len=strlen  (A->seq_al[ls[0]]);
3710         seq=vcalloc (len+1, sizeof (char));
3711
3712         if ( ns==0)
3713           {
3714             ns=A->nseq;
3715             ls=vcalloc ( A->nseq, sizeof (int));
3716             for ( a=0; a< A->nseq; a++)ls[a]=a;
3717             clean_ls=1;
3718           }
3719
3720
3721         if ( !group_list)
3722            {
3723                group_list=declare_char ( 26, 2);
3724                for ( a=0; a<26; a++)group_list[a][0]=a+'a';
3725                n_groups=26;
3726                aa_group=1;
3727            }
3728         
3729         
3730         for ( a=0; a<len; a++)
3731             {
3732                 group=vcalloc (n_groups+1, sizeof (int));
3733                 for (best_group=0,b=0; b< ns; b++)
3734                     {
3735                     if ( !is_gap(A->seq_al[ls[b]][a]))
3736                          {
3737                          for (c=0; c< n_groups; c++)
3738                              if ( is_in_set (tolower(A->seq_al[ls[b]][a]), group_list[c]))
3739                                          {group[c]++;
3740                                           best_group=(group[c]>group[best_group])?c:best_group;
3741                                          }
3742                          }
3743                     seq[a]=group_list[best_group][0];
3744                     }
3745                 vfree (group);
3746             }
3747         seq[a]='\0';
3748         if ( aa_group) free_char (group_list, -1);
3749
3750         if ( clean_ls)vfree(ls);
3751         
3752         return seq;
3753         }
3754
3755 Alignment *aln2conservation ( Alignment *A, int threshold,char *seq)
3756 {
3757   int a, b, c, d, i, c1, c2;
3758   int   *pos;
3759   float *eval;
3760   float tot=0;
3761   float tn=0;
3762   int **sim;
3763   int w=0;
3764   
3765   pos =vcalloc (A->len_aln, sizeof (int));
3766   eval=vcalloc (A->len_aln, sizeof (int));
3767   sim=aln2sim_mat (A, "idmat");
3768   if (seq)i=name_is_in_list (seq, A->name, A->nseq, 100);
3769   else i=0;
3770   
3771   if ( i==-1) {HERE ("%s is an unknown:sequence [FATAL]"); myexit (EXIT_FAILURE);}
3772   
3773   for (a=0; a<A->len_aln; a++)
3774     {
3775       double s;
3776       int e;
3777       for (c=0,e=a-w; e<=a+w; e++)
3778         {
3779           if (e<0 || e==A->len_aln)continue;
3780           c1=toupper (A->seq_al[i][e]);
3781           for (b=0; b<A->nseq; b++)
3782             {
3783               c2=toupper (A->seq_al[b][a]);
3784               if (c1==c2)
3785                 {       
3786                   c++;
3787                   s=(double)((double)sim[i][b]/(double)(100));
3788                   
3789                 }
3790               else
3791                 {
3792                   s=(double)(((double)100-(double)sim[i][b])/(double)(100));
3793                 }
3794               eval[a]+=(s==0)?0:log(s);
3795             }
3796         }
3797       pos[a]=(c*100)/A->nseq;
3798       if (!is_gap(c1)){tot+=pos[a]; tn++;}
3799       
3800       if (pos[a]>=threshold)A->seq_al[i][a]=toupper (A->seq_al[i][a]);
3801       else A->seq_al[i][a]=tolower (A->seq_al[i][a]);
3802     }
3803   fprintf (stdout, ">%s %s [i=%d]\n%s\n", A->name[i],A->aln_comment[i],i, A->seq_al[i]);
3804   tot=(tn>0)?(float)tot/(float)tn:0;
3805   
3806   for (d=0,a=0; a<A->len_aln; a++)
3807     {
3808       fprintf (stdout, "# %c %4d", A->seq_al[i][a],pos[a]);
3809
3810       
3811       if ( !is_gap (A->seq_al[i][a]))
3812         {
3813           fprintf (stdout, " LogOdd: %6.2f ", (tot==0 || pos[a]==0)?0:(float)log((float)pos[a]/tot));
3814           fprintf ( stdout, " Pos: %5d E-Val: %9.2f", ++d, eval[a]/(A->nseq));
3815         }
3816       fprintf ( stdout, "\n");
3817     }
3818   fprintf ( stdout, "#average conservation: %.2f", tot);
3819   myexit (EXIT_SUCCESS);
3820 }
3821 char *aln2cons_seq_mat ( Alignment *A, char *mat_name)
3822 {
3823   return sub_aln2cons_seq_mat (A, A->nseq, NULL, mat_name);
3824 }
3825 char *sub_aln2cons_seq_mat2 ( Alignment *A,int ns, char **ls, char *mat_name)
3826 {
3827   char *cons;
3828   int *list;
3829   list=name_array2index_array(ls, ns, A->name, A->nseq);
3830   cons=sub_aln2cons_seq_mat  ( A,ns, list, mat_name);
3831   vfree (list);
3832   return cons;
3833 }
3834
3835 char *sub_aln2cons_seq_mat  ( Alignment *A,int ns, int *ls, char *mat_name)
3836 {
3837  int a, b, c, s;
3838  char *seq, r1, r2;
3839  int **mat;
3840  int score=0, best_score=0, best_r=0;
3841  int len;
3842  int naa;
3843  
3844  mat=read_matrice (mat_name);
3845  len=strlen ( A->seq_al[(ls==NULL)?0:ls[0]]);
3846  seq=vcalloc (len+1, sizeof (char));
3847  for ( a=0; a<len; a++)     
3848    {
3849      for (b=0; b<20; b++)
3850        {
3851          r1=AA_ALPHABET[b];
3852          for ( naa=0,score=0,c=0; c<ns; c++)
3853            {
3854              s=(ls==NULL)?c:ls[c];
3855              if ( ls && ls[c]==-1) continue;
3856              else if (is_gap(A->seq_al[s][a]))continue;
3857              else 
3858                {
3859                  naa++;
3860                  r2=A->seq_al[s][a];
3861                  score+=mat[r1-'A'][r2-'A'];
3862                }
3863            }
3864          if (naa==0)best_r='-';
3865          if ( b==0 || score>best_score){best_score=score; best_r=r1;}
3866        }
3867      seq[a]=best_r;
3868    }
3869  free_int (mat, -1);
3870  return seq;
3871 }
3872
3873 int  seq_list2in_file ( TC_method *M, Sequence *S, char *list, char *file)
3874 {
3875   X_template *T=NULL;
3876   
3877   if ( !S)return 0;
3878   else
3879     {
3880       int t;
3881       t=tolower(M->seq_type[0]);
3882      
3883       if ( t=='s')
3884         {
3885           return seq_list2fasta_file ( S, list, file, M->out_mode);
3886           
3887         }
3888       else
3889         {
3890           FILE *fp, *fp2;
3891           int a, n, s, c;
3892           int *slist;
3893
3894
3895           
3896           fp=vfopen ( file, "w");
3897           slist=string2num_list (list);
3898           n=slist[0];
3899           
3900           if (strlen (M->seq_type) >1)
3901             {
3902               add_warning( stderr, "\nERROR: Mixed seq_type not supported for external methods\n[FATAL:%s]", PROGRAM);
3903             }
3904           
3905           for ( a=2; a<n; a++)
3906             {
3907               s=slist[a];
3908               if (t=='p')T=(S->T[s])->P;
3909               else if (t=='r')T=(S->T[s])->R;
3910               else if (t=='g')T=(S->T[s])->G;
3911               
3912               if (!T && t=='r')
3913                 {
3914                   fprintf ( fp, ">%s\n%s%s", S->name[s], S->seq[s], LINE_SEPARATOR);
3915                 }
3916               else if ( T && T->template_file && T->template_file[0])
3917                 {
3918                   fp2=vfopen (T->template_file, "r");
3919                   while ( (c=fgetc (fp2))!=EOF)
3920                     {
3921                       fprintf ( fp, "%c", c);
3922                     }
3923                   fprintf (fp, "%s", LINE_SEPARATOR);
3924                   vfclose (fp2);
3925                 }
3926             }
3927
3928           fprintf (fp, "TARGET_SEQ_NAME: ");
3929           for (a=2; a<n; a++)fprintf ( fp, "%s ", (S->name[slist[a]]));
3930           fprintf ( fp, "%s", LINE_SEPARATOR);
3931           
3932           vfclose (fp); vfree (slist);
3933           
3934         }
3935
3936       return 1;
3937     }
3938 }
3939
3940 int  seq_list2fasta_file( Sequence *S,  char *list, char *file, char *outmode)
3941         {
3942         FILE *fp;
3943         int n, a, s;
3944         static char *buf;
3945         static int blen;
3946         int l;
3947         //out_mode: names can only be re-converted when out mode is aln
3948         
3949         /*Buf is used because cmalloced functions cannot go through strtok*/
3950         if ( !S)return 0;
3951         else
3952           {
3953             fp=vfopen ( file, "w");
3954             if ( !list)
3955               {
3956                 for ( a=0; a<S->nseq; a++)
3957                   {
3958                     if (outmode && strm (outmode, "aln"))fprintf ( fp, ">%s %s\n%s\n", decode_name (S->name[a], CODE),S->name[a], S->seq[a]);
3959                     else fprintf ( fp, ">%s %s\n%s\n", S->name[a],S->name[a], S->seq[a]);
3960                   }
3961               }
3962             else
3963               {
3964                 int **list2;
3965                 int max;
3966                 
3967                 l=strlen (list);
3968                 if ( l>blen)
3969                   {
3970                     if (buf)vfree(buf);
3971                     buf=vcalloc ( strlen (list)+1, sizeof (char));
3972                     sprintf ( buf, "%s", list);
3973                     blen=l;
3974                   }
3975                 n=atoi(strtok (list,SEPARATORS));
3976                 
3977                 list2=declare_int (n, 2);
3978                 max=n*1000;
3979                 for ( a=0; a<n; a++)
3980                   {
3981                     list2[a][0]=atoi(strtok (NULL, SEPARATORS));
3982                     list2[a][1]=rand()%max;
3983                   }
3984                 if ( atoigetenv ("HoT_4_TCOFFEE"))sort_int ( list2,2, 1, 0, n-1);
3985                 for ( a=0; a< n; a++)
3986                   {
3987                     int i=list2[a][0];
3988                     if (outmode && strm (outmode, "aln"))fprintf ( fp, ">%s %s\n%s\n", decode_name (S->name[i], CODE), S->name[a],S->seq[i]);
3989                     else fprintf ( fp, ">%s %s\n%s\n", S->name[a], S->name[a],S->seq[i]);
3990                   }
3991               }
3992             vfclose (fp);
3993           }
3994         return 1;
3995         }
3996 Structure * seq2struc ( Sequence *S, Structure *ST)
3997         {
3998         int a, b;
3999         
4000         for ( a=0; a< S->nseq; a++)
4001             for ( b=0; b< S->len[a]; b++)
4002                 ST->struc[a][b+1][ST->n_fields-1]=S->seq[a][b];
4003         return ST;
4004         }
4005
4006 void aln2struc (Alignment *A, Structure *ST) 
4007         {
4008         int a, b, c;
4009
4010         for ( a=0; a< A->nseq; a++)
4011             for (c=0, b=0; b< A->len_aln; b++)
4012                 {
4013                 if ( !is_gap (A->seq_al[a][b]))
4014                      {
4015                      ST->struc[a][c][ST->n_fields-1]=A->seq_al[a][b];
4016                      c++;
4017                      }
4018                 }
4019         }
4020 Alignment *stack_aln (Alignment *A, Alignment *B)
4021         {
4022         int a,b;
4023         int max_len=0, max_nseq=0;
4024         if ( B==NULL)return A;
4025         if ( A==NULL)return B;
4026         
4027         max_nseq=A->nseq+B->nseq;
4028         for (a=0; a< A->nseq; a++)max_len=MAX(strlen(A->seq_al[a]),max_len);
4029         for (a=0; a< B->nseq; a++)max_len=MAX(strlen(B->seq_al[a]),max_len);
4030         
4031         A=realloc_aln2 ( A,max_nseq,max_len+1);
4032         
4033         for (a=A->nseq,b=0; b< B->nseq; b++, a++)
4034             {
4035             sprintf ( A->seq_comment[a] , "%s", B->seq_comment[b]);
4036             sprintf ( A->aln_comment[a] , "%s", B->aln_comment[b]);
4037             
4038             sprintf ( A->seq_al [a] , "%s", B->seq_al [b]);
4039             sprintf ( A->name   [a] , "%s", B->name[b]);
4040             sprintf ( A->file   [a], "%s" , B->file[b]);
4041             A->order[a][0]=B->order[b][0];
4042             A->order[a][1]=B->order[b][1];
4043             A->score_seq[a]=B->score_seq[b];
4044             A->len[a]=B->len[b];
4045             }
4046         
4047         A->len_aln=MAX(A->len_aln, B->len_aln);
4048         A->nseq=A->nseq+B->nseq;
4049         A->score_aln=A->score_aln+B->score_aln;
4050         
4051         A->finished=A->finished+B->finished;
4052         return A;
4053         }
4054             
4055 Alignment *chseqIaln(char *name, int seq_n, int start,int len,Sequence *S, int seqIaln, Alignment *A)
4056         {
4057         char *seq;
4058
4059         seq=extract_char ( S->seq[seq_n], start, len);
4060         A=realloc_aln2 (A, (A==NULL)?(seqIaln+1):MAX(A->nseq,seqIaln+1), ((A==NULL)?(strlen (seq)):MAX(strlen (seq),A->len_aln))+1);
4061         
4062         
4063         sprintf ( A->seq_al[seqIaln], "%s",seq);
4064
4065         
4066         A->order[seqIaln][0]=seq_n;
4067         A->order[seqIaln][1]=start;
4068         sprintf ( A->name[seqIaln], "%s", name);
4069         A->nseq=MAX(A->nseq, seqIaln+1);
4070         A->len_aln=return_maxlen(A->seq_al, A->nseq);
4071         A->S=S;
4072         vfree (seq);
4073         return A;
4074         }
4075
4076 Alignment * aln_gap2random_aa(Alignment *A)
4077         {
4078          int a, b,l;
4079          char alp[200];
4080          
4081          if (strm ( (A->S)->type, "PROTEIN"))
4082            sprintf ( alp, "acefghiklmnpqrstuvwy");
4083          else if ( strm ( (A->S)->type, "DNA") ||strm ( (A->S)->type, "RNA") )
4084            sprintf ( alp, "agct");
4085          l=strlen (alp);
4086          
4087          
4088          for (a=0; a<A->nseq; a++)
4089             for ( b=0; b<A->len_aln; b++)
4090               if ( is_gap (A->seq_al[a][b]))A->seq_al[a][b]=alp[(int)rand()%(l)];
4091           return A;
4092         }
4093
4094 Alignment * make_random_aln(Alignment *A,int nseq, int len, char *alphabet)
4095         {
4096         int a;
4097         
4098
4099         A=realloc_aln2(A, nseq, len+1);
4100
4101         A->nseq=0;
4102         A->len_aln=len;
4103         for ( a=0; a< A->nseq; a++)sprintf ( A->file[a], "random alignment");
4104         for ( a=0; a< nseq; a++)
4105             A=add_random_sequence2aln(A,alphabet);
4106         return A;
4107         }
4108 Alignment * add_random_sequence2aln( Alignment *A, char *alphabet)
4109         {
4110         int a, n;
4111
4112         vsrand(0);
4113
4114         n=strlen(alphabet);
4115         A=realloc_alignment2 (A, A->nseq+1, A->len_aln+1);
4116         
4117         for ( a=0; a< A->len_aln; a++)A->seq_al[A->nseq][a]=alphabet[rand()%n];
4118         if (! A->name[A->nseq][0])
4119           {
4120             for ( a=0; a<10; a++)A->name[A->nseq][a]=alphabet[rand()%n];
4121             A->name[A->nseq][a]='\0';
4122           }
4123         
4124         A->nseq++;
4125         return A;
4126         }
4127
4128 Sequence *get_defined_residues( Alignment *A)
4129         {
4130             char *buf;
4131             Sequence *S;
4132             int a, b, s, l, r;
4133             if ( !A || !A->S) return NULL;
4134
4135             S=duplicate_sequence (A->S);
4136             for ( a=0; a< S->nseq; a++)
4137                 for ( b=0; b< S->len[a]; b++)S->seq[a][b]=UNDEFINED_RESIDUE;
4138             buf=vcalloc(A->len_aln+1,sizeof (char));
4139             for ( a=0; a< A->nseq; a++)
4140                 {
4141                     sprintf ( buf, "%s",A->seq_al[a]);
4142                     ungap(buf);
4143                     l=strlen (buf);
4144                     s=A->order[a][0];
4145                     
4146                     for ( b=1; b<= l; b++)
4147                         {
4148                         r=A->seq_cache[s][b];
4149                         
4150                         if ( r>=0)S->seq[s][r-1]=(A->S)->seq[s][r-1];
4151                         }
4152                 }
4153             vfree(buf);
4154             return S;
4155         }
4156 Alignment *thread_defined_residues_on_aln ( Alignment *A, Sequence *S1)
4157         {
4158         int a, b;
4159         int gap, r,s, r2;
4160         for ( a=0; a< A->nseq; a++)
4161             {
4162                 s=A->order[a][0];
4163                 r=A->order[a][1];
4164                 for (b=0;b< A->len_aln; b++)
4165                     {
4166                     gap=is_gap(A->seq_al[a][b]);
4167                     
4168                     if (!gap)
4169                         {
4170                         r+=!gap;
4171                         r2=A->seq_cache[s][r]-1;
4172                         
4173                         if (r2>=0 && S1->seq[s][r2]==UNDEFINED_RESIDUE)
4174                             A->seq_al[a][b]=UNDEFINED_RESIDUE;
4175                         }
4176                     }
4177             }
4178         return A;
4179         }
4180
4181 int ** trim_aln_borders (char **seq1, char **seq2, int nseq)
4182         {
4183         int a, b, c,l1,l2;
4184         char *buf1;
4185         char *buf2;
4186         int max;
4187
4188         
4189
4190         
4191         max=MAX(get_longest_string (seq1,-1, NULL, NULL),get_longest_string (seq2,-1, NULL, NULL))+1;
4192         buf1=vcalloc ( max, sizeof(char));
4193         buf2=vcalloc ( max, sizeof(char));
4194         
4195         for ( a=0; a< nseq; a++)
4196             {
4197             sprintf ( buf1, "%s", seq1[a]);
4198             sprintf ( buf2, "%s", seq2[a]);
4199
4200
4201            
4202             ungap (buf1);
4203             ungap (buf2);
4204
4205             if (str_overlap ( buf1, buf2,'*')!=0)
4206                 {                     
4207                 l1=strlen ( seq1[a]);
4208                 l2=strlen ( seq2[a]);
4209                 for ( b=0,c=0; c< l1; c++)
4210                     if ( !is_gap(seq1[a][c]))seq1[a][c]=buf1[b++];
4211                 seq1[a][c]='\0';
4212                 for ( b=0,c=0; c< l2; c++)
4213                     if ( !is_gap(seq2[a][c]))seq2[a][c]=buf2[b++]; 
4214                 seq2[a][c]='\0';
4215                 }
4216             }
4217         vfree (buf1);
4218         vfree (buf2);
4219         return NULL;
4220
4221         }
4222 Sequence * merge_seq    ( Sequence *IN, Sequence *OUT)
4223         {
4224         int a;
4225         
4226         if ( OUT==NULL)return duplicate_sequence (IN);
4227         else
4228             {
4229              if ( IN && check_list_for_dup( IN->name, IN->nseq))
4230                   {
4231                       fprintf ( stderr, "\nERROR: %s is duplicated in file %s[FATAL]\n", check_list_for_dup( IN->name, IN->nseq), IN->file[0]);
4232                       myexit (EXIT_FAILURE);
4233                   }
4234             for ( a=0; a< IN->nseq; a++)
4235                 if ((OUT=add_sequence ( IN, OUT, a))==NULL)return NULL;
4236             return OUT;
4237             }
4238         }
4239
4240 Alignment *seq_name2removed_seq_name(Sequence *S, Alignment *NA, float **diff)
4241 {
4242   int a, b, rb, s;
4243   float min_diff;
4244   for (a=0; a< S->nseq; a++)
4245     {
4246       if (name_is_in_list( S->name[a], NA->name, NA->nseq, 100)!=-1) continue;
4247       for ( min_diff=100, s=0, b=0; b< NA->nseq; b++)
4248         {
4249           rb=name_is_in_list ( NA->name[b], S->name, S->nseq, 100);
4250           if ( diff[a][rb]<min_diff)
4251             {   
4252               s=b;
4253               min_diff=diff[a][rb];
4254
4255             }
4256         }
4257       strcat ( NA->seq_comment[s], " ");
4258       strcat ( NA->seq_comment[s], S->name[a]);
4259     }
4260   return NA;
4261 }
4262   
4263       
4264               
4265      
4266 int seq_name2index (char *name, Sequence *S)
4267 {
4268   if ( !S) return -1;
4269   else return name_is_in_list ( name, S->name, S->nseq, MAXNAMES+1);
4270 }
4271 char * seq_name2coor ( char *s, int *start, int *end, char sep)
4272 {
4273   /*name|start|end */
4274   char n1[100], n2[100];
4275   int a=0, b=0, c=0;
4276   
4277   n1[0]=n2[0]='\0';
4278   start[0]=end[0]=0;
4279   
4280   while ( s[a]!=sep && s[a]!='\0')a++;
4281   if ( s[a]=='\0')return s;
4282   else 
4283     s[a++]='\0';
4284
4285  
4286   
4287   while ( s[a]!=sep && s[a]!='\0')n1[b++]=s[a++];
4288   
4289   if ( s[a]=='\0'){n1[b]='\0';if ( n1[0])start[0]=atoi(n1);return s;}
4290   else s[a++]=n1[b]='\0';
4291  
4292   
4293   while ( s[a]!=sep && s[a]!='\0')n2[c++]=s[a++];
4294   n2[c]='\0';
4295
4296   
4297   if ( n1[0])start[0]=atoi(n1);
4298   if ( n2[0])end[0]=atoi(n2);
4299
4300
4301   return s;
4302 }
4303   
4304 Sequence *extract_one_seq(char *n,int start, int end, Alignment *S, int keep_name)
4305        {
4306         
4307          int seq, a;
4308          FILE*fp;
4309          char *name;
4310          Sequence *OUT_S;
4311          
4312
4313          if ( n[0]=='#')seq=S->nseq;
4314          else if ( (seq=name_is_in_list (n, S->name, S->nseq, 100)+1)!=0);
4315          else if (is_number (n) && (seq=atoi(n))!=0) seq=atoi(n);
4316          else
4317            {
4318              fprintf ( stderr, "\nCould not find Sequence %s [FATAL]", n);
4319              myexit (EXIT_FAILURE);
4320            }
4321          seq--;
4322          
4323          name=vtmpnam ( NULL);
4324          fp=vfopen ( name, "w");
4325          if ( start && end &&!keep_name)fprintf (fp, ">%s_%d_%d\n",S->name[seq],start, end);
4326          else if ( start && end==0 && !keep_name)fprintf (fp, ">%s_%d_%d\n",S->name[seq],start,(int)strlen ( S->seq_al[seq]));
4327          else fprintf (fp, ">%s\n", S->name[seq]);
4328          
4329          if ( start==0 && end==0){fprintf (fp, "%s\n", S->seq_al[seq]);}
4330          else if (end==0){fprintf (fp, "%s\n", S->seq_al[seq]+start-1);}
4331          else
4332            {
4333              for ( a=start-1; a<end; a++){fprintf ( fp, "%c", S->seq_al[seq][a]);}
4334              fprintf ( fp, "\n");
4335            }
4336          
4337          
4338          vfclose (fp);
4339          OUT_S=get_fasta_sequence_num (name, NULL);
4340          
4341          return OUT_S;
4342        }
4343          
4344
4345          
4346 Sequence * extract_sub_seq( Sequence  *COOR, Sequence *S)
4347         {
4348         int a, b, c,s;
4349         int start, end;
4350         
4351         for ( a=0; a< S->nseq; a++)
4352             {
4353             if ( (s=name_is_in_list ( S->name[a], COOR->name, COOR->nseq, 100))!=-1)
4354                  {
4355                  
4356                  sscanf ( COOR->seq_comment[s], "%d %d", &start, &end);
4357                  for (c=0,b=start-1; b< end; b++, c++)S->seq[a][c]=S->seq[a][b];
4358                  S->seq[a][c]='\0';
4359                  sprintf ( S->seq_comment[a], "%s",COOR->seq_comment[s]);
4360                  
4361                  }
4362             }
4363         S=reorder_seq ( S, COOR->name, COOR->nseq);
4364         return S;
4365         }
4366                  
4367
4368
4369 char *    aln_column2string (Alignment *A, int p)
4370   {
4371     char *s;
4372     int a;
4373     if (p>=A->len_aln)
4374       {
4375         HERE ("ERROR: index (p=%d) loger than aln (l=%d) [FATAL]", p, A->len_aln);
4376         myexit (EXIT_FAILURE);
4377       }
4378     else
4379       {
4380         s=vcalloc (A->nseq+1, sizeof (char));
4381         for (a=0; a< A->nseq; a++)s[a]=A->seq_al[a][p];
4382       }
4383     return s;
4384   }
4385
4386
4387 int **fix_seq_aln (Sequence *S, Alignment*A, int **cache)
4388 {
4389   int s, b,i,nr;
4390   
4391   if (!cache)cache=vcalloc (S->nseq, sizeof (int*));
4392   
4393   for (s=0; s<A->nseq; s++)
4394     {
4395       if ((i=name_is_in_list (A->name[s], S->name, S->nseq, 100)==-1))continue;
4396       for (nr=0,b=0; b<A->len_aln; b++)
4397         {
4398           if (!is_gap(A->seq_al[s][b]))
4399             cache[i][++nr]=b+1;
4400         }
4401     }
4402   return cache;
4403 }
4404
4405 int **fix_seq_seq (Sequence *S0, Sequence *Sx)
4406 {
4407   //Expresses seq1 in terms of s2
4408   //sequences 0-N
4409   //residues  1-N+1
4410   int s0, r0,i;
4411   int **index;
4412
4413   index=vcalloc ( S0->nseq, sizeof (int*));
4414   for (s0=0; s0<S0->nseq; s0++)
4415     {
4416       int l=S0->len[s0];
4417       index[s0]=vcalloc (l+1, sizeof (int));
4418       i=index[s0][0]=name_is_in_list (S0->name[s0], Sx->name, Sx->nseq, 100);
4419       if (i==-1);
4420       else if (strm (S0->seq[s0], Sx->seq[i]))
4421         {
4422           for (r0=1; r0<=l; r0++)
4423             {
4424               index [s0][r0]=r0;
4425             }
4426         }
4427       else
4428         {
4429           int c;
4430           int nr0=0;
4431           int nr1=0;
4432           
4433           Alignment *B=align_two_sequences (S0->seq[s0],Sx->seq[i],(strm(S0->type, "PROTEIN"))?"blosum62mt":"idmat",-4,-1, "myers_miller_pair_wise");
4434           for (c=0; c<B->len_aln; c++)
4435             {
4436               
4437               int g0=is_gap(B->seq_al[0][c]);
4438               int g1=is_gap(B->seq_al[1][c]);
4439               nr0+=1-g0;
4440               nr1+=1-g1;
4441               if (!g0 && !g1)index[s0][nr0]=nr1;
4442             }
4443           if (aln2sim(B, "idmat")<20) add_warning (stderr,"Unreliable reconciliation for sequence %s. If it a PDB, check source file", S0->name[s0]);
4444           free_aln (B);B=NULL;
4445         }
4446     }
4447   return index;
4448 }
4449 int **fix_aln_seq_new (Alignment *A, Sequence *Sx)
4450 {
4451   Sequence *S;
4452   int **f;
4453   
4454   S=aln2seq (A);
4455   f=fix_seq_seq(S, Sx);
4456   free_sequence (S, S->nseq);
4457   return f;
4458 }
4459 Alignment * fix_aln_seq  ( Alignment *A, Sequence *S)
4460         {
4461         int a, b, c;
4462         char *buf1, *buf2;
4463         int g0, g1, nr0, nr1;
4464         int id, tot;
4465         Alignment *B;
4466
4467
4468         /*This function establishes the correspondance between every (1..N+1) residue of each aligned sequence
4469           and its correspondance in S:
4470           A->seq_cache[a][b]=x means that residue b of aligned sequence a corresponds to residue x of the sequence with tye same index in S
4471           A->seq_cache[a][b]=0 means there is no correspondance.
4472           a is the index of the sequence
4473           Applying this function is needed for turning an alignment into a constraint list
4474         */
4475         
4476
4477         if ( S==NULL)return A;
4478         reorder_aln (A, S->name,S->nseq);
4479         if (A->seq_cache)free_int (A->seq_cache, -1);
4480         A->seq_cache=declare_int ( S->nseq, MAX((A->len_aln+1), S->max_len+1));
4481         
4482         for (a=0; a< S->nseq; a++)
4483           for ( b=0; b< A->len_aln; b++)A->seq_cache[a][b]=-1;
4484         
4485         buf1=buf2=NULL;
4486         for ( a=0; a< S->nseq; a++)
4487             {
4488             for (b=0; b< A->nseq; b++) 
4489                 {
4490                 if (strm ( S->name[a], A->name[b]))
4491                    {
4492                    A->order[b][0]=a;
4493                    
4494                    vfree (buf1);
4495                    buf1=vcalloc ( A->len_aln+1, sizeof (char));
4496                    sprintf (buf1, "%s", A->seq_al[b]);
4497                    ungap (buf1);
4498                    upper_string (buf1);
4499                    
4500                    vfree(buf2);
4501                    buf2=vcalloc (strlen(S->seq[a])+1, sizeof (char));
4502                    sprintf (buf2, "%s",S->seq[a]);
4503                    ungap (buf2);
4504                    upper_string (buf2);
4505                    
4506                    
4507
4508                    if ( strm (buf1,buf2))
4509                        {
4510                            
4511                            for ( c=0; c<S->len[a]; c++)A->seq_cache[a][c+1]=c+1;
4512                        }
4513                    else
4514                        {
4515                           
4516                            B=align_two_sequences (buf2,buf1,"blosum62mt",-4,-1, "myers_miller_pair_wise");
4517                            if ( getenv ("DEBUG_RECONCILIATION"))
4518                              {
4519                                fprintf (stderr, "\n[DEBUG_RECONCILIATION:fix_aln_seq]\nReconciliation of %s\nA=Ref_sequence\nB=New_seq", S->name[a]);
4520                                print_aln (B);
4521                              }
4522                            
4523                            for (id=0, tot=0,nr0=0,nr1=0,c=0; c<B->len_aln; c++)
4524                              {
4525                                g0=is_gap(B->seq_al[0][c]);
4526                                g1=is_gap(B->seq_al[1][c]);
4527                                nr0+=1-g0;
4528                                nr1+=1-g1;
4529                                if ( !g0 && !g1)
4530                                  {
4531                                    tot++;
4532                                    id+=(B->seq_al[0][c]==B->seq_al[1][c])?1:0;
4533                                    A->seq_cache[a][nr1]=nr0;
4534                                  }
4535                                else if (g0 && !g1)
4536                                  {
4537                                    A->seq_cache[a][nr1]=0;
4538                                  }
4539                              }
4540                            if ( ((id*100)/tot)<20)
4541                              {
4542                                print_aln (B);
4543                                fprintf ( stderr, "\nTwo different sequences have the same name: %s", S->name[a]);               
4544                                fprintf ( stderr, "\nIf %s is a PDBID, Make sure it identifies the right chain (A, B, 1, 2...)", S->name[a]);
4545                                fprintf ( stderr, "\nChain number or index must be added to the PDB id (i.e. 1gowA)");
4546                                fprintf ( stderr, "\nIf You want to use %s anyway, rename it with a non-PDB identifier such as seq_%s\n",S->name[a],S->name[a]); 
4547                                myexit (EXIT_FAILURE);
4548                              }
4549
4550                            free_sequence ( B->S, -1);
4551                            free_aln (B);
4552                        }
4553                    
4554                    }
4555                 }
4556             }
4557             vfree(buf1);vfree(buf2);
4558             return A;
4559         }
4560
4561 Sequence * add_prf2seq  ( char *file, Sequence *S)
4562     {
4563       char **new_seq;
4564       Sequence *NS;
4565       
4566       if ( !is_aln (file)&& !is_seq (file))return S;
4567       else
4568         {
4569           X_template *R;
4570           Alignment *A;
4571         
4572
4573           R=fill_R_template(file,file, S);
4574         
4575           A=(R->VR)->A;
4576           ((R->VR)->A)->expand=1;
4577           new_seq=declare_char (1,A->len_aln+1);
4578           sprintf ( new_seq[0], "%s",aln2cons_seq_mat(A, "blosum62mt"));
4579           
4580           NS=fill_sequence_struc(1, new_seq,A->file);
4581           S=add_sequence (NS, S, 0);
4582           (S->T[S->nseq-1])->R=R;
4583           
4584           free_sequence (NS, NS->nseq);
4585           free_char( new_seq, -1);
4586           
4587           return S;
4588         }
4589     }
4590 int prf_in_seq ( Sequence *S)
4591 {
4592   int a;
4593   
4594   if ( !S) return 0;
4595   else 
4596     {
4597       for ( a=0; a< S->nseq; a++)
4598         if (seq2R_template_profile(S, a)) return 1;
4599     }
4600   return 0;
4601 }
4602 Sequence * add_sequence ( Sequence *IN, Sequence *OUT, int i)
4603     {
4604       int s, a;
4605    
4606     char *buf;
4607     if (OUT==NULL)
4608       {
4609         
4610         OUT=duplicate_sequence (IN);
4611         return OUT;
4612       }
4613     for (a=0; a<OUT->nseq; a++)
4614       {
4615         Alignment *P;
4616         P=seq2R_template_profile (OUT, a);
4617         if (!P) continue;
4618         else if (name_is_in_list (IN->name[i], P->name, P->nseq, 100)!=-1) return OUT;
4619       }
4620     
4621     /*Adds sequence i of IN at the end of OUT*/
4622     
4623     if ((s=name_is_in_list ( IN->name[i], OUT->name, OUT->nseq,STRING))==-1 )
4624        {
4625          OUT=realloc_sequence (OUT, OUT->nseq+1, IN->len[i]);    
4626          sprintf ( OUT->name[OUT->nseq],"%s",IN->name[i]);
4627          sprintf ( OUT->file[OUT->nseq],"%s",IN->file[i]);
4628          sprintf ( OUT->seq_comment[OUT->nseq],"%s",IN->seq_comment[i]);
4629          sprintf ( OUT->aln_comment[OUT->nseq],"%s",IN->aln_comment[i]);
4630          
4631          sprintf ( OUT->seq[OUT->nseq],"%s",IN->seq[i]);
4632          OUT->len[OUT->nseq]=IN->len[i];
4633          OUT->T[OUT->nseq][0]=IN->T[i][0];
4634          OUT->nseq++;
4635          return OUT;
4636        }
4637     else if ( s!=-1 && !case_insensitive_strcmp ( IN->seq[i], OUT->seq[s]))
4638        {
4639
4640          if ( getenv4debug("DEBUG_RECONCILIATION"))fprintf ( stderr,"[DEBUG_RECONCILIATION:add_sequence]\n%s\n%s\n", IN->seq[i], OUT->seq[s]);
4641          
4642          add_warning (stderr, "DISCREPANCY:%s in [%s] and  [%s]\n", IN->name[i], IN->file[i], OUT->file[s]);
4643          
4644          
4645        if (((buf=build_consensus(IN->seq[i], OUT->seq[s],"cfasta_pair_wise" ))!=NULL)||((buf=build_consensus(IN->seq[i], OUT->seq[s],"myers_miller_pair_wise" ))!=NULL))
4646            {
4647             
4648              OUT->max_len=MAX(OUT->max_len, strlen(buf));
4649              OUT->min_len=MIN(OUT->min_len, strlen(buf));
4650              OUT->seq    =realloc_char ( OUT->seq, -1, -1,OUT->nseq,OUT->max_len+1);
4651              
4652              sprintf ( OUT->seq[s],"%s",buf);
4653              OUT->len[s]=strlen (buf);
4654              vfree (buf);
4655              return OUT;
4656            }
4657        else
4658          {
4659            fprintf ( stderr, "IMPOSSIBLE TO RECONCILIATE SOME SEQUENCES[FATAL:%s]\n", PROGRAM);
4660            print_aln ( align_two_sequences (IN->seq[i], OUT->seq[s], "idmat", 0, 0, "fasta_pair_wise"));
4661            myexit (EXIT_FAILURE);
4662            return NULL;
4663          }
4664        
4665        }
4666     else
4667        {
4668        return OUT;
4669        }
4670     }
4671                            
4672
4673 Sequence  * trim_seq       ( Sequence  *A, Sequence  *B)
4674         {
4675         int a;
4676         Sequence *R;
4677         
4678         if (A->nseq>B->nseq)
4679           {
4680             Sequence *I;
4681             I=A;A=B;B=I;
4682           }
4683
4684         R=declare_sequence (MIN(A->min_len,B->min_len), MAX(A->max_len, B->max_len), MIN(A->nseq, B->nseq));
4685         R->nseq=0;
4686         
4687         for (a=0; a< A->nseq; a++)
4688             {  
4689             if ( name_is_in_list ( A->name[a], B->name, B->nseq,STRING+1)!=-1)
4690                 {
4691                   sprintf ( R->name[R->nseq], "%s", A->name[a]);
4692                   sprintf ( R->seq[R->nseq], "%s", A->seq[a]);
4693                   sprintf ( R->file[R->nseq], "%s", A->file[a]);
4694                   sprintf ( R->aln_comment[R->nseq], "%s", A->aln_comment[a]);
4695                   sprintf ( R->seq_comment[R->nseq], "%s", A->seq_comment[a]);
4696                   
4697                   R->len[R->nseq]=A->len[a];
4698                   R->nseq++;
4699                 }
4700             }
4701         return R;
4702         }
4703
4704 Sequence * trim_aln_seq ( Alignment *A, Alignment *B)
4705         {
4706         int a;
4707         static char **name_list;
4708         int n=0;
4709         Sequence *SA, *SB;
4710         int **cache_A=NULL;
4711         int **cache_B=NULL;
4712         int * p;
4713
4714         /*This function inputs two alignments A and B
4715           It removes sequences that are not common to both of them
4716           It rearange the sequences so that they are in the same order
4717           A decides on the order
4718           The Sequences (A->S) and (B->S) are treated the same way
4719           Sequences are also merged in order to detects discrepencies.
4720           A pointer to S is returned
4721         */
4722         if (name_list)free_char (name_list, -1);
4723         name_list=declare_char (MAX(A->nseq, B->nseq), STRING+1);
4724         
4725         for ( a=0; a< A->nseq; a++)
4726             {  
4727             if ( name_is_in_list ( A->name[a], B->name, B->nseq,STRING)!=-1)
4728                 {
4729                 sprintf ( name_list[n++], "%s", A->name[a]);
4730                 }
4731             }
4732         
4733         
4734         
4735         reorder_aln ( A, name_list, n);
4736         if (A->seq_cache)cache_A=duplicate_int (A->seq_cache, -1, -1);
4737         if (B->seq_cache)cache_B=duplicate_int (B->seq_cache, -1, -1);
4738         reorder_aln ( B, name_list, n);
4739         for ( a=0; a< n; a++)
4740           {
4741             if ( cache_A)
4742               {
4743                 p=A->seq_cache[A->order[a][0]];
4744                 A->seq_cache[A->order[a][0]]=cache_A[a];
4745                 cache_A[a]=p;
4746               }
4747            if ( cache_B)
4748               {
4749                 p=B->seq_cache[B->order[a][0]];
4750                 B->seq_cache[B->order[a][0]]=cache_B[a];
4751                 cache_B[a]=p;
4752               } 
4753            A->order[a][0]=B->order[a][0]=a;
4754           }
4755         free_int(A->seq_cache, -1);
4756         free_int(B->seq_cache, -1);
4757
4758         A->seq_cache=cache_A;
4759         B->seq_cache=cache_B;
4760           
4761
4762         
4763         SA=aln2seq(A);
4764         SB=aln2seq(B);
4765         
4766         A->S=B->S=merge_seq (SA, SB);
4767         return A->S;
4768         }
4769 Sequence * trim_aln_seq_name ( Alignment *A, Alignment *B)
4770         {
4771         int a;
4772         Sequence *S;
4773         
4774         /*This function inputs two alignments A and B
4775           It removes sequences that are not common to both of them
4776           It rearange the sequences so that they are in the same order
4777           A decides on the order
4778         */
4779         S=declare_sequence ( 1, 1, A->nseq+B->nseq);
4780         S->nseq=0;
4781         for ( a=0; a< A->nseq; a++)
4782             {  
4783             if ( name_is_in_list ( A->name[a], B->name, B->nseq,STRING)!=-1)
4784                 {
4785                 sprintf ( S->name[S->nseq++], "%s", A->name[a]);
4786                 }
4787             }
4788         return S;
4789         }
4790
4791
4792
4793 char ** rm_name_tag (char **name, int nseq, char *tag)
4794 {
4795   int a , b, ntag;
4796   char **tag_list;
4797   char *s;
4798   char **template_list; 
4799   if ( !name )return NULL;
4800
4801   tag_list=declare_char (10, 4);
4802
4803   if ( tag)
4804     {
4805       ntag=1; sprintf ( tag_list[0], "%s", tag);
4806     }
4807   else
4808     {
4809       ntag=0;
4810       sprintf ( tag_list[ntag++], "_S_");
4811       sprintf ( tag_list[ntag++], "_G_");
4812     }
4813   template_list=declare_char (nseq, 100);
4814   for ( a=0; a<nseq ; a++)
4815     {
4816       for ( b=0; b<ntag; b++)
4817         {
4818         s=strstr(name[a], tag_list[b]);
4819         if ( s)
4820           {
4821             s[0]='\0';
4822             s[2]='\0';
4823             sprintf ( template_list[a], ">%s _%s_ %s", name[a], s+1, s+3);
4824             break;
4825           }
4826         }
4827     }
4828                 
4829   free_char (tag_list, -1);     
4830   return template_list;
4831 }
4832 Sequence * swap_header ( Sequence *S, Sequence *H)
4833 {
4834   int a, b, n;
4835
4836   for ( a=0; a< S->nseq; a++)
4837     {
4838       if ( (n=name_is_in_list (S->name[a],H->name, H->nseq, 1000))!=-1)
4839            {
4840              char **list;
4841
4842              
4843              list=string2list (H->seq_comment[n]);
4844              if ( list==NULL || atoi(list[0])==1)continue;
4845              S->seq_comment[a]='\0';
4846              sprintf (S->name[a], "%s%s%s",H->name[n], list[1], list[2]);
4847              vfree ( S->seq_comment[a]);S->seq_comment[a]=vcalloc ( strlen (H->seq_comment[n])+1, sizeof (char));
4848              for (b=3; b< atoi(list[0]); b++)S->seq_comment[a]=strcat (S->seq_comment[a], list[b]);
4849              free_char (list, -1);
4850            }
4851     }
4852   return S;
4853 }
4854
4855
4856 Sequence * profile_seq2template_seq ( Sequence *S, char *template_file, Fname *F)
4857 {
4858   /*This function fetches potential templates associated with sequences within a profile*/
4859   int i;
4860   Alignment *A;
4861  
4862   for ( i=0; i< S->nseq; i++)
4863     {
4864
4865       if ( (A=seq2R_template_profile (S, i)))
4866         {
4867           
4868           A->S=aln2seq (A);
4869           A->S=seq2template_seq (A->S, template_file, F);         
4870           if (!A->S)return NULL;
4871         }
4872     }
4873
4874   return S;
4875 }
4876       
4877 Sequence * seq2template_type(Sequence *Seq)
4878 {
4879   //add template
4880   int a, e;
4881   int s;
4882   struct X_template *S=NULL;
4883   struct X_template *P=NULL;
4884   struct X_template *R=NULL;
4885   struct X_template *G=NULL;
4886   struct X_template *F=NULL;
4887   struct X_template *T=NULL;
4888   struct X_template *E=NULL;
4889   struct X_template *U=NULL;
4890   Alignment *A;
4891
4892
4893   e=' ';
4894   for (a=0; a< Seq->nseq; a++)
4895     {
4896       if (!Seq->T[a])continue;
4897       //HERE ADD a Template
4898       P=seq_has_template (Seq, a, "_P_");
4899       S=seq_has_template (Seq, a, "_S_");
4900       R=seq_has_template (Seq, a, "_R_");
4901       G=seq_has_template (Seq, a, "_G_");
4902       F=seq_has_template (Seq, a, "_F_");
4903       T=seq_has_template (Seq, a, "_T_");
4904       E=seq_has_template (Seq, a, "_E_");
4905       U=seq_has_template (Seq, a, "_U_");
4906       
4907       s=(!P)?1:0;
4908       sprintf ( (Seq->T[a])->seq_type, "%c%c%c%c%c%c%c%c", (P)?'P':e, (S)?'S':e, (S &&!P)?'s':e,(R)?'R':e, (G)?'G':e,(T)?'T':e,(E)?'E':e,(U)?'U':e);
4909       
4910       if (R && (A=seq2R_template_profile (Seq,a)) && A->S)
4911         {
4912         
4913           A->S=seq2template_type ( A->S);
4914         }         
4915     }
4916   return Seq;
4917 }
4918
4919 char * string_contains_template_tag (char *string_in)
4920 {
4921   char string[100];
4922   
4923   if ( strstr (string, "_P_"))return "_P_";
4924   if ( strstr (string, "_S_"))return "_S_";
4925   if ( strstr (string, "_R_"))return "_R_";
4926   if ( strstr (string, "_G_"))return "_G_";
4927   if ( strstr (string, "_F_"))return "_F_";
4928   if ( strstr (string, "_T_"))return "_T_";
4929   if ( strstr (string, "_E_"))return "_E_";
4930   if ( strstr (string, "_U_"))return "_U_";
4931   
4932   return NULL;
4933 }
4934 static int check_blast_is_installed (char *server);
4935
4936
4937  
4938 static int check_blast_is_installed (char *server)
4939 {
4940   if (strm (server, "EBI"));
4941   else if ( strm (server, "NCBI"))
4942     return check_program_is_installed (NCBIWEBBLAST_4_TCOFFEE,NULL, NULL,NCBIWEBBLAST_ADDRESS, INSTALL_OR_DIE);
4943   else if ( strm (server, "LOCAL"))
4944     return check_program_is_installed (NCBIBLAST_4_TCOFFEE,NULL, NULL,NCBIBLAST_ADDRESS, INSTALL_OR_DIE);
4945   return 1;
4946 }
4947
4948
4949 Sequence * vremove_seq_template_files(Sequence *S)
4950 {
4951     return handle_seq_template_file (S, "remove");
4952 }
4953 Sequence * display_seq_template_files(Sequence *S)
4954 {
4955   return handle_seq_template_file (S, "display");
4956 }
4957 Sequence * handle_seq_template_file (Sequence *S, char *mode)
4958 {
4959   int a;
4960   Template *T;
4961   
4962   for (a=0; a< S->nseq; a++)
4963     {
4964       T=S->T[a];
4965       if (T)
4966         {
4967           handle_X_template_files (T->P, mode);
4968           handle_X_template_files (T->F, mode);
4969           handle_X_template_files (T->R, mode);
4970           handle_X_template_files (T->T, mode);
4971           handle_X_template_files (T->E, mode);
4972         }
4973     }
4974                
4975   return S;
4976 }
4977 int handle_X_template_files ( X_template *T, char *mode)
4978   {
4979     if (!T)return 0;
4980     
4981     if ( strm (mode, "remove"))
4982       {
4983         vremove (T->template_file);
4984         vremove (T->template_name);
4985       }
4986     else if (strm (mode, "display"))
4987       {
4988         char buf[100];
4989         sprintf ( buf, "Template %s",  template_type2type_name (T->template_type));
4990         if (check_file_exists (T->template_name))display_output_filename ( stdout,buf,T->template_format,T->template_name, STORE); 
4991       }
4992     else
4993       {
4994         printf_exit (EXIT_FAILURE, stderr, "\nUnkonwn mode %s for template handling [FATAL:%s]", mode, PROGRAM);
4995       }
4996     return 1;
4997   }
4998 Sequence * seq2template_seq ( Sequence *S, char *template_list, Fname *F)
4999 {
5000   /*Expected format for the template file:
5001     >seq_name _X_ Target_template
5002     X: S for Structures 
5003     G for genomes (Exoset)
5004     When alternative templates are given for a sequence, the first one superseeds all the others
5005   */
5006   
5007   /*Fill the sequences*/
5008   /*1: No template*/
5009   char buf[1000];
5010   
5011   int PmC,PmI,PMI;
5012   int BmC,BmI,BMI;
5013   char *server;
5014   char *pdb_db,*prot_db;
5015   char pdb_type[100];
5016   char *p;
5017   int remove_template_file=0;
5018   
5019   
5020   remove_template_file=get_int_variable ("remove_template_file");
5021   server=get_string_variable ("blast_server");
5022   pdb_db=get_string_variable ("pdb_db");
5023   prot_db=get_string_variable ("prot_db");
5024   
5025   PmI=get_int_variable ("pdb_min_sim");
5026   PMI=get_int_variable ("pdb_max_sim");
5027   PmC=get_int_variable ("pdb_min_cov");
5028
5029   BmI=get_int_variable ("prot_min_sim");
5030   BMI=get_int_variable ("prot_max_sim");
5031   BmC=get_int_variable ("prot_min_cov");
5032   
5033   //Set the type of the PDB structure
5034   if ((p=get_string_variable ("pdb_type")))
5035     {
5036       sprintf ( pdb_type, "%s",p);
5037     }
5038   else
5039     {
5040       sprintf (pdb_type, "dmn");
5041     }
5042   
5043   if ( (template_list && template_list[0]=='\0') || strm ( template_list, "no_template")) 
5044     {
5045       return S;
5046     }
5047   else if ( strstr (template_list, "MODE_"))//pre_set mode
5048     {
5049       return seq2template_seq ( S,template_list+strlen ("MODE_"),F);
5050     }
5051   else if ( strm ( template_list, "SSP")|| strm ( template_list, "GOR"))
5052     {
5053       
5054       /*use GOR to Predict the secondary structure*/
5055       check_program_is_installed (GOR4_4_TCOFFEE,NULL, NULL,GOR4_ADDRESS, INSTALL_OR_DIE);
5056       sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#ssp_template@seq#%s/%s@obs#%s/%s@cache#%s@type#_E_",get_mcoffee_4_tcoffee(), "New_KS.267.seq", get_mcoffee_4_tcoffee(), "New_KS.267.obs", get_cache_dir());
5057       S=seq2template_seq (S,buf, F);
5058       return S;
5059     }
5060   else if ( strm ( template_list, "PSISSP") || strm (template_list, "PSIGOR"))
5061     {
5062       
5063       /*Computes a GOR consensus on a psi-blast output*/
5064       check_program_is_installed (GOR4_4_TCOFFEE,NULL, NULL,GOR4_ADDRESS, INSTALL_OR_DIE);
5065       check_blast_is_installed(server);
5066       
5067       sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#psissp_template@seq#%s/%s@obs#%s/%s@cache#%s@minid#%d@maxid#%d@mincov#%d@server#%s@type#_E_",get_mcoffee_4_tcoffee(), "New_KS.267.seq", get_mcoffee_4_tcoffee(), "New_KS.267.obs", get_cache_dir(), BmI,BMI,BmC,server);
5068       S=seq2template_seq (S,buf, F);
5069       return S;
5070     }
5071   else if ( strm ( template_list, "TM"))
5072     {
5073       
5074       /*predict transmembrane structure*/
5075       check_program_is_installed (HMMTOP_4_TCOFFEE,NULL, NULL,HMMTOP_ADDRESS, INSTALL_OR_DIE);
5076       sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#tm_template@arch#%s/%s@psv#%s/%s@type#_T_",get_mcoffee_4_tcoffee(), "hmmtop.arch", get_mcoffee_4_tcoffee(), "hmmtop.psv");
5077       S=seq2template_seq (S,buf, F);
5078       return S;
5079     }
5080   else if ( strm ( template_list, "PSITM"))
5081     {
5082       
5083       /*predict transmembrane structure*/
5084       check_program_is_installed (HMMTOP_4_TCOFFEE,NULL, NULL,HMMTOP_ADDRESS, INSTALL_OR_DIE);
5085       check_blast_is_installed(server);
5086       
5087       sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#psitm_template@database#%s@arch#%s/%s@psv#%s/%s@cache#%s@minid#%d@maxid#%d@mincov#%d@server#%s@type#_T_", prot_db, get_mcoffee_4_tcoffee(), "hmmtop.arch", get_mcoffee_4_tcoffee(), "hmmtop.psv",get_cache_dir(), BmI,BMI,BmC,server);
5088       S=seq2template_seq (S,buf, F);
5089       return S;
5090     }
5091   
5092   else if (strm ( template_list, "PSIBLAST"))
5093     {
5094      
5095       check_blast_is_installed(server);
5096       sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#psiprofile_template@database#%s@method#psiblast@cache#%s@minid#%d@maxid#%d@mincov#%d@server#%s@type#_R_", prot_db,get_cache_dir(),BmI,BMI,BmC,server);
5097       S=seq2template_seq (S,buf, F);
5098       
5099       return S;
5100     }
5101   else if (strm ( template_list, "BLAST") )
5102     {
5103       check_blast_is_installed(server);
5104       sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#profile_template@database#%s@method#blastp@cache#%s@minid#%d@maxid#%d@mincov#%d@server#%s@type#_R_", prot_db,get_cache_dir(),BmI,BMI,BmC,server);
5105       S=seq2template_seq (S,buf, F);
5106       
5107       return S;
5108     }
5109   else if ( strm ( template_list, "EXPRESSO") || strm (template_list, "PDB"))
5110     {
5111       check_blast_is_installed(server);
5112       
5113       int isRNA = 0;
5114       int i;
5115       for (i= 0; i < S->len[0]; ++i)
5116         {
5117            isRNA =  (isRNA || is_rna(S->seq[0][i]));
5118         }
5119       
5120       if (isRNA)
5121         {
5122           sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#pdb_template@database#%s@method#blastn@cache#%s@minid#%d@maxid#%d@mincov#%d@server#%s@type#_P_@pdb_type#%s",pdb_db, get_cache_dir(),PmI,PMI,PmC, server,pdb_type);
5123         }
5124       else
5125         {
5126           sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#pdb_template@database#%s@method#blastp@cache#%s@minid#%d@maxid#%d@mincov#%d@server#%s@type#_P_@pdb_type#%s",pdb_db, get_cache_dir(),PmI,PMI,PmC, server,pdb_type);
5127         }
5128       return seq2template_seq (S,buf, F);
5129     }
5130   
5131   else if ( strm (template_list, "RCOFFEE") || strm (template_list, "RNA"))
5132     {
5133       char *file_struc_clac = vtmpnam (NULL);
5134       FILE* struc_calc_f =vfopen(file_struc_clac,"w");
5135       int i;
5136       int j=0;
5137       for (i = 0; i< S->nseq; ++i)
5138         {
5139           if (S->T[i]->P)
5140             {
5141               ++j;
5142               fprintf(struc_calc_f,"%s %s\n",S->name[i],S->T[i]->P->template_file); 
5143             }
5144         }
5145         vfclose(struc_calc_f);
5146        if (j == S->nseq)
5147           {
5148 //                S = seq2template_seq (S,buf,F);
5149                   sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#calc_rna_template@pdbfile#%s@cache#%s@type#_F_", file_struc_clac,get_cache_dir());
5150           }
5151           else
5152           {
5153                 check_program_is_installed (RNAPLFOLD_4_TCOFFEE,NULL, NULL,RNAPLFOLD_ADDRESS, IS_FATAL);
5154                 sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#RNA_template@type#_F_");
5155                 if (j > 0)
5156                 {
5157                         S = seq2template_seq (S,buf,F);
5158                         sprintf ( buf, "SCRIPT_tc_generic_method.pl@mode#calc_rna_template@pdbfile#%s@cache#%s@type#_F_", file_struc_clac,get_cache_dir());
5159                 }
5160           }
5161 //        printf("IN T_\n");
5162       return seq2template_seq (S,buf,F);
5163     }
5164      
5165   
5166   /*2: Templates from seqnames (SELF) or named like the sequences (SEQFILE)*/
5167   else if ( strstr (template_list, "SELF_") ||strstr (template_list, "SEQFILE_") )
5168     {
5169       int a;
5170       char *p;
5171
5172       //add template
5173       for (a=0; a< S->nseq; a++)
5174         {
5175           
5176           if ( (p=strstr (template_list,"SELF_")))p=S->name[a];
5177           else if ( strstr (template_list, "SEQFILE_"))p=template_list;
5178           else 
5179             {
5180               fprintf ( stderr, "\nUnkown mode for Template [FATAL:%s]\n", PROGRAM);
5181               myexit (EXIT_FAILURE);
5182             }
5183           
5184           if (      strstr (template_list, "_P_") && !(S->T[a])->P)(S->T[a])->P  =fill_P_template  ( S->name[a], p,S);//PDB
5185           else if ( strstr (template_list, "_S_") && !(S->T[a])->S)(S->T[a])->S  =fill_S_template  ( S->name[a], p,S);//Sequence          
5186           else if ( strstr (template_list, "_R_" )&& !(S->T[a])->R)(S->T[a])->R  =fill_R_template  ( S->name[a], p,S);//pRofile
5187           else if ( strstr (template_list, "_G_" )&& !(S->T[a])->G)(S->T[a])->G  =fill_G_template  ( S->name[a], p,S);//Genomic
5188           else if ( strstr (template_list, "_F_" )&& !(S->T[a])->F)(S->T[a])->F  =fill_F_template  ( S->name[a], p,S);//Fold 
5189           else if ( strstr (template_list, "_T_" )&& !(S->T[a])->T)(S->T[a])->T  =fill_T_template  ( S->name[a], p,S);//Trans Membrane
5190           else if ( strstr (template_list, "_E_" )&& !(S->T[a])->E)(S->T[a])->E  =fill_E_template  ( S->name[a], p,S);//Secondary Structure
5191           else if ( strstr (template_list, "_U_" )&& !(S->T[a])->U)(S->T[a])->U  =fill_U_template  ( S->name[a], p,S);//unicode, list template
5192           
5193         }
5194       return S;
5195     }
5196
5197   /*2: Templates comes in a template_file*/
5198   else if ( template_list==NULL || format_is_fasta (template_list))
5199     {
5200       Sequence *T;
5201       int a, i;
5202       int ntemp=0;
5203       T=(template_list!=NULL)?get_fasta_sequence (template_list, NULL):S;
5204       for (a=0; a< T->nseq; a++)
5205         {
5206           
5207           char *p;
5208           if ((i=name_is_in_list(T->name[a], S->name, S->nseq, MAXNAMES))!=-1)
5209             {
5210              
5211               if (       (p=strstr (T->seq_comment[a], " _P_ ")) && !(S->T[i])->P &&( (S->T[i])->P=fill_P_template (S->name[i],p,S)))ntemp++;
5212               else if (  (p=strstr (T->seq_comment[a], " _F_ ")) && !(S->T[i])->F &&( (S->T[i])->F=fill_F_template (S->name[i],p,S)))ntemp++;
5213               else if (  (p=strstr (T->seq_comment[a], " _S_ ")) && !(S->T[i])->S &&( (S->T[i])->S=fill_S_template (S->name[i],p,S)))ntemp++;
5214
5215               else if (  (p=strstr (T->seq_comment[a], " _R_ ")) && !(S->T[i])->R &&( (S->T[i])->R=fill_R_template (S->name[i],p,S)))ntemp++;
5216               else if (  (p=strstr (T->seq_comment[a], " _G_ ")) && !(S->T[i])->G &&( (S->T[i])->G=fill_G_template (S->name[i],p,S)))ntemp++;
5217               else if (  (p=strstr (T->seq_comment[a], " _T_ ")) && !(S->T[i])->T &&( (S->T[i])->T=fill_T_template (S->name[i],p,S)))ntemp++;
5218               else if (  (p=strstr (T->seq_comment[a], " _E_ ")) && !(S->T[i])->E &&( (S->T[i])->E=fill_E_template (S->name[i],p,S)))ntemp++;
5219               else if (  (p=strstr (T->seq_comment[a], " _U_ ")) && !(S->T[i])->U &&( (S->T[i])->E=fill_U_template (S->name[i],p,S)))ntemp++;
5220
5221               if (T!=S)strcat (S->seq_comment[i], T->seq_comment[a]);
5222              
5223             }
5224         }
5225       
5226       if (T!=S)free_sequence (T, -1);
5227       
5228       if ( remove_template_file==2)
5229         {
5230           vremove (template_list);
5231         }
5232       else 
5233         if (template_list)display_output_filename ( stdout, "Template_List","fasta_seq", template_list, STORE); 
5234       return S;
5235     }
5236   
5237   /*3 Templates are generated with a script*/
5238   else if (strstr (template_list, "SCRIPT_") && get_string_variable ("multi_core") && strstr (get_string_variable ("multi_core"), "templates") && get_nproc()>1)
5239     {
5240       char *tmp1,*command;
5241       Alignment *A;
5242       char **temp_file,**seq_file;
5243       int  * pid_list, pid, npid, submited;
5244       int nproc, max_nproc;
5245       int num=0;
5246
5247       char outfile[1000];
5248       static char *script;
5249       static int ntemp;
5250       char *p;
5251       int z, i;
5252       int freeF=0;
5253       
5254       if (!script)script=vcalloc ( 1000, sizeof(char));
5255       
5256       ntemp++;
5257       
5258       command=vcalloc ( 1000, sizeof (char));
5259       tmp1=vtmpnam (NULL); 
5260       
5261       A=seq2aln (S,NULL, 0);
5262       string_array_upper(A->seq_al, A->nseq);
5263       output_fasta_seq (tmp1, A);
5264       sprintf ( script, "%s", after_strstr (template_list, "SCRIPT_"));
5265       
5266       if ((p=strstr (template_list, "@type#")))
5267         p+=strlen ("@type#");
5268       
5269       if (!F){F=parse_fname (S->file[0]);freeF=1;}
5270       sprintf (outfile, "%s%s_%s%d.template_list", F->path,F->name,template_type2short_type_name(p),ntemp);
5271       while ( check_file_exists (outfile))
5272         {
5273           sprintf (outfile, "%s%s_%s%d.%d.template_list",F->path, F->name,template_type2short_type_name(p),ntemp, ++num);
5274         }
5275       if (freeF)free_fname(F);
5276       
5277       nproc=get_nproc();
5278       //max_nproc=2*nproc;
5279       max_nproc=20; //EBI recommended maximum            
5280       script=substitute(script, "@", " -");
5281       script=substitute(script, "#", "=");
5282            
5283       temp_file=vcalloc ( A->nseq, sizeof (char*));
5284       seq_file =vcalloc (A->nseq, sizeof (char*)); 
5285       pid_list =vcalloc (MAX_N_PID, sizeof (int *));
5286       
5287       fprintf ( stderr, "\n\t------ Fetch Templates [Multi Core Mode %d CPUs]\n",get_nproc());
5288       for (npid=0, submited=0,i=0; i<S->nseq; i++)
5289         {
5290           FILE *fp2;
5291           seq_file[i]=vtmpnam (NULL);
5292           temp_file[i]=vtmpnam (NULL);
5293           fp2=vfopen (seq_file[i], "w");
5294           fprintf ( fp2, ">%s\n%s\n", S->name[i], S->seq[i]);
5295           vfclose (fp2);
5296                   
5297           pid=vvfork(NULL);
5298           if (pid==0)
5299             {
5300               initiate_vtmpnam (NULL);
5301               if  ( strstr (script, "tc_generic_method"))
5302                 {
5303                   //sprintf ( command, "%s -other_pg %s -infile=%s -outfile=%s -tmpdir=%s",get_string_variable ("t_coffee"),script,seq_file[i],temp_file[i],get_tmp_4_tcoffee());
5304                   sprintf ( command, "%s -infile=%s -outfile=%s -tmpdir=%s",script,seq_file[i],temp_file[i],get_tmp_4_tcoffee());
5305                 }
5306               else 
5307                 //sprintf ( command, "%s -other_pg %s -infile=%s -outfile=%s",get_string_variable("t_coffee"),script,seq_file[i],temp_file[i]);
5308                 sprintf ( command, "%s -infile=%s -outfile=%s",script,seq_file[i],temp_file[i]);
5309               command=substitute(command, "@", " ");
5310               //my_system ( command);
5311               myexit (my_system(command));
5312             }
5313           else
5314             {
5315               pid_list[pid]=npid;
5316               //set_pid(pid);
5317               npid++;
5318               submited++;
5319               submited=vwait_npid(submited,max_nproc,nproc);
5320             }
5321         }
5322       
5323       submited=vwait_npid(submited,0,0);
5324       //Concatenate all the files
5325       vremove (outfile);
5326       for (i=0; i<npid; i++)  file_cat (temp_file[i],outfile);
5327       
5328       //Free the process table
5329       vfree (temp_file);
5330       vfree (pid_list);
5331       vfree (seq_file);
5332       
5333       free_aln (A);
5334       if ( check_file_exists (outfile) && format_is_fasta(outfile))
5335         {
5336           S=seq2template_seq (S, outfile, F);
5337         }
5338       else if (strstr (command, "webblast.pl"))return S; 
5339       else 
5340         {
5341           
5342           add_warning (stderr, "Could not Run %s to find templates[%s](Forked mode)\n",command, PROGRAM);
5343           return NULL;
5344         }
5345   
5346       vfree (command);
5347       return S;
5348     }
5349   
5350   else if (strstr (template_list, "SCRIPT_"))
5351     {
5352           char x[299];
5353       char *tmp1,*command;
5354       Alignment *A;
5355       char outfile[1000];
5356       static char *script;
5357       static int ntemp;
5358       char *p;
5359       int z;
5360       if (!script)script=vcalloc ( 1000, sizeof(char));
5361       
5362       ntemp++;
5363       
5364       command=vcalloc ( 1000, sizeof (char));
5365       tmp1=vtmpnam (NULL); 
5366       
5367       A=seq2aln (S,NULL, 0);
5368       string_array_upper(A->seq_al, A->nseq);
5369       output_fasta_seq (tmp1, A);
5370       sprintf ( script, "%s", after_strstr (template_list, "SCRIPT_"));
5371       fprintf ( stderr, "\n");
5372       if ((p=strstr (template_list, "@type#")))
5373         p+=strlen ("@type#");
5374       if (F)
5375         {
5376           sprintf (outfile, "%s%s_%s%d.template_list", F->path,F->name,template_type2short_type_name(p),ntemp);
5377         }
5378       else
5379         {
5380           F=parse_fname (S->file[0]);
5381           sprintf (outfile, "%s%s_%s%d.template_list",F->path, F->name,template_type2short_type_name(p),ntemp);
5382           free_fname (F);
5383         }
5384       
5385       script=substitute(script, "@", " -");
5386       script=substitute(script, "#", "=");
5387       
5388       if  ( strstr (script, "tc_generic_method"))
5389         {
5390           sprintf ( command, "%s -other_pg %s -infile=%s -outfile=%s -tmpdir=%s",get_string_variable ("t_coffee"),script, tmp1,outfile,get_tmp_4_tcoffee());
5391         }
5392       else sprintf ( command, "%s -other_pg %s -infile=%s -outfile=%s",get_string_variable("t_coffee"),script, tmp1, outfile);
5393       
5394       vremove (outfile);
5395       command=substitute(command, "@", " ");
5396       
5397       my_system ( command);
5398     
5399       free_aln (A);
5400       
5401       if ( check_file_exists (outfile) && format_is_fasta(outfile))
5402         {
5403           S=seq2template_seq (S, outfile, F);
5404         }
5405       else if (strstr (command, "webblast.pl"))return S; 
5406       else 
5407         {
5408           
5409           add_warning (stderr, "Could not Run %s to find templates[%s](unforked mode)\n",command, PROGRAM);
5410           return NULL;
5411         }
5412       
5413       vfree (command);
5414       return S;
5415     }
5416   
5417   return S;
5418 }
5419
5420 char* seq2template_file (Sequence *S, char *file)
5421 {
5422   Alignment *A;
5423   int i;
5424   if (!S)return file;
5425   if (file==NULL)file=vtmpnam (NULL);
5426   
5427   seq2template_file2 (S, file, "w");
5428   
5429   for (i=0; i<S->nseq; i++)
5430     {
5431       if ( (A=seq2R_template_profile (S, i)))
5432         {
5433           Sequence *S;
5434           S=A->S;
5435           if (S)seq2template_file2 (A->S, file, "a");
5436         }
5437     }
5438   return file;
5439 }
5440   
5441 int seq2template_file2 (Sequence *S, char *file, char *mode)
5442 {
5443   FILE *fp;
5444   int i;
5445   char buf1[10000];
5446   char buf2[10000];
5447   struct X_template *X;
5448   
5449   fp=vfopen ( file, mode);
5450   for ( i=0; i< S-> nseq; i++)
5451     {
5452       buf1[0]=0;
5453       if ( S->T)
5454         {
5455           if (S->T[i])
5456             {
5457               if ( (X=(S->T[i])->P)){sprintf (buf2, " %s %s ", X->template_type, X->template_file);strcat (buf1, buf2);}
5458               /*if ( (X=(S->T[i])->S)){sprintf (buf2, " %s %s ", X->template_type, X->template_file);strcat (buf1, buf2);}*/
5459               if ( (X=(S->T[i])->R)){sprintf (buf2, " %s %s ", X->template_type, X->template_file);strcat (buf1, buf2);}
5460               if ( (X=(S->T[i])->G)){sprintf (buf2, " %s %s ", X->template_type, X->template_file);strcat (buf1, buf2);}
5461               if (buf1[0])fprintf ( fp, ">%s %s\n", S->name[i], buf1);
5462             }
5463         }
5464     }
5465   vfclose (fp);
5466   return EXIT_SUCCESS;
5467 }
5468            
5469       
5470         
5471         
5472 int seq2n_X_template ( Sequence *S, char *type)
5473 {
5474   int a, n;
5475   
5476   for (n=0,a=0; a< S->nseq; a++)
5477     {
5478       if ( strm2 (type, "_P_","_*_") && (S->T[a])->P)n++;
5479       if ( strm2 (type, "_F_","_*_") && (S->T[a])->F)n++;
5480       if ( strm2 (type, "_S_","_*_") && (S->T[a])->S)n++;
5481       if ( strm2 (type, "_R_","_*_") && (S->T[a])->R)n++;
5482       if ( strm2 (type, "_G_","_*_") && (S->T[a])->G)n++;
5483     }
5484   return n;
5485 }
5486 struct X_template *fill_X_template ( char *name, char *p, char *token)
5487 {
5488   struct X_template *X;
5489
5490
5491
5492
5493   char *k;
5494   
5495   X=vcalloc (1, sizeof (X_template));
5496   sprintf ( X->seq_name, "%s", name);
5497   if ( (k=strstr (p, token)))sscanf (k+strlen(token), "%s",X->template_name);
5498   else sprintf (X->template_name, "%s", p);
5499   
5500    
5501   /*Add a Structure HERE*/
5502   sprintf ( X->template_type, "%s", token);
5503   if ( strm (token, "_P_"))X->VP=vcalloc (1, sizeof (P_template));
5504   if ( strm (token, "_F_"))X->VF=vcalloc (1, sizeof (F_template));
5505   
5506   if ( strm (token, "_S_"))X->VS=vcalloc (1, sizeof (S_template));
5507   if ( strm (token, "_R_"))X->VR=vcalloc (1, sizeof (R_template));
5508   if ( strm (token, "_G_"))X->VG=vcalloc (1, sizeof (G_template));
5509   if ( strm (token, "_T_"))X->VT=vcalloc (1, sizeof (T_template));
5510   if ( strm (token, "_E_"))X->VE=vcalloc (1, sizeof (E_template));
5511   if ( strm (token, "_U_"))X->VU=vcalloc (1, sizeof (U_template));
5512   
5513   return X;
5514 }
5515
5516 struct X_template* free_X_template ( struct X_template *X)
5517 {
5518   if (X->VP)
5519     {
5520       vfree (X->VP);
5521     }
5522   if (X->VF)
5523     {
5524       vfree (X->VF);
5525     }
5526   if ( X->VS)
5527     {
5528       free_sequence ((X->VS)->S, -1);
5529       vfree (X->VS);
5530     }
5531   if ( X->VR)
5532     {
5533       free_aln ((X->VR)->A);
5534       vfree (X->VR);
5535     }
5536   if ( X->VG)
5537     {
5538       free_sequence ((X->VG)->S, -1);
5539       vfree (X->VG);
5540     }
5541   
5542   vfree (X);
5543   return NULL;
5544 }
5545
5546 FILE * display_sequence_templates (Sequence *S,int i, FILE *io)
5547 {
5548   
5549
5550   io=display_X_template ( (S->T[i])->P, io);
5551
5552   io=display_X_template ( (S->T[i])->F, io);
5553
5554   io=display_X_template ( (S->T[i])->S, io);
5555
5556   io=display_X_template ( (S->T[i])->R, io);
5557   io=display_X_template ( (S->T[i])->G, io);
5558   io=display_X_template ( (S->T[i])->T, io);
5559   io=display_X_template ( (S->T[i])->E, io);
5560
5561   return io;
5562 }
5563  
5564 FILE * display_X_template (struct X_template *X, FILE *io)
5565 {
5566   
5567   if ( !X) return io;
5568   if ( !strm (X->template_type, "_S_"))fprintf (io, "\n\t%s: Template=%s, File=%s",template_type2type_name (X->template_type), X->template_name,X->template_file);
5569   return io;
5570 }
5571 char *template_type2short_type_name (char *type)
5572 {
5573   //add_template
5574   if (!type)return "";
5575   else if ( strstr (type, "_P_"))       return "pdb";
5576   else if ( strstr (type, "_F_")) return "rfold";
5577   else if ( strstr (type, "_S_")) return "seq";
5578   else if ( strstr (type, "_R_")) return "prf";
5579   else if ( strstr (type, "_G_")) return "genome";
5580   else if ( strstr (type, "_E_")) return "ssp";
5581   else if ( strstr (type, "_T_")) return "tmp";
5582   else if ( strstr (type, "_U_")) return "unicode";
5583   else return type;
5584 }
5585 char *template_type2type_name (char *type)
5586 {
5587   //add_template
5588   if ( strstr (type, "_P_"))      return "PDB struc";
5589   else if ( strstr (type, "_F_")) return "RNA Fold";
5590   else if ( strstr (type, "_S_")) return "Sequeence";
5591   else if ( strstr (type, "_R_")) return "Profile";
5592   else if ( strstr (type, "_G_")) return "Genomic";
5593   else if ( strstr (type, "_E_")) return "Protein Secondary Structure";
5594   else if ( strstr (type, "_T_")) return "Protein Trans Membrane Structure ";
5595   else if ( strstr (type, "_U_")) return "Unicode and strings";
5596   
5597   else return type;
5598 }
5599 struct X_template *fill_F_template ( char *name,char *p, Sequence *S)
5600 {
5601   /*Profile template*/
5602   struct X_template *F;
5603   
5604   F=fill_X_template ( name, p, "_F_");  
5605   sprintf (F->template_format , "TCOFFEE_LIBRARY");
5606   if (!F || !check_file_exists (F->template_name))
5607     {
5608       fprintf ( stderr, "Could Not Fill _F_ (Fold) template for sequence |%s|", name);
5609       free_X_template (F);
5610       return NULL;
5611     }
5612   else if ( check_file_exists (F->template_name))
5613     {
5614       sprintf ( F->template_file, "%s", F->template_name);
5615     }
5616   
5617   return F;
5618
5619 }
5620  
5621
5622 struct X_template *fill_P_template ( char *name,char *p, Sequence *S)
5623 {
5624   struct X_template *P;
5625   Sequence *PS;
5626   Alignment *A;
5627   int sim, cov, i;
5628   char *buf;
5629   
5630  
5631   P=fill_X_template ( name, p, "_P_");
5632   sprintf (P->template_format , "pdb");
5633   
5634   if (!P ||(check_file_exists (P->template_name) && !is_pdb_file (P->template_name) ))
5635     {
5636       //fprintf ( stderr, "Could Not Fill _P_ template for sequence |%s|", name);
5637       free_X_template (P);
5638       return NULL;
5639     }
5640   else if ( check_file_exists (P->template_name))
5641     {
5642       sprintf ( P->template_file, "%s", P->template_name);
5643       buf=path2filename (P->template_name);
5644       if (P->template_name!=buf)
5645         {
5646           sprintf ( P->template_name, "%s",buf );
5647           vfree (buf);
5648         }
5649     }
5650    else
5651      {
5652        char *st;
5653        
5654        st=is_pdb_struc (P->template_name);
5655        if (st)
5656          {
5657            if (st!=P->template_file)sprintf ( P->template_file, "%s", st);
5658          }
5659      }
5660   
5661   /*Make a first run to fix relaxed PDB files*/
5662   buf=fix_pdb_file (P->template_file);
5663   
5664   if ( buf!=P->template_file)
5665   {
5666     
5667     sprintf ( P->template_file, "%s",buf);
5668     vfree (buf);
5669   }
5670  
5671   /*Check the PDB FILE EXISTS*/
5672   
5673   if (!is_pdb_file (P->template_file))
5674     {
5675
5676       if (p)add_warning(stderr, "_P_ Template | %s | Could Not Be Found\n",p);
5677       else if (name)add_warning(stderr, "_P_ Template | %s | Could Not Be Found\n",name);
5678       free_X_template (P);
5679       return NULL;
5680     }
5681   else
5682     {
5683       buf= get_pdb_id (P->template_file);
5684       if (buf!=(P->VP)->pdb_id)
5685         {
5686           sprintf ((P->VP)->pdb_id, "%s", buf);
5687           vfree (buf);
5688         }
5689     }
5690
5691   /*Check the target sequence is similar enough*/
5692   
5693   PS=get_pdb_sequence (P->template_file);
5694   
5695
5696
5697   if ( PS==NULL)
5698     {
5699       add_warning( stderr, "_P_  Template |%s| Could Not be Used for Sequence |%s|: Structure Not Found", P->template_name, name);
5700       free_X_template (P);P=NULL;
5701     }
5702   else
5703     {
5704       int minsim=get_int_variable ("pdb_min_sim");
5705       int mincov=get_int_variable ("pdb_min_cov");
5706
5707       
5708       i=name_is_in_list (name, S->name, S->nseq, 100);
5709      
5710       A=align_two_sequences (S->seq[i], PS->seq[0],"idmat",-3,0, "fasta_pair_wise");
5711       
5712       sprintf ( A->name[0], "seq");
5713       sprintf ( A->name[1], "pdb");
5714       cov=aln2coverage (A, 0);
5715       sim=aln2sim (A, "idmat");
5716      
5717       if (sim<=minsim)
5718         {
5719           add_information( stderr, "_P_  Template %s Could Not be Used for Sequence %s: Similarity too low [%d, Min=%d]",P->template_name,name,sim,minsim);          
5720           add_information( stderr, "If you want to include %s in anycase,add -pdb_min_sim=%d to the command line",name,sim);
5721           print_aln (A);
5722           free_X_template (P);
5723           P=NULL;
5724         }
5725       else if ( cov<=mincov)
5726         {
5727           add_information(stderr, "_P_  Template |%s| Could Not be Used for Sequence |%s|: Coverage too low [%d, Min=%d]",P->template_name,name, cov, mincov);
5728           add_information( stderr, "If you want to include this sequence in anycase add -pdb_min_cov=%d to the command line", cov);
5729           print_aln (A);
5730           free_X_template (P);P=NULL;
5731         }
5732       free_aln(A);
5733       free_sequence (PS, -1);
5734     }
5735   
5736   return P;
5737 }
5738
5739 struct X_template *fill_S_template ( char *name,char *p, Sequence *Seq)
5740 {
5741   struct X_template *S;
5742   S=fill_X_template ( name, p, "_S_"); 
5743   if ( strm (name, p))sprintf ( S->template_file, "%s",output_fasta_seqX (NULL,"w",Seq,NULL, seq_name2index (name, Seq)));
5744   (S->VS)->S=get_fasta_sequence (S->template_file, NULL);
5745   return S;
5746 }
5747 struct X_template *fill_R_template ( char *name,char *p, Sequence *S)
5748 {
5749   /*Profile template*/
5750   struct X_template *R;
5751   
5752
5753   R=fill_X_template ( name, p, "_R_");
5754   sprintf (R->template_format , "fasta_aln");
5755   
5756   
5757   if (!is_aln(R->template_name) && !is_seq (R->template_name))
5758     {
5759       
5760       add_information ( stderr, "_R_ Template %s Could Not Be Found\n",R->template_name);
5761       free_X_template (R);
5762       return NULL;
5763     }
5764   else
5765     {
5766       int s;
5767       Sequence *S1;
5768       Alignment *A1;
5769       
5770       (R->VR)->A=main_read_aln (R->template_name, NULL);
5771       
5772       if ( !S)
5773         sprintf ( R->template_file, "%s", R->template_name);
5774       else
5775         {
5776           s=name_is_in_list(name, S->name, S->nseq, 100);
5777           if ( s!=-1)
5778             {
5779               S1=fill_sequence_struc (1, &S->seq[s], &S->name[s]);
5780               A1=seq2aln (S1,NULL, RM_GAP);
5781               
5782               (R->VR)->A=trim_aln_with_seq (A1, (R->VR)->A);
5783         
5784               sprintf ( R->template_file, "%s", vtmpnam (NULL));
5785               output_clustal_aln (R->template_file, (R->VR)->A);
5786             }
5787           else
5788             sprintf ( R->template_file, "%s", R->template_name);
5789         }
5790       (R->VR)->A=aln2profile ((R->VR)->A);
5791       
5792       //free_data_in_aln ((R->VR)->A);
5793       
5794     }
5795   return R;
5796 }
5797
5798 struct X_template *fill_T_template ( char *name,char *p, Sequence *S)
5799 {
5800   /*Profile template*/
5801   struct X_template *T;
5802   
5803   T=fill_X_template ( name, p, "_T_");
5804   sprintf (T->template_format , "fasta_seq");
5805   
5806   if (!is_aln(T->template_name) && !is_seq (T->template_name))
5807     {
5808       
5809       add_information ( stderr, "_T_ Template %s Could Not Be Found\n",T->template_name);
5810       free_X_template (T);
5811       return NULL;
5812     }
5813   else
5814     {
5815   
5816       (T->VT)->S=main_read_seq(T->template_name);
5817       sprintf ( T->template_file, "%s", T->template_name);
5818     }
5819   return T;
5820 }
5821 //add template
5822 struct X_template *fill_U_template ( char *name,char *p, Sequence *S)
5823 {
5824   /*Profile template*/
5825   struct X_template *U;
5826   
5827   U=fill_X_template ( name, p, "_U_");
5828   sprintf (U->template_format , "string list");
5829   
5830   if (!check_file_exists(U->template_name))
5831     {
5832       add_information ( stderr, "_U_ Template %s Could Not Be Found\n",U->template_name);
5833       free_X_template (U);
5834       return NULL;
5835     }
5836   else
5837     {
5838       //(U->VU)->list=file2string(U->template_name);
5839       sprintf ( U->template_file, "%s", U->template_name);
5840     }
5841   return U;
5842 }
5843 struct X_template *fill_E_template ( char *name,char *p, Sequence *S)
5844 {
5845   /*Profile template*/
5846   struct X_template *E;
5847   
5848
5849   E=fill_X_template ( name, p, "_E_");
5850   sprintf (E->template_format , "fasta_seq");
5851   
5852   if (!is_aln(E->template_name) && !is_seq (E->template_name))
5853     {
5854       
5855       add_information ( stderr, "_E_ Template %s Could Not Be Found\n",E->template_name);
5856       free_X_template (E);
5857       return NULL;
5858     }
5859   else
5860     {
5861       (E->VE)->S=main_read_seq (E->template_name);
5862       sprintf ( E->template_file, "%s", E->template_name);
5863     }
5864   return E;
5865 }
5866 struct X_template *fill_G_template ( char *name,char *p, Sequence *S)
5867 {
5868   struct X_template *G;
5869   G=fill_X_template ( name, p, "_G_");  
5870   sprintf (G->template_format , "fasta_seq");
5871   
5872   /*1: Get the sequence from another file if needed*/
5873   if ( strm (name, p))sprintf ( G->template_file, "%s",output_fasta_seqX (NULL,"w",S,NULL, seq_name2index (name, S)));
5874   else if ( strstr (p, "SEQFILE_"))
5875     {
5876       Sequence *ST;
5877       int i2;
5878       
5879    
5880       ST=main_read_seq (after_strstr ( p,"SEQFILE_G_"));
5881    
5882       i2=seq_name2index (name, ST);
5883       if ( i2!=-1)
5884         {
5885           sprintf ( G->template_file, "%s",output_fasta_seqX (NULL,"w",ST,NULL, i2));
5886           sprintf ( G->template_name, "%s", name);
5887         }
5888       free_sequence (ST, -1);
5889     }
5890   else sprintf (G->template_file, "%s", G->template_name);
5891         
5892   
5893   /*2: Put the template in VG->S*/
5894   if (!is_seq (G->template_file))
5895     {
5896       add_information ( stderr, "_G_ Template %s Could Not Be Found \n",p);
5897
5898       free_X_template (G);
5899       return NULL;
5900     }
5901   else
5902     {
5903       (G->VG)->S=get_fasta_sequence (G->template_file, NULL);
5904     }
5905   return G;
5906 }
5907
5908
5909 char *seq2T_value ( Sequence *S, int n, char *value, char *type)
5910 {
5911   static char *rv_buf;
5912   X_template *X;
5913
5914   if ( !rv_buf)rv_buf=vcalloc (100, sizeof(char));
5915   if (!(X=seq_has_template (S, n, type)))return NULL;
5916   else
5917     {
5918       if (strm (value, "template_file"))return X->template_file;
5919       else if ( strm (value, "template_name"))return X->template_name;
5920       else if ( strm (value, "seq_name"))return X->seq_name;
5921       else if (strm (type, "_P_"))
5922         {
5923           if ( strm (value, "pdb_id"))return (X->VP)->pdb_id;
5924         }
5925       else if ( strm (type, "_R_"))
5926         {
5927           if ( strm (value, "A"))
5928             {
5929               if ((X->VR)->A)
5930                 {sprintf ( rv_buf, "%ld", (long)(X->VR)->A);return rv_buf;}
5931               else return NULL;
5932             }
5933         }
5934       
5935     }
5936   return NULL;
5937 }
5938 char *seq2P_pdb_id (Sequence *S, int n)
5939 {
5940   if (!S->T || !S->T[n] || !(S->T[n])->P ) return NULL;
5941   else return ((S->T[n])->P)->template_name;
5942 }
5943
5944   
5945 char *seq2P_template_file(Sequence *S, int n)
5946 {
5947  
5948   return seq2T_value (S, n, "template_file", "_P_");
5949 }
5950
5951 char *profile2P_template_file (Sequence *S, int n)
5952 {
5953   Alignment *A;
5954   int a;
5955   char *p;
5956   
5957   if ( !(A=seq2R_template_profile (S, n)))return NULL;
5958   for (a=0; a<A->nseq; a++)
5959     {
5960       if ((p=seq2P_template_file (A->S, a))!=NULL)return p;
5961     }
5962   return NULL;
5963 }
5964 Alignment * seq2R_template_profile (Sequence *S, int n)
5965 {
5966   X_template *X;
5967   
5968   return (Alignment *)atop(seq2T_value (S, n, "A", "_R_"));
5969   
5970   if (!(X=seq_has_template (S, n, "_R_")))return NULL;
5971   else
5972     {
5973       if (!(X->VR))return NULL;
5974       else return (X->VR)->A;
5975     }
5976   return NULL;
5977         
5978   
5979   
5980 }
5981 char * seq2E_template_string (Sequence *S, int n)
5982 {
5983   struct X_template *T;
5984   
5985   if ( (T=seq_has_template (S, n, "_E_"))!=NULL)
5986     return  ((T->VE)->S)->seq[0];
5987   else 
5988     return NULL;
5989 }
5990 //add template
5991 int* seq2U_template (Sequence *S, int n)
5992 {
5993    struct X_template *T;
5994   
5995    if ( (T=seq_has_template (S, n, "_U_"))!=NULL)
5996      return  (T->VU)->list;
5997    else 
5998      return NULL;
5999 }
6000 char * seq2T_template_string (Sequence *S, int n)
6001 {
6002   struct X_template *T;
6003   
6004   if ( (T=seq_has_template (S, n, "_T_"))!=NULL)
6005     return  ((T->VT)->S)->seq[0];
6006   else 
6007     return NULL;
6008 }
6009
6010 struct X_template* seq_has_template ( Sequence *S, int n, char *mode)
6011 {
6012   Template *T;
6013   
6014   if ( !S || !mode) return NULL;
6015   else if ( n<0 || n>=S->nseq)return NULL;
6016   else if ( !(S->T)) return NULL;
6017   else if ( !(S->T[n]))return NULL;
6018
6019   T=S->T[n];
6020   //ADD STRUCTURE
6021   //add template
6022   if      ( strm (mode, "_P_"))return T->P;
6023   else if ( strm (mode, "_F_"))return T->F;
6024   else if ( strm (mode, "_S_"))return T->S;
6025   else if ( strm (mode, "_R_"))return T->R;
6026   else if ( strm (mode, "_T_"))return T->T;
6027   else if ( strm (mode, "_E_"))return T->E;
6028   else if ( strm (mode, "_U_"))return T->U;
6029   else if ( strm (mode, "_G_"))return T->G;
6030   else return NULL;
6031 }  
6032
6033 char ** name2random_subset (char **in_name, int n_in, int n_out)
6034 {
6035   char **out_name;
6036   
6037   int **list;
6038   int a,max;
6039   
6040   
6041   vsrand (0);
6042   max=n_in*10000;
6043   out_name=declare_char (n_out,MAXNAMES+1 );
6044   list=declare_int (n_in, 2);
6045   
6046   for (a=0; a<n_in; a++)
6047       {
6048         list[a][0]=a;
6049         list[a][1]=rand ()%max;
6050       }
6051   sort_int ( list,2, 1, 0, n_in-1);
6052   
6053   for ( a=0; a<n_in; a++)
6054   {
6055     sprintf ( out_name[a], "%s", in_name[list[a][0]]);
6056   }
6057   free_int (list, -1);
6058   return out_name;
6059 }
6060     
6061 Alignment * aln2random_order (Alignment *A)
6062 {
6063   
6064   char **name_list;
6065   
6066   name_list=name2random_subset (A->name, A->nseq, A->nseq);
6067   A=reorder_aln (A, name_list, A->nseq);
6068   free_char (name_list, -1);
6069   return A;
6070 }
6071 Alignment *aln2jacknife (Alignment *A, int nseq, int len)
6072 {
6073   int a, b;
6074   
6075   if (nseq!=0 && nseq<A->nseq)
6076     {
6077       char **name;
6078       
6079       name=name2random_subset (A->name, A->nseq, nseq);
6080       A=reorder_aln (A, name, nseq);
6081       free_char (name, -1);
6082     }
6083   
6084   if (len!=0 && len<A->len_aln)
6085     {
6086       int **l;
6087       Alignment *B;
6088       
6089       l=declare_int (A->len_aln, 2);
6090       for (a=0; a< A->len_aln; a++)
6091         {
6092           l[a][0]=a; 
6093           l[a][1]=rand()%(A->len_aln*1000);
6094         }
6095       sort_int ( l,2, 1, 0, A->len_aln-1);
6096       B=copy_aln (A, NULL);
6097       for ( a=0; a< len; a++)
6098         {
6099           for ( b=0; b<A->nseq; b++)
6100             {
6101               A->seq_al[b][a]=B->seq_al[b][l[a][0]];
6102             }
6103         }
6104       for (b=0; b<A->nseq; b++)A->seq_al[b][len]='\0';
6105       free_aln (B);
6106       free_int (l, -1);
6107     }
6108   return A;
6109 }
6110 Alignment * aln2scramble_seq (Alignment *A)
6111 {
6112   int **list;
6113   char **name_list;
6114   int a,max;
6115
6116   max=100*A->nseq;
6117   vsrand (0);
6118   
6119   list=declare_int (A->nseq, 2);
6120   name_list=vcalloc (A->nseq, sizeof (char*));
6121   
6122   
6123   for (a=0; a<A->nseq; a++)
6124       {
6125         list[a][0]=a;
6126         list[a][1]=rand ()%max;
6127       }
6128   sort_int ( list,2, 1, 0, A->nseq-1);
6129   
6130   for ( a=0; a< A->nseq; a++)
6131     name_list[a]=A->seq_al[a];
6132   for (a=0; a<A->nseq; a++)
6133     {
6134       A->seq_al[a]=name_list[list[a][0]];
6135     }
6136   vfree (name_list);
6137   free_int (list, -1);
6138   return aln2random_order (A);
6139 }
6140   
6141   
6142
6143 Alignment * reorder_aln ( Alignment *A, char **name, int nseq)
6144         {
6145         int a,sn;
6146         Alignment *BUF;
6147         int  n=0;
6148         int *tpp_int;
6149         
6150         if ( name==NULL)return aln2random_order(A);
6151         
6152         
6153         BUF=copy_aln ( A,NULL); 
6154         for ( a=0; a<nseq; a++)
6155                 {
6156                   sn =name_is_in_list ( name[a],BUF->name, A->nseq,STRING);
6157                   if ( sn==-1)
6158                         {
6159                             ;
6160                         }
6161                 else
6162                     {
6163                     
6164                       
6165                     SWAPP(A->order[n], BUF->order[sn], tpp_int);
6166                     sprintf ( A->name[n], "%s", BUF->name[sn]);             
6167                     sprintf ( A->seq_al[n], "%s",BUF->seq_al[sn]);
6168                     sprintf ( A->seq_comment[n], "%s",  BUF->seq_comment[sn]);
6169                     
6170                     n++;
6171                       
6172                     }
6173                 }
6174         
6175         for ( a=n; a< A->nseq; a++)A->name[a][0]=A->seq_al[a][0]='\0';
6176         A->nseq=n;
6177         
6178         if ( A->A)A->A=reorder_aln(A->A, name, nseq);
6179         free_aln (BUF);
6180         return A;
6181         } 
6182 Sequence * reorder_seq_2 ( Sequence *A, int **order,int field, int nseq)
6183         {
6184           char **name;
6185           int a;
6186           
6187           if (!A || !order) return A;
6188           name=declare_char (A->nseq, 100);
6189           for (a=0; a<nseq; a++)
6190             sprintf ( name[a], "%s", A->name[order[a][field]]);
6191           A=reorder_seq (A, name,nseq);
6192           free_char (name, -1);
6193           return A;
6194         }
6195 Sequence * reorder_seq ( Sequence *A, char **name, int nseq)
6196         {
6197         int a,sn;
6198         Sequence *nA;
6199
6200         
6201         nA=duplicate_sequence (A);
6202         
6203         
6204         for ( a=0; a< nseq; a++)
6205           {
6206             sn=name_is_in_list (name[a] ,nA->name, nA->nseq, 100);
6207             if (sn==-1)continue;
6208             
6209             if ( nA->file)       sprintf ( A->file[a], "%s", nA->file[sn]);
6210             
6211             if ( nA->seq_comment)sprintf ( A->seq_comment[a], "%s", nA->seq_comment[sn]);
6212             if ( nA->aln_comment)sprintf ( A->aln_comment[a], "%s", nA->aln_comment[sn]);
6213             sprintf ( A->seq[a], "%s", nA->seq[sn]);
6214             A->len[a]=nA->len[sn];
6215             sprintf ( A->name[a], "%s", nA->name[sn]);
6216             A->T[a][0]=nA->T[sn][0];
6217           }
6218         A->nseq=nseq;
6219         free_sequence (nA, nA->nseq);
6220         
6221         return A;
6222
6223
6224 char * concatenate_seq ( Sequence *S, char *conc, int *order)
6225         {
6226             int a;
6227             
6228             vfree (conc);
6229             conc=vcalloc ( S->nseq*S->max_len, sizeof (char));
6230
6231             for ( a=0; a< S->nseq; a++)
6232                 {
6233                     conc=strcat ( conc, S->seq[order[a]]);
6234                 }
6235             return conc;
6236
6237         }
6238
6239
6240           
6241
6242 Alignment * rotate_aln ( Alignment *A, char *name)
6243 {
6244   Alignment *B;
6245   int a, b;
6246   
6247   B=declare_aln2 (A->len_aln, A->nseq+1);
6248   for ( a=0; a< A->nseq; a++)
6249     for ( b=0; b< A->len_aln; b++)
6250       {
6251         B->seq_al[b][a]=A->seq_al[a][b];
6252       }
6253   for (a=0; a< A->len_aln; a++)
6254     if (name && name[0])sprintf ( B->name[a], "%s_%s%d", name, (a<9)?"0":"",a+1);
6255     else
6256       sprintf ( B->name[a], "%d", a+1);
6257   
6258   
6259   for (a=0; a< A->len_aln; a++)B->seq_al[a][A->nseq]='\0';
6260   B->len_aln=A->nseq;
6261   B->nseq=A->len_aln;
6262   /*free_aln (A);*/
6263   return B;
6264 }
6265   
6266 Alignment * invert_aln ( Alignment *A)
6267 {
6268   char *buf;
6269   int l, a, b, c;
6270   
6271   for ( a=0; a< A->nseq; a++)
6272     {
6273         l=strlen ( A->seq_al[a]);
6274         buf=vcalloc ( l+1,sizeof (char) );
6275         
6276         for ( c=l-1,b=0; b< l; b++, c--)
6277           {
6278             buf[c]=A->seq_al[a][b];
6279           }
6280         buf[l]='\0';
6281         sprintf ( A->seq_al[a], "%s", buf);
6282     }
6283   vfree(buf);
6284   return A;
6285 }
6286 char * complement_string (char *s)
6287 {
6288   char *buf;
6289   int l, a, b, c;
6290   
6291   l=strlen (s);
6292   for ( b=0; b< l; b++)
6293     {
6294       char r;
6295       r=s[b];
6296       if ( r=='a')r='t';
6297       else if (r=='A')r='T';
6298       else if (r=='t')r='a';
6299       else if (r=='T')r='A';
6300       else if (r=='g')r='c';
6301       else if (r=='G')r='C';
6302       else if (r=='c')r='g';
6303       else if (r=='C')r='G';
6304       s[b]=r;
6305     }
6306   
6307   return invert_string (s);
6308 }
6309 Alignment * complement_aln ( Alignment *A)
6310 {
6311   char *buf;
6312   int l, a, b, c;
6313   
6314   for ( a=0; a< A->nseq; a++)
6315     {
6316       A->seq_al[a]=complement_string (A->seq_al[a]);
6317     }
6318
6319   return A;
6320 }
6321
6322 Alignment * extract_nol_local_aln(Alignment *A, int start, int max_end)
6323      {
6324      A=extract_aln ( A, start, max_end);
6325      A=trunkate_local_aln (A);
6326      return A;
6327      }
6328
6329 Alignment * alnpos_list2block (Alignment *A, int n, char **in_list)
6330 {
6331   int *pos;
6332   int a;
6333   char **list;
6334   int list_declared=0;
6335   Alignment *B;
6336   
6337   if (check_file_exists (in_list[0]))
6338     {
6339       int mn;
6340       char ***tmp_list;
6341       
6342       mn=count_n_line_in_file (in_list[0]);
6343       list=declare_char (mn, 100);
6344       list_declared=1;
6345       tmp_list=file2list (in_list[0], " ");
6346       a=0;
6347       n=0;
6348       while (tmp_list[a])
6349         {
6350           if (tmp_list[a][1][0]!='!')
6351             {
6352               sprintf (list[n++], "%s", tmp_list[a][1]);
6353             }
6354           a++;
6355         }
6356       free_arrayN ((void **)tmp_list, 3);
6357     }
6358   else
6359     {
6360       list=in_list;
6361     }
6362           
6363   
6364   pos=vcalloc (A->len_aln, sizeof (int));
6365   for (a=0; a<n; a++)
6366     {
6367       
6368       if (strstr (list[a], "-"))
6369         {
6370           int start, end, x;
6371           x=sscanf (list[a], "%d-%d", &start, &end);
6372           if (x!=2 || !A || start<=0 || start>=end || end>A->len_aln+1)
6373             {
6374               add_warning ( stderr, "Illegal coordinates in extract_pos_list [%s]", list[a]);
6375               return A;
6376             }
6377           start--; end--;
6378           for (a=start; a<end; a++)pos[a]=1;
6379         }
6380       else
6381         {
6382           int p;
6383           p=atoi (list[a]);
6384           if (p<1 || p>A->len_aln)
6385             {
6386               add_warning ( stderr, "Illegal coordinates in extract_pos_list [%s]", list[a]);
6387             }
6388           p--;
6389           pos[p]=1;
6390         }
6391     } 
6392   B=alnpos2block(A, pos, NULL);
6393   vfree (pos);
6394   if ( list_declared)free_char (list, -1);
6395   
6396   return B;
6397 }
6398 Alignment * aln2block   (Alignment  *A, int start, int end, Alignment *B)
6399 {
6400   if ( !A || start<=0 || start>=end || end>A->len_aln+1)
6401     {
6402       add_warning ( stderr, "Illegal coordinates in extract_block start=%d end=%d len=%d [Note : [start-end[, with [1...n] ** Block Ingored", start, end, A->len_aln);
6403       return A;
6404     }
6405   else
6406     {
6407       int *pos, p;
6408       start--;
6409       end--;
6410       pos=vcalloc (A->len_aln, sizeof (int));
6411       for (p=start;p<end;p++)
6412             {
6413               pos[p]=1;
6414             }
6415       B=alnpos2block (A, pos, B);
6416       vfree (pos);
6417       return B;
6418     }
6419 }
6420 Alignment * alnpos2block   (Alignment  *A, int *pos, Alignment *B)
6421 {
6422  
6423   //extract a subset of B without over-writing A
6424   int a, b;
6425   
6426   B=copy_aln (A, B);
6427   B->len_aln=0;
6428   for (a=0; a<=A->len_aln; a++)
6429     {
6430       if ( pos[a]!=0 || a==A->len_aln)
6431         {
6432           for ( b=0; b<A->nseq; b++)
6433             B->seq_al[b][B->len_aln]=A->seq_al[b][a];
6434           if ( a!=A->len_aln)B->len_aln++;
6435         }
6436     }
6437  
6438   return B;
6439 }
6440 Alignment * extract_aln ( Alignment *A, int start, int end)
6441 {
6442   return extract_aln2 ( A, start, end, "cons");
6443 }
6444
6445 Alignment * extract_aln2 ( Alignment *A, int in_start, int in_end, char *seq)
6446      {
6447        char *tmp;
6448        FILE *fp;
6449        
6450
6451        tmp=vtmpnam (NULL);
6452        fp=vfopen (tmp, "w");
6453        fprintf ( fp, "%s %d %d\n", seq, in_start, in_end);
6454        vfclose (fp);
6455        return extract_aln3 (A,tmp);
6456      }
6457 Alignment * extract_aln3 ( Alignment *B, char *file)
6458      {
6459      int a, b, c;
6460      int start, end;
6461      int n, i, s, nline=0;
6462      FILE *fp;
6463      Alignment *A=NULL;
6464      int *col;
6465      char name[MAXNAMES];
6466      char line[VERY_LONG_STRING];
6467      int *offset;
6468      
6469      /*Reads in a file
6470        #comment
6471        ! seq_name offset
6472        seqname pos
6473        OR
6474        seqname start end[
6475        modifies the incoming alignment
6476      */
6477    
6478      offset=vcalloc ( B->nseq+1, sizeof (int));
6479      fp=vfopen (file,"r");
6480      while ( (c=fgetc(fp))!=EOF)
6481        {
6482          s=-1;
6483          fgets ( line, VERY_LONG_STRING,fp);
6484          if ( c=='!')
6485            {
6486              sscanf (line, "%s %d", name, &start);
6487              s=name_is_in_list (name,B->name,B->nseq,MAXNAMES);
6488            }
6489          if (s!=-1)
6490            offset[s]=start;
6491        }
6492      
6493      vfclose (fp);
6494      
6495      A=copy_aln (B, A);     
6496      col=vcalloc ( A->len_aln, sizeof (int));
6497      
6498      fp=vfopen ( file, "r");
6499      while ( (c=fgetc(fp))!=EOF)
6500        {
6501          nline++;
6502          if ( c=='#' || c=='!')fgets ( line, VERY_LONG_STRING,fp);
6503          else
6504            {
6505              ungetc(c, fp);
6506              fgets ( line, VERY_LONG_STRING,fp);
6507              
6508              if (sscanf (line, "%s %d %d", name, &start, &end)==3);
6509              else if (sscanf (line, "%s %d", name, &start)==2)
6510                {
6511                  end=start+1;
6512                }
6513              else
6514                {
6515                  add_warning ( stderr, "Wrong format in coordinate file (line=%d) ** Line Ignored", nline);
6516                  continue;
6517                }
6518              if ( end==0)end=A->len_aln+1;
6519
6520              s=name_is_in_list (name,A->name,A->nseq,MAXNAMES);
6521              
6522              
6523              if ( s==-1 && !strm (name, "cons"))
6524                {
6525                  add_warning ( stderr, "Seq %s does not belong to the alignment (line %d) ** Line ignored", name,nline);
6526                  continue;
6527                }
6528              else if ( start>end)
6529                {
6530                  add_warning ( stderr, "Illegal coordinates [%s %d %d] (line %d) ** Line ignored", name,start, end,nline);
6531                  continue;
6532                }
6533              else
6534                {
6535                  int done=0;
6536                  if ( s!=-1)
6537                    { 
6538                      start-=offset[s]-1;
6539                      end-=offset[s]-1;
6540                    }
6541                  for (n=0, a=0; done!=1 && a< A->len_aln; a++)
6542                    {
6543                      i=(strm (name, "cons"))?1:!is_gap(A->seq_al[s][a]);
6544                      
6545                      n+=i;
6546                      if (n>=start && n<end)
6547                        {
6548                          col[a]=1;
6549                        }
6550                      if (n>=end)done=1;
6551                      //if (n>=start && n<end && !(i==0 && n==end-1))
6552                      //{
6553                      // col[a]=1;
6554                      //}
6555                      //else if ( n>=end)a=A->len_aln;
6556                    }
6557                  if ( done==0)
6558                    {
6559                      HERE ("Warning Missing positions in File %s",file );
6560                    }
6561                }
6562            }
6563        }
6564      vfclose ( fp);
6565      
6566
6567                  
6568      /*Extract [start-end[*/
6569      for ( b=0,a=0; a< A->len_aln; a++)
6570        {
6571          if ( col[a])
6572            {
6573              for (c=0; c< A->nseq; c++)A->seq_al[c][b]=A->seq_al[c][a];
6574              b++;
6575            }
6576        }
6577      A->len_aln=b;
6578
6579      for (c=0; c< A->nseq; c++)A->seq_al[c][A->len_aln]='\0';
6580      vfree (col);
6581      
6582      return A;
6583
6584      }
6585 Alignment * trunkate_local_aln ( Alignment *A)
6586      {
6587      int a, b;
6588      int **pos;
6589      int **cache;
6590      int seq;
6591    
6592      
6593      cache=declare_int (return_max_int (A->order,read_size_int ( A->order,sizeof (int*)),0)+1,return_max_int (A->order,read_size_int ( A->order,sizeof (int*)),1)+A->len_aln+1);    
6594      pos=aln2pos_simple(A,A->nseq);
6595      
6596      for ( b=0; b<A->len_aln; b++)
6597          for ( a=0; a< A->nseq; a++)     
6598              {
6599              seq=A->order[a][0];
6600              if ( pos[a][b]<=0);
6601              else if ( pos[a][b]>0)
6602                  {
6603                  
6604                  if (cache[seq][pos[a][b]]==0)cache[seq][pos[a][b]]++;
6605                  else if ( cache[seq][pos[a][b]]>=1)
6606                       {      
6607                       cache[seq][pos[a][b]]++;
6608                       A->seq_al[a][b]='\0';
6609                       }
6610                  }
6611              }
6612      
6613      A->len_aln=get_shortest_string ( A->seq_al, A->nseq, NULL, NULL);
6614      pad_string_array ( A->seq_al, A->nseq, A->len_aln, '-');
6615      
6616      free_int (pos, -1);
6617      free_int ( cache,-1);
6618      
6619      
6620      return A;
6621      }
6622
6623 int get_nol_aln_border ( Alignment *A, int start, int direction)
6624      {
6625      int a, b;
6626      int **pos;
6627      int **cache;
6628      int seq,end;
6629      
6630      /*This Function Returns the limit position for a non overlaping alignment*/
6631      
6632      cache=declare_int (return_max_int (A->order,read_size_int ( A->order,sizeof (int*)),0)+1,return_max_int (A->order,read_size_int ( A->order,sizeof (int)),1)+A->len_aln+1);
6633      pos=aln2pos_simple(A,A->nseq);
6634      end=(direction==GO_RIGHT)?A->len_aln:-1;
6635      
6636
6637      for ( b=start; b!=end;b+=direction)
6638          for ( a=0; a< A->nseq; a++)     
6639              {
6640              seq=A->order[a][0];
6641              if ( pos[a][b]<=0);
6642              else if ( pos[a][b]>0)
6643                  {
6644                  
6645                  if (cache[seq][pos[a][b]]==0)cache[seq][pos[a][b]]++;
6646                  else if ( cache[seq][pos[a][b]]>=1)
6647                       {      
6648                       cache[seq][pos[a][b]]++;
6649                       free_int(cache, -1);
6650                       return b-direction;
6651                       }
6652                  }
6653              }
6654      
6655      free_int ( cache,-1);
6656      free_int (pos, -1);
6657      return end-direction;
6658      }
6659
6660
6661
6662
6663
6664 char * extract_defined_seq ( char *in, int in_of, int in_start, int *aa_def, int dir, int *out_start, char *out)
6665      {
6666      int start=0, end,l;
6667      int b, c, d;
6668
6669      
6670
6671      if ( dir==GO_LEFT){start=in_start-1;}
6672      else if ( dir==GO_RIGHT){start=in_start+1;}        
6673         
6674      end=start;
6675      while (aa_def[end]!=UNDEFINED)
6676          {
6677          end+=dir;
6678          }
6679      end-=dir;
6680      
6681      if (end<start)SWAP(end,start);
6682      
6683      l=strlen ( in);
6684      out_start[0]=-1;
6685      for (b=0,d=0,c=in_of;b<l; b++)
6686          {
6687          c+=1-is_gap(in[b]);
6688          if ( c>=start && c<=end)
6689              {
6690              if ( out_start[0]==-1)out_start[0]=c-!is_gap(in[b]);
6691              out[d++]=in[b];
6692              }
6693          }
6694      out[d]='\0';
6695      
6696     
6697      return out;
6698      }
6699
6700 Alignment * aln2N_replicate (Alignment *A,char *nn, char *name)
6701 {
6702   int a, n;
6703   char *fname;
6704
6705   fname=vcalloc (100, sizeof (char));
6706   if (nn)n=atoi(nn);
6707   else n=100;
6708   if (!name){name=vcalloc (100, sizeof (char)); sprintf (name, "replicate");}
6709   
6710   
6711   for (a=0; a< n;a++)
6712     {
6713       FILE *fp;
6714       sprintf (fname, "%s.%d.rep",name, a+1);
6715       fp=vfopen (fname, "w");
6716       
6717       vfclose(aln2replicate (A, fp));
6718       fprintf ( stdout, ">%s Alignment Replicate #%d\n",fname, a+1); 
6719     }
6720   myexit (EXIT_SUCCESS);
6721 }
6722 FILE *aln2replicate (Alignment *A, FILE *fp)
6723 {
6724   int a, b;
6725   int *p;
6726   float tot=0;
6727   float corr;
6728   if (A->col_weight)for (a=0; a<A->len_aln; a++)tot+=A->col_weight[a];
6729   else tot=A->len_aln;
6730   
6731   p=vcalloc (A->len_aln, sizeof (int));
6732   corr=(float)A->len_aln/tot;
6733   
6734   for (a=0; a<A->len_aln; a++)
6735     {
6736       int x;
6737       x=rand()%(int)tot;
6738       
6739       p[a]=(int)(x*corr);
6740     }
6741   
6742   for (a=0; a<A->nseq; a++)
6743     {
6744       fprintf ( fp, ">%s\n", A->name[a]);
6745       //for (b=0;b<A->len_aln; b++)fprintf ( stdout, "%d ", (int)p[b]);
6746       for (b=0;b<A->len_aln; b++)fprintf ( fp, "%c", A->seq_al[a][p[b]]);
6747       fprintf ( fp, "\n");
6748     }
6749
6750   vfree (p);
6751   return fp;
6752 }
6753     
6754 Alignment * orthologous_concatenate_aln (Alignment *A, Sequence *S, char *mode)
6755 {
6756   Alignment *C;
6757   char **name, *cname;
6758   int nname=0;
6759   int a, b,c, i;
6760   
6761   if (mode && strm (mode, "voronoi"))seq_weight2species_weight (A, S);
6762   
6763   
6764   cname=vcalloc ( 100, sizeof (char));
6765   name=declare_char (A->nseq, 100);
6766   for (a=0; a<A->nseq; a++)
6767     {
6768       char *p=strstr (A->name[a], "_");
6769       if (!p)
6770         {
6771           fprintf ( stderr, "\nWARNING: Seq %s could not be included.", A->name[a]);
6772         }
6773       p+=1;
6774       if ( name_is_in_list (p, name,nname, 100)==-1)
6775         {
6776           sprintf ( name[nname++], "%s", p);
6777         }
6778     }
6779  
6780   C=declare_aln2 (nname, (A->len_aln*S->nseq)+1);
6781   free_char (C->name,-1); C->name=name;
6782   C->nseq=nname;
6783   C->col_weight=vcalloc ( A->len_aln*S->nseq, sizeof(float));
6784   
6785   C->len_aln=0;
6786     for (a=0; a<S->nseq; a++)
6787     {
6788       for (b=0; b<C->nseq; b++)
6789         {
6790           sprintf (cname, "%s_%s", S->name[a],C->name[b]);
6791           if ((i=name_is_in_list (cname, A->name, A->nseq, 100))==-1)
6792             {
6793               char *s=generate_null (A->len_aln);
6794               strcat (C->seq_al[b], s);
6795               vfree (s);
6796             }
6797           else
6798             strcat (C->seq_al[b], A->seq_al[i]);
6799         }
6800       for (c=C->len_aln, b=0;b<A->len_aln;b++, c++)  
6801         {
6802           C->col_weight[c]=(S->W)->SEQ_W[a];
6803         }
6804       C->len_aln+=A->len_aln;
6805     }
6806   return C;
6807 }
6808               
6809
6810 Alignment * concatenate_aln ( Alignment *A1, Alignment *A2, char *spacer)
6811 {
6812   Alignment *A;
6813   int a, i;
6814   
6815   A=declare_aln2( A1->nseq+A2->nseq , A1->len_aln+A2->len_aln+1);
6816   for ( a=0; a< A1->nseq; a++)
6817     {
6818       if ((i=name_is_in_list ( A1->name[a], A2->name, A2->nseq, 100))!=-1)
6819         {
6820           sprintf ( A->name[A->nseq], "%s", A1->name[a]);
6821           sprintf (A->seq_al[A->nseq], "%s%s%s", A1->seq_al[a],(spacer)?spacer:"", A2->seq_al[i]);
6822           A->nseq++;
6823         }
6824       else 
6825         {
6826           char *buf;
6827           buf=generate_string (A2->len_aln, '-');
6828           sprintf ( A->name[A->nseq], "%s", A1->name[a]);
6829           sprintf (A->seq_al[A->nseq], "%s%s",  A1->seq_al[a], buf);
6830           A->nseq++;
6831           vfree (buf);
6832         }
6833     }
6834   for ( a=0; a< A2->nseq; a++)
6835     {
6836       if ((i=name_is_in_list ( A2->name[a], A1->name, A1->nseq, 100))==-1)
6837         {
6838           char *buf;
6839           buf=generate_string (A1->len_aln, '-');
6840           sprintf ( A->name[A->nseq], "%s", A2->name[a]);
6841           sprintf (A->seq_al[A->nseq], "%s%s",  buf, A2->seq_al[a]);
6842           A->nseq++;
6843           vfree (buf);
6844         }
6845     }
6846   A->len_aln=A1->len_aln+A2->len_aln;
6847   return A;
6848 }
6849 Alignment * aln_cat ( Alignment *A, Alignment *B)
6850      { 
6851      int a;
6852      
6853      if ( A->nseq!=B->nseq) 
6854          {
6855          fprintf ( stderr, "\nERROR IN ALN CAT: DIFFERENT NSEQ\n");
6856          myexit(EXIT_FAILURE);
6857          }
6858
6859      A=realloc_alignment2(A, A->nseq,A->len_aln+B->len_aln+1);
6860     
6861      for ( a=0;a< A->nseq; a++)
6862          {      
6863          strcat ( A->seq_al[a], B->seq_al[a]);
6864          }
6865      A->len_aln+=B->len_aln;
6866      return A;
6867      }
6868 int verify_aln ( Alignment *A, Sequence *S, char *message)
6869      {
6870      int a, b, c,s,r;
6871
6872
6873      for ( a=0;a< A->nseq; a++)
6874          {
6875          s=A->order[a][0];
6876          r=A->order[a][1];
6877          for ( b=0, c=0; b< A->len_aln; b++)
6878              {
6879              if ( !is_gap(A->seq_al[a][b]))
6880                   {
6881                   if (tolower(A->seq_al[a][b])!=tolower(S->seq[s][c+r]))
6882                       {
6883                       fprintf ( stderr, "\n%s\nResidue [%c %d, %c %d] line %d seq %d",message,A->seq_al[a][b], b,S->seq[s][c+r], c+r,a,s);  
6884                       output_Alignment_with_res_number(A, stderr);
6885                       myexit(EXIT_FAILURE);
6886                       return 0;
6887                       }
6888                   c++;
6889                   }
6890              }
6891          }
6892      return 1;
6893      }
6894
6895 Alignment *adjust_est_aln ( Alignment *PW, Alignment *M, int s)
6896 {
6897   /*This function reajusts M, threading M onto PW
6898    two seqences in PW
6899    s+1 seq in M
6900    
6901    seq 0 PW ----> 0->s-1 in M
6902    seq 1 PW ----> 1->s   in M;
6903    
6904    */
6905   int a, b;
6906   static char **array;
6907
6908   
6909   int top_M=0;
6910   int bottom_M=0;
6911   
6912   
6913   if ( array==NULL)
6914     {
6915       array=declare_char (500, 100000);
6916     }
6917
6918   for ( a=0; a< PW->len_aln; a++)
6919     {
6920       if ( is_gap(PW->seq_al[0][a]))
6921         {
6922           for ( b=0; b< s; b++)
6923             array[b][a]='-';
6924         }
6925       else
6926         {
6927           for ( b=0; b< s; b++)
6928             array[b][a]=M->seq_al[b][top_M];
6929         top_M++;
6930         }
6931       
6932       if ( is_gap(PW->seq_al[1][a]))
6933         {
6934           array[s][a]='-';
6935         }
6936       else
6937         {
6938           
6939           array[s][a]=M->seq_al[s][bottom_M];
6940         bottom_M++;
6941         } 
6942     }
6943   
6944   M->len_aln=PW->len_aln;
6945   for (a=0; a<s; a++)
6946     {
6947       for (b=0; b<PW->len_aln; b++)
6948         M->seq_al[a][b]=array[a][b];
6949       M->seq_al[a][b]='\0';
6950     }
6951
6952
6953   M->nseq=s+1;
6954   
6955   return M;
6956 }
6957
6958
6959 Alignment * rename_seq_in_aln (Alignment *A, char ***list)
6960 {
6961   int n, i;
6962   if ( !A)return A;
6963   
6964
6965   
6966   n=0;
6967   while ( list[n][0][0])
6968     {
6969       if ( (i=name_is_in_list (list[n][0], A->name, A->nseq, 100))!=-1)
6970         {
6971           sprintf ( A->name[i], "%s", list[n][1]);
6972         }
6973       n++;
6974     }
6975   
6976   A->S=rename_seq_in_seq (A->S, list);
6977   return A;
6978 }
6979 Sequence * rename_seq_in_seq (Sequence *A, char ***list)
6980 {
6981   int n, i;
6982   if ( !A || !list)return A;
6983   
6984   n=0;
6985   while ( list[n][0][0])
6986     {
6987       if ( (i=name_is_in_list (list[n][0], A->name, A->nseq, 100))!=-1)
6988         {
6989           sprintf ( A->name[i], "%s", list[n][1]);
6990         }
6991       n++;
6992     }
6993   return A;
6994 }
6995 /********************************************************************/
6996 /*                                                                  */
6997 /*                   FLOAT SIMILARITIES                             */
6998 /*                                                                  */
6999 /*                                                                  */
7000 /*                                                                  */
7001 /********************************************************************/
7002 float get_seq_fsim ( char *string1, char *string2, char *ignore, char *similarity_set,int **matrix, int MODE )
7003         {
7004         int len, a, r1, r2, nr1=0, nr2=0;
7005         float pos=0, sim=0;
7006                 
7007
7008         len=MIN((strlen (string1)),(strlen (string2)));
7009         if ( len==0)return 0;
7010         
7011         for ( a=0; a< len; a++)
7012                 {
7013                   
7014                   r1=string1[a];
7015                   r2=string2[a];
7016                   nr1+=!is_gap(r1);
7017                   nr2+=!is_gap(r2);
7018                   
7019                   if ( !is_in_set (r1, ignore) && !is_in_set (r2, ignore))
7020                         {
7021                         pos++;
7022                         if ( matrix)sim+=matrix[r1-'A'][r2-'A'];
7023                         else if (is_in_same_group_aa(r1,r2,0, NULL,similarity_set))
7024                                 {
7025                                 sim++;
7026                                 }
7027                         }
7028                 }
7029         if ( MODE==UNGAPED_POSITIONS)return ( sim*100)/pos;
7030         else if ( MODE==ALIGNED_POSITIONS)return (sim*100)/len;
7031         else if ( MODE==AVERAGE_POSITIONS)return (sim*200)/(nr1+nr2);
7032         else
7033           {
7034             return 0;
7035           }
7036         
7037         }
7038 float get_seq_fsim2 ( char *string1, char *string2, char *ignore, char *in_mode)
7039         {
7040         int len1;
7041         int a;
7042         int p1, p2;
7043         int r1=0,r2=0;
7044         char *p;
7045         char mode[1000];
7046         float r=0, pos1, pos2, pos0, gap, sim;
7047         
7048
7049         sprintf ( mode, "%s", in_mode);
7050         
7051         /*mode: <mat>__<sim_mode>
7052           mat: idscore to get the alignment done
7053                any legal cw matrix
7054           sim_mode: sim1->identities/matches
7055                     sim2->identities/min len     
7056         */
7057
7058                 
7059         if ( (p=strstr (mode, "_"))!=NULL)
7060           {
7061             p[0]='\0';
7062             p++;
7063           }
7064
7065                 
7066         if (strstr (mode, "idscore"))
7067           {
7068             static int **mat;
7069             if (!mat) mat=read_matrice ("blosum62mt");
7070             return idscore_pairseq (string1, string2, -12, -1, mat,mode);
7071             
7072           }
7073         
7074         len1=strlen (string1);
7075         for ( sim=pos1=pos2=pos0=gap=0,a=0; a< len1; a++)
7076                 {
7077                   r1=string1[a];
7078                   r2=string2[a];
7079                   p1=1-is_in_set (r1, ignore);
7080                   p2=1-is_in_set (r2, ignore);
7081                   pos1+=p1; pos2+=p2;
7082                   if (p1 && p2)
7083                         {
7084                           pos0++;
7085                           if (is_in_same_group_aa(r1,r2,0, NULL, mode))
7086                             {                 
7087                               sim++;
7088                             }
7089                         }
7090                   else if (p1+p2==1)
7091                     {
7092                       gap++;
7093                     }
7094                 }
7095
7096         if ( p==NULL || strm (p, "sim1") || strm (p, "sim"))
7097           {
7098             r=(pos0==0)?0:(sim*MAXID)/pos0;
7099           }
7100         else if ( strm (p, "sim2"))
7101           {
7102             r=(pos1==0 || pos2==0)?0:(sim*MAXID)/MIN(pos1,pos2);
7103           }
7104         else if ( strm (p, "sim3"))
7105           {
7106             r=(pos1==0 || pos2==0)?0:(sim*MAXID)/MAX(pos1,pos2);
7107           }
7108         else if ( strm (p, "gap1"))
7109           {
7110             r=(len1==0)?MAXID:(gap*MAXID)/len1;
7111             r=MAXID-r;
7112           }
7113         else if ( strm (p, "logid"))
7114           {
7115             r=logid_score (pos0, sim);
7116           }
7117
7118         return r;
7119         
7120         }       
7121
7122 /********************************************************************/
7123 /*                                                                  */
7124 /*                   ALIGNMENT ANALYSES                             */
7125 /*                                                                  */
7126 /*                                                                  */
7127 /*                                                                  */
7128 /********************************************************************/
7129 int **dist_array2sim_array ( int **p, int max)
7130 {
7131   int s1, s2, a, b;
7132   s1=read_array_size ((void *)p, sizeof (void *));
7133   s2=read_array_size ((void*)p[0],sizeof (int));
7134   /*  s2=read_array_size ((void*)p[0],sizeof (void *)); OLD before 64 BITS*/
7135   for ( a=0; a< s1; a++)
7136     for ( b=0; b< s2; b++)
7137       {
7138         p[a][b]=max-p[a][b];
7139       } 
7140   return p;
7141 }
7142
7143 int **sim_array2dist_array ( int **p, int max)
7144 {
7145   int s1, s2, a, b;
7146   s1=read_array_size ((void *)p, sizeof (void *));
7147   s2=read_array_size ((void*)p[0],sizeof (int));
7148
7149   /*s2=read_array_size ((void*)p[0],sizeof (void *)); OLD before 64 Bits stuff*/ 
7150  for ( a=0; a< s1; a++)
7151     for ( b=0; b< s2; b++)
7152       {
7153         p[a][b]=max-(int)p[a][b];
7154       } 
7155   return p;
7156 }
7157
7158 int **normalize_array (int **p, int max, int norm)
7159 {
7160 int s1, s2, a, b;
7161  s1=read_array_size ((void *)p, sizeof (void *));
7162  s2=read_array_size ((void*)p[0],sizeof (int));
7163  
7164  /*s2=read_array_size ((void*)p[0],sizeof (void *)); OLD before 64 Bits stuff*/ 
7165  for ( a=0; a< s1; a++)
7166    for ( b=0; b< s2; b++)
7167      {
7168        p[a][b]=(p[a][b]*norm)/max;
7169       } 
7170  return p;
7171 }
7172
7173 int aln2most_similar_sequence ( Alignment *A, char *mode)
7174 {
7175   int **w;
7176   int a, b;
7177   int avg, best_avg=0, best_seq=0;
7178   char *buf;
7179   int coverage;
7180
7181   
7182   if ( !A) return -1;
7183   else if ( A->nseq==1)return 0;
7184   else
7185     {
7186       buf=vcalloc ( A->len_aln+1, sizeof (char));
7187       w=get_sim_aln_array ( A, mode);
7188       
7189       for ( a=0; a< A->nseq; a++)
7190         {
7191           sprintf ( buf, "%s", A->seq_al[a]);
7192           ungap(buf);
7193           coverage=(strlen(buf)*MAXID)/A->len_aln;
7194           
7195           for ( avg=0,b=0; b< A->nseq; b++)avg+=w[a][b]*coverage;
7196           if ( avg>best_avg){best_avg=avg; best_seq=a;}
7197         }
7198       free_int (w, -1);
7199       vfree (buf);
7200       return best_seq;
7201     }
7202   
7203 }
7204
7205 int aln2coverage ( Alignment *A, int ref_seq)
7206 {
7207   int a,b;
7208   int cov_pos=0, npos=0;
7209
7210   
7211   for ( a=0; a< A->len_aln; a++)
7212     {
7213       if ( !is_gap ( A->seq_al[ref_seq][a]))
7214         {
7215           npos++;
7216           for ( b=0; b< A->nseq; b++)
7217             {
7218               if ( b!=ref_seq && !is_gap ( A->seq_al[b][a])){cov_pos++;break;}
7219             }
7220         }
7221     }
7222
7223   return  (int) (npos==0)?0:(( MAXID*cov_pos)/npos);
7224 }
7225  
7226
7227 int sub_aln2sim ( Alignment *A, int *ns, int **ls, char *mode)
7228 {
7229   int a, b, n;
7230   float avg;
7231
7232   n=0; avg=0;
7233   if (!A || (ns==NULL && A->nseq<2))return -1;
7234   else if (ns==NULL)
7235     {
7236       for (a=0; a< A->nseq-1; a++)
7237         for ( b=a+1; b< A->nseq;b++, n++)
7238           avg+=generic_get_seq_sim (A->seq_al[a], A->seq_al[b], NULL, mode);
7239     }
7240   else
7241     {
7242       for (a=0; a<ns[0]; a++)
7243         for (b=0; b< ns[1]; b++, n++)
7244           {
7245             avg+=generic_get_seq_sim (A->seq_al[ls[0][a]], A->seq_al[ls[1][b]], NULL, mode);
7246           }
7247     }
7248   return (int)(n==0)?0:((float)avg/(float)n);
7249 }
7250 int sub_aln2max_sim ( Alignment *A, int *ns, int **ls, char *mode)
7251 {
7252   int a, b, n;
7253   float avg;
7254
7255   n=0; avg=0;
7256   if (!A || (ns==NULL && A->nseq<2))return -1;
7257   else if (ns==NULL)
7258     {
7259       for (a=0; a< A->nseq-1; a++)
7260         for ( b=a+1; b< A->nseq;b++, n++)
7261           avg=MAX(avg,generic_get_seq_sim (A->seq_al[a], A->seq_al[b], NULL, mode));
7262     }
7263   else
7264     {
7265       for (a=0; a<ns[0]; a++)
7266         for (b=0; b< ns[1]; b++, n++)
7267           {
7268             avg=MAX(avg,generic_get_seq_sim (A->seq_al[ls[0][a]], A->seq_al[ls[1][b]], NULL, mode));
7269           }
7270     }
7271   return avg;
7272 }       
7273
7274
7275 double aln2entropy (Alignment *A, int *in_ls, int in_ns, float gap_threshold)
7276 {
7277   int ns, a, s, col, r,ncol;
7278   int *ls;
7279   double *count;
7280   double entropy=0;
7281   float ng;
7282     
7283   ls=vcalloc ( A->nseq, sizeof (int));
7284   count=vcalloc ( 26, sizeof (double));
7285   
7286   
7287   if ( in_ls)
7288     {
7289       ns=in_ns;
7290       for ( a=0; a< ns; a++)ls[a]=in_ls[a];
7291     }
7292   else 
7293     {
7294       ns=A->nseq;
7295       for ( a=0; a< ns; a++)ls[a]=a;
7296     }
7297   
7298   if ( ns==0)
7299     {
7300       vfree(ls);vfree(count);return 0;
7301     }
7302   for (ncol=0,col=0; col<A->len_aln; col++)
7303     {
7304       for (ng=0,a=0; a< ns; a++) 
7305         {
7306           s=ls[a];
7307           ng+=is_gap(A->seq_al[s][col]);
7308         }
7309       ng/=ns;
7310       if ( ng>gap_threshold)continue;
7311       
7312       ncol++;
7313       
7314       for ( a=0; a<ns; a++)
7315         {
7316           s=ls[a];
7317           r=tolower(A->seq_al[s][col]);
7318           if (!is_gap(r))count[r-'a']++;
7319         }
7320       for (a=0; a<26; a++)
7321         {
7322           if ( count[a]==0);
7323           else 
7324             {
7325               count[a]/=(double)ns;
7326               
7327               entropy+=count[a]*log(count[a]);
7328               count[a]=0;
7329             }
7330         }
7331     }
7332   entropy/=-ncol;
7333   vfree (ls); vfree(count);
7334   
7335   return entropy;
7336 }
7337 int aln2sim ( Alignment *A, char *mode)
7338 {
7339   return sub_aln2sim ( A, NULL, NULL, mode);
7340   /*
7341   if ( !A || A->nseq<2) return -1;
7342   w=get_sim_aln_array ( A, mode);
7343
7344   for (c=0, a=0; a< A->nseq-1; a++)
7345     for ( b=a+1; b< A->nseq; b++, c++)
7346       {
7347         avg+=(float)w[a][b];
7348       }
7349   free_int (w, -1);
7350   return (int)((float)avg/(float)c);
7351   */
7352 }
7353
7354 int aln_is_aligned ( Alignment *A)
7355 {
7356   int a, b;
7357   
7358   if ( !A)return 0;
7359   for (a=0; a< A->nseq; a++)
7360     for ( b=A->len_aln-1; b>0; b--)
7361       {
7362         if (!is_gap(A->seq_al[a][b]) && is_gap(A->seq_al[a][b-1]))return 1;
7363       }
7364   return 0;
7365 }
7366         
7367
7368 int seq2aln2sim_old ( char *seq1, char *seq2, char *mode_aln, char *mode_id)
7369 {
7370   Alignment *A;
7371   int sim;
7372
7373   A=align_two_sequences (seq1, seq2, "pam250mt", -10, -1, mode_aln);
7374   sim=aln2sim (A, mode_id);
7375   free_aln (A);
7376   return sim;
7377 }
7378 int seq2aln2sim ( char *seq1, char *seq2, char *mode_aln, char *mode_id)
7379 {
7380   Alignment *A;
7381   int sim;
7382   static int gop;
7383   
7384   if (!gop)
7385     {
7386       int **m;
7387       m=read_matrice ("blosum62mt");
7388       gop=get_avg_matrix_mm(m, AA_ALPHABET)*10;
7389       free_int (m, -1);
7390     }
7391   
7392   A=align_two_sequences (seq1, seq2, "blosum62mt",gop,-1, mode_aln);
7393   sim=aln2sim (A, mode_id);
7394   free_aln (A);
7395   return sim;
7396 }
7397 int* get_cdna_seq_winsim ( int *cache, char *string1, char *string2, char *ignore, char *mode,int *w )
7398         {
7399         int len1, len2;
7400         int a, x;
7401
7402         
7403         len1=strlen (string1);
7404         len2=strlen (string2);
7405                 
7406         if ( len1!=len2)
7407           {
7408             fatal_exit( stderr,EXIT_FAILURE, "\nTHE TWO cDNAs DO NOT HAVE THE SAME LENGTH [FATAL:get_cdna_seq_sim:%s", PROGRAM);
7409           }
7410         
7411         x=get_cdna_seq_sim(cache, string1, string2, ignore, "");
7412         for ( a=0; a< len1; a++)
7413           w[a]=x;
7414
7415         add_warning (stderr, "\nWARNING: winsim not implemented for cDNA");
7416         return w;
7417         }
7418
7419 int get_cdna_seq_sim ( int *cache, char *string1, char *string2, char *ignore, char *mode)
7420         {
7421         int len1;
7422         int len2;
7423         int a;
7424         int pos=0;
7425         int sim=0;
7426         char r1=0, r2=0;
7427         
7428         len1=strlen (string1);
7429         len2=strlen (string2);
7430
7431
7432         
7433         if ( len1!=len2)
7434           {
7435             fprintf ( stderr, "\nTHE TWO cDNAs DO NOT HAVE THE SAME LENGTH [FATAL:get_cdna_seq_sim:%s", PROGRAM);
7436             crash("");
7437           }
7438             
7439         for ( a=0; a< len1;)
7440                 {
7441                  
7442                   if ( cache[a]==0){a++;continue;}
7443                   else if ( cache[a]==1)
7444                     {
7445                       
7446                       r1=translate_dna_codon (string1+a, 'x');
7447                       r2=translate_dna_codon (string2+a, 'x');
7448                       a+=3;
7449                     }
7450                   
7451                   if ( !is_in_set (r1, ignore) && !is_in_set (r2, ignore))
7452                         {
7453                         pos++;
7454                         if (is_in_same_group_aa(r1,r2,0, NULL,mode+4))
7455                                 {
7456                                 sim++;
7457                                 }
7458                         }
7459                 }
7460
7461
7462
7463         if (pos==0)
7464                  return 0;
7465         else    
7466                 return (int) (sim*MAXID)/pos;
7467         
7468         }       
7469
7470 int* get_seq_winsim ( char *string1, char *string2, char *ignore, char *mode, int*w)
7471         {
7472         int len1, len2, len;
7473         int left, right;
7474         int a,b;
7475         int sim=0;
7476         int window;
7477         int r1, r2;
7478
7479         len1=strlen (string1);
7480         len2=strlen (string2);
7481         window=atoi(mode);
7482         len=2*window+1;
7483         
7484         if ( len1!=len2)return 0;
7485         if (window==0 || (window*2+1)>=len1)
7486           {
7487             sim=get_seq_sim (string1, string2, ignore, "");
7488             for (a=0; a<len1; a++)w[a]=sim;
7489             return w;
7490           }
7491         
7492
7493         for ( a=0; a< len1; a++)
7494                 {
7495                   
7496                   left =MAX(0, a-window);
7497                   right=MIN(len1, left+len);
7498                   for (sim=0,b=left; b<right; b++)
7499                     {
7500                       r1=string1[b];
7501                       r2=string2[b];
7502                       if (  !is_in_set (r1, ignore) && !is_in_set (r2, ignore))
7503                         {
7504                           if (r1==r2)sim++;
7505                         }
7506                     }
7507                   w[a]=(sim*MAXID)/len;
7508                 }
7509         return w;
7510         }
7511
7512
7513 int get_seq_sim ( char *string1, char *string2, char *ignore, char *in_mode)
7514         {
7515         int len1;
7516         int a;
7517         int pos1, pos2, pos0,gap=0, sim;
7518         int p1, p2;
7519         int r=0,r1=0,r2=0;
7520         char *p;
7521         static char *mode;
7522         
7523         if (!mode)mode=vcalloc (100, sizeof (char));
7524         else mode[0]='\0';
7525         if (in_mode)
7526           {
7527             while (in_mode[0]=='_')in_mode++;
7528             sprintf ( mode, "%s", in_mode);
7529           }
7530         
7531         /*mode: <mat>__<sim_mode>
7532           mat: idscore to get the alignment done
7533                any legal cw matrix
7534           sim_mode: sim1->identities/matches
7535                     sim2->identities/min len     
7536         */
7537
7538         
7539         if ( (p=strstr (mode, "_"))!=NULL)
7540           {
7541             p[0]='\0';
7542             p++;
7543           }
7544
7545             
7546         if (strstr (mode, "idscore"))
7547           {
7548             static int **mat;
7549             if (!mat) mat=read_matrice ("blosum62mt");
7550             return idscore_pairseq (string1, string2, -12, -1, mat,mode);
7551             
7552           }
7553         len1=strlen (string1);
7554         for ( sim=pos1=pos2=pos0=0,a=0; a< len1; a++)
7555                 {
7556                   r1=string1[a];
7557                   r2=string2[a];
7558                   p1=1-is_in_set (r1, ignore);
7559                   p2=1-is_in_set (r2, ignore);
7560                   
7561                   pos1+=p1; pos2+=p2;
7562                   if (p1 && p2)
7563                         {
7564                           pos0++;
7565                           if (is_in_same_group_aa(r1,r2,0, NULL, mode))
7566                             {                 
7567                               sim++;
7568                             }
7569                         }
7570                   else if (p1+p2==1)
7571                     {
7572                       gap++;
7573                     }
7574                 }
7575         
7576         if ( strstr (mode, "cov"))
7577           {
7578             r=(pos0+gap==0)?0:(pos0*MAXID)/(pos0+gap);
7579           }
7580         else if ( p==NULL || strm (p, "sim1") || strm (p, "sim"))
7581           {
7582             r=(pos0==0)?0:(sim*MAXID)/pos0;
7583           }
7584         else if ( strm (p, "sim2"))
7585           {
7586             r=(pos1==0 || pos2==0)?0:(sim*MAXID)/MIN(pos1,pos2);
7587           }
7588         else if ( strm (p, "sim3"))
7589           {
7590             r=(pos1==0 || pos2==0)?0:(sim*MAXID)/MAX(pos1,pos2);
7591           }
7592         else if ( strm (p, "gap1"))
7593           {
7594             r=(len1==0)?MAXID:(gap*MAXID)/len1;
7595             r=MAXID-r;
7596           }
7597         else if ( strm (p, "logid"))
7598           {
7599             r=logid_score (pos0, sim);
7600           }
7601         else if ( strstr (mode, "sim"))
7602           {
7603             r=(pos0==0)?0:(sim*MAXID)/pos0;
7604           }
7605
7606         
7607         return r;
7608         
7609         }       
7610 int get_seq_sim_2 ( char *string1, char *string2, char *ignore, char **gr, int ng)
7611         {
7612         int len1;
7613         int len2;
7614         int a;
7615         int pos=0;
7616         int sim=0;
7617         char r1, r2;
7618         
7619         
7620         len1=strlen (string1);
7621         len2=strlen (string2);
7622         
7623         if ( len1!=len2)return 0;
7624         
7625         for ( a=0; a< len1; a++)
7626                 {
7627                 r1=string1[a];
7628                 r2=string2[a];
7629                 if ( !is_in_set (r1, ignore) && !is_in_set (r2, ignore))
7630                         {
7631                         pos++;
7632                         if (is_in_same_group_aa(r1,r2,ng, gr, NULL))
7633                                 {
7634                                 sim++;
7635                                 }
7636                         }
7637                 }
7638         
7639         if (pos==0)
7640                  return 0;
7641         else    
7642                 return (int) (sim*MAXID)/pos;
7643         
7644         }
7645
7646 int get_seq_sim_3 ( char *string1, char *string2, char *ignore, int **mat)
7647         {
7648         int len1;
7649         int len2;
7650         int a;
7651         
7652         int sim=0;
7653         char r1, r2;
7654         
7655         
7656         len1=strlen (string1);
7657         len2=strlen (string2);
7658         
7659         if ( len1!=len2)return 0;
7660         
7661         for ( a=0; a< len1; a++)
7662                 {
7663                 r1=string1[a];
7664                 r2=string2[a];
7665                 if ( !is_in_set (r1, ignore) && !is_in_set (r2, ignore))
7666                         {
7667                         sim+=mat[r1-'A'][r2-'A'];
7668                         }
7669                 }
7670         return sim;
7671         
7672         }       
7673 int * get_aln_col_weight ( Alignment *A, char *mode)
7674         {
7675         int a, b;
7676         char *col;
7677         int *weight;
7678         
7679         col=vcalloc ( A->nseq, sizeof (int));
7680         weight=vcalloc (A->len_aln, sizeof (int));
7681         
7682         for (a=0; a< A->len_aln; a++)
7683                 {
7684                 for ( b=0; b< A->nseq; b++)
7685                         col[b]=A->seq_al[b][a];
7686                 weight[a]=(find_group_aa_distribution (col, A->nseq,0,NULL,NULL, mode )*MAXID)/A->nseq;          
7687                 }
7688         vfree (col);
7689         return weight;
7690         
7691         }       
7692                         
7693 int analyse_aln_column ( Alignment *B, int col)
7694     {
7695
7696     char r=' ';
7697     int a, b, c=0;
7698     static char *mat;
7699     static int ng_cw_star;
7700     static char **cw_star;
7701     int *cw_star_count;
7702     
7703     static int ng_cw_col;
7704     static char **cw_col;
7705     int *cw_col_count;
7706     
7707     static int ng_cw_dot;
7708     static char **cw_dot;
7709     int *cw_dot_count;
7710     
7711
7712
7713
7714     
7715     
7716     if ( !B->S || !(B->S)->type)B= get_aln_type (B);
7717     
7718     if ( !mat)mat=vcalloc ( STRING, sizeof (char));
7719
7720     if ( !ng_cw_star)
7721        {
7722            cw_star=make_group_aa ( &ng_cw_star, strcpy ( mat,"idmat"));
7723            cw_col=make_group_aa ( &ng_cw_col, strcpy (mat,"clustalw_col"));
7724            cw_dot=make_group_aa ( &ng_cw_dot, strcpy (mat, "clustalw_dot"));
7725        }
7726
7727     cw_star_count=vcalloc (ng_cw_star, sizeof (int));
7728     cw_col_count=vcalloc ( ng_cw_col, sizeof (int));
7729     cw_dot_count=vcalloc (ng_cw_dot, sizeof (int));
7730     
7731     for ( a=0; a< B->nseq; a++)
7732         {
7733         c=tolower (B->seq_al[a][col]);
7734         if (is_gap(c)){r=' ';break;}
7735           
7736         for ( b=0; b< ng_cw_star; b++)
7737             cw_star_count[b]+=is_in_set (c, cw_star[b]);        
7738         for ( b=0; b< ng_cw_col; b++)
7739             cw_col_count[b]+=is_in_set  (c, cw_col[b]);
7740         for ( b=0; b< ng_cw_dot; b++)
7741             cw_dot_count[b]+=is_in_set  (c, cw_dot[b]);
7742         }
7743     
7744    
7745    
7746    
7747     
7748     if ( !is_gap(c) && r==' ')
7749         for ( b=0; b< ng_cw_star; b++)if ( cw_star_count[b]==B->nseq){r='*'; break;}
7750     if ( !is_gap(c) && r==' ' && !(strm((B->S)->type, "DNA")||strm ((B->S)->type,"RNA")))
7751         for ( b=0; b< ng_cw_col ; b++)if ( cw_col_count [b]==B->nseq){r=':'; break;}
7752     if ( !is_gap(c) && r==' ' && !(strm((B->S)->type, "DNA")||strm ((B->S)->type,"RNA")))
7753         for ( b=0; b< ng_cw_dot ; b++)if ( cw_dot_count [b]==B->nseq){r='.'; break;}
7754     
7755     
7756     
7757     vfree(cw_star_count);
7758     vfree(cw_col_count);
7759     vfree(cw_dot_count);   
7760         
7761     return r;
7762     }
7763
7764
7765 int ** get_cov_aln_array ( Alignment *A, char *mode)
7766 {
7767   int **w;
7768   int a, b, c, t;
7769   
7770   w=declare_int ( A->nseq, A->nseq);
7771   
7772   
7773   for ( a=0; a< A->nseq-1; a++)
7774     {
7775       w[a][a]=100;
7776       for ( t=0,b=a+1; b< A->nseq; b++)
7777         {
7778           for ( c=0; c< A->len_aln; c++)
7779             {
7780               t+=(!is_gap(A->seq_al[a][c]) &&!is_gap(A->seq_al[b][c]));
7781             }
7782           w[a][b]=w[b][a]=(t*100)/A->len_aln;
7783         }
7784     }
7785   return w;
7786 }
7787
7788 int ** get_cov_master_aln_array ( Alignment *A,int n, char *mode)
7789 {
7790   int **w;
7791   int    b, c, t;
7792   
7793   w=declare_int ( A->nseq, A->nseq);
7794   
7795   
7796   for (b=0; b< A->nseq; b++)
7797         {
7798           
7799           for (t=0, c=0; c< A->len_aln; c++)
7800             {
7801               t+=(!is_gap(A->seq_al[n][c]) &&!is_gap(A->seq_al[n][c]));
7802             }
7803           w[n][b]=w[b][n]=(t*100)/A->len_aln;
7804         }
7805     
7806   return w;
7807 }
7808 int ** get_sim_master_aln_array ( Alignment *A,int n, char *mode)
7809         {
7810         int **w;
7811         int a;
7812         
7813         w=declare_int ( A->nseq, A->nseq);
7814         
7815         
7816         for ( a=0; a< A->nseq; a++)
7817           {
7818             if ( strm (mode, "cdna"))
7819             w[n][a]=w[a][n]=get_cdna_seq_sim ( A->cdna_cache[0], A->seq_al[a], A->seq_al[n],GAP_LIST, mode);                    
7820           else
7821             w[n][a]=w[a][n]=get_seq_sim ( A->seq_al[n], A->seq_al[a],GAP_LIST, mode);
7822           }
7823         return w;
7824         }
7825 int ** get_dist_aln_array ( Alignment *A, char *mode)
7826 {
7827   
7828   int **w;
7829
7830   w=get_sim_aln_array ( A, mode);
7831   return sim_array2dist_array(w,MAXID);
7832 }
7833 Sequence * seq2filter (Sequence *Sin, int min, int max)
7834 {
7835   int *keep;
7836   char *tmpfile;
7837   Sequence *S, *Sout;
7838   int a, b, sim;
7839   int **M;
7840   FILE *fp;
7841   int n;
7842
7843   S=duplicate_sequence (Sin);
7844   for (a=0; a<S->nseq; a++)ungap(S->seq[a]);
7845   keep=vcalloc (S->nseq, sizeof (int));
7846   M=read_matrice ("blossum62mt");
7847   for (a=0; a<S->nseq; a++)
7848     {
7849       output_completion ( stderr, a, S->nseq, 100, "Distance Matrix Computation: ");
7850       for ( b=a+1; b<S->nseq; b++)
7851         {
7852           
7853           sim=idscore_pairseq(S->seq[a], S->seq[b],-10, -2,M, "sim");
7854           if ( sim>min && sim<max)keep[a]=keep[b]=1;
7855           fprintf ( stderr, "\nSim %d Min %d Max %d", sim, min, max);
7856         }
7857     }
7858
7859   tmpfile=vtmpnam (NULL);
7860   fp=vfopen (tmpfile, "w");
7861   for (n=0,a=0; a< S->nseq; a++)
7862     if ( keep[a]) 
7863       {
7864       fprintf ( fp, ">%s %s\n%s", S->name[a], S->seq_comment[a], S->seq[a]);
7865       n++;
7866       }
7867   vfclose (fp);
7868   if (n==0) return NULL;
7869   Sout=main_read_seq(tmpfile);
7870   free_int (M, -1); vfree (keep); free_sequence (S, -1);
7871   return Sout;
7872 }
7873
7874 Alignment * grep_seq (Alignment *S,char *field, char *mode, char *string)
7875 {
7876   int a;
7877   FILE *fp;
7878   char *tmp;
7879   int n=0;
7880   
7881   tmp=vtmpnam (NULL);
7882   fp=vfopen (tmp, "w");
7883   
7884   if ( !strm(mode, "KEEP") && ! strm (mode, "REMOVE"))
7885     {
7886       add_warning ( stderr, "\nERROR: +grep <field> <KEEP|REMOVE> <string> [FATAL: %s]", PROGRAM);
7887       myexit (EXIT_FAILURE);
7888     }
7889   else if ( !strm(field, "SEQ") && ! strm (field, "COMMENT") && ! strm(field, "NAME"))
7890     {
7891       add_warning ( stderr, "\nERROR: +grep <NAME|COMMENT|SEQ> <mode> <string> [FATAL: %s]", PROGRAM);
7892       myexit (EXIT_FAILURE);
7893     }
7894   
7895
7896   for (n=0, a=0; a< S->nseq; a++)
7897     {
7898       int found=0;
7899
7900       if (strm(field, "NAME") && perl_strstr (S->name[a], string))found=1;
7901       else if (strm(field, "COMMENT") && S->seq_comment[a][0] && perl_strstr (S->seq_comment[a], string) )found=1;
7902       else if (strm(field, "SEQ") && perl_strstr (S->seq_al[a], string))found=1;
7903       
7904       if ( (strm (mode, "KEEP") && found) || (strm (mode, "REMOVE") && !found))
7905         {
7906           n++;
7907           fprintf (fp, ">%s", S->name[a]);
7908           if (S->seq_comment[a][0])fprintf (fp, " %s", S->seq_comment[a]);
7909           fprintf (fp, "\n%s\n", S->seq_al[a]);
7910         }
7911     }
7912   
7913   vfclose (fp);
7914   
7915   free_aln (S);
7916   if ( n==0) return NULL;
7917   else
7918     return main_read_aln (tmp, NULL);
7919 }
7920
7921 Alignment * modify_seq (Alignment *S, char *field, char *string1, char *string2)
7922 {
7923   int a;
7924   FILE *fp;
7925   char *tmp;
7926
7927   tmp=vtmpnam (NULL);
7928   fp=vfopen (tmp, "w");
7929   for ( a=0; a< S->nseq; a++)
7930     {
7931       if (strm(field, "NAME"))S->name[a]=substitute ( S->name[a], string1, string2); 
7932       else if (strm(field, "COMMENT"))S->seq_comment[a]=substitute ( S->seq_comment[a], string1, string2); 
7933       else if (strm(field, "SEQ"))S->seq_al[a]=substitute ( S->seq_al[a], string1, string2);
7934       fprintf (fp, ">%s", S->name[a]);
7935       if (S->aln_comment[a][0])fprintf (fp, " %s", S->aln_comment[a]);
7936       fprintf (fp, "\n%s\n", S->seq_al[a]);
7937     }
7938   vfclose (fp);
7939   free_aln (S);
7940   S=main_read_aln (tmp, NULL);
7941   return S;
7942 }
7943
7944 int ** seq2sim_mat (Sequence *S, char *mode)
7945 {
7946   return seq2comp_mat ( S,mode, "sim");
7947 }
7948 int ** seq2cov_mat (Sequence *S, char *mode)
7949 {
7950   return seq2comp_mat ( S,mode, "cov");
7951 }
7952
7953 int ** seq2comp_mat (Sequence *S, char *mode, char *comp_mode)
7954 {
7955   int a, b;
7956   int **sim;
7957   char file[1000];
7958   Alignment *A;
7959   char *name;
7960
7961   
7962   /*Use pre_computed value if available in the current dir*/
7963
7964   name=path2filename(S->file[0]);
7965   sprintf ( file, "%s%s.%s.%s_file", get_cache_dir(),name, mode, comp_mode);
7966   A=seq2aln(S,NULL, RM_GAP);
7967   if ( check_file_exists (file) && is_distance_matrix_file (file) && (sim=input_similarities(file, A, NULL))!=NULL)
7968     {
7969       display_input_filename (stderr, "SIMILARITY_MATRIX", "SIMILARITY_MATRIX_FORMAT_01", file, CHECK);
7970       fprintf ( stderr, "\n");
7971     }
7972   else
7973     {
7974       char mode2[1000];
7975       int **M;
7976       
7977       M=read_matrice (mode);
7978       sim=declare_int ( S->nseq, S->nseq);
7979       for ( a=0; a< S->nseq; a++)
7980         {
7981           ungap (S->seq[a]);
7982           sim[a][a]=100;
7983         }
7984
7985       for ( a=0; a<S->nseq-1; a++)
7986         {
7987           
7988           output_completion4halfmat ( stderr, a, S->nseq, 100, "Similarity Matrix Computation: ");
7989           for ( b=a+1; b< S->nseq; b++)
7990             {
7991               sim[a][b]=sim[b][a]=idscore_pairseq(S->seq[a], S->seq[b],-12, -1,M, comp_mode);
7992             }
7993         }
7994       free_int (M,-1);
7995       sprintf ( mode2, "_memory_%ld", (long int)sim);
7996       output_similarities( file, A, mode2);
7997       display_output_filename (stderr, "SIMILARITY_MATRIX", "SIMILARITY_MATRIX_FORMAT_01", file, CHECK);
7998       fprintf ( stderr, "\n");
7999     }
8000   free_aln (A);
8001   return sim;
8002 }
8003
8004 int ** fast_aln2sim_list (Alignment *A,  char *mode, int *ns, int **ls)
8005 {
8006   int **simm;
8007   int p1, p2, p3, r1, r2;
8008   int gap,pos0,pos1,pos2,len,sim;
8009   int a, b, c, m, s=0,s1, s2, n;
8010   int free_ns=0;
8011
8012   if (ns==NULL)
8013     {
8014       free_ns=1;
8015       ns=vcalloc (2, sizeof (int));
8016       ns[0]=ns[1]=A->nseq;
8017       ls=declare_int (2, A->nseq);
8018       for ( a=0; a< 2; a++)
8019         for (b=0; b<A->nseq; b++)
8020           ls[a][b]=b;
8021     }
8022   
8023
8024   simm=declare_int (ns[0]*ns[1]+1, 3);
8025   
8026   if (strstr (mode, "sim1"))m=0;
8027   else if (strstr (mode, "sim2"))m=1;
8028   else if (strstr (mode, "sim3"))m=2;
8029   else if (strstr (mode, "gap1"))m=3;
8030   else if (strstr (mode, "cov1"))m=4;
8031   else if (strstr (mode, "logid"))m=5;
8032   else m=0;
8033   
8034   
8035
8036   for (n=0,a=0; a<ns[0]; a++)
8037     {
8038       s1=ls[0][a];
8039       for ( b=0; b<ns[1]; b++, n++)
8040         {
8041           s2=ls[1][b];
8042           gap=pos0=pos1=pos2=len=sim=0;
8043           
8044           for ( c=0; c< A->len_aln; c++)
8045             {
8046               r1=tolower (A->seq_al[s1][c]);
8047               r2=tolower (A->seq_al[s2][c]);
8048               p1=(r1!='-')?1:0;
8049               p2=(r2!='-')?1:0;
8050               p3=p1+p2;
8051               if ( p3==0)continue;
8052               if ( p3==1)gap++;
8053               if ( r1==r2)sim++;
8054               pos1+=p1;
8055               pos2+=p2;
8056               pos0+=(p3==2)?1:0;
8057               len++;
8058             }
8059
8060           if (m==0)s=(pos0==0)?0:(sim*MAXID)/pos0; //sim1
8061           else if (m==1)  s=(MIN(pos1,pos2)==0)?0:(sim*MAXID)/MIN(pos1,pos2);//sim2
8062           else if (m==2)  s=(MAX(pos1,pos2)==0)?0:(sim*MAXID)/MAX(pos1,pos2);//sim3
8063           else if (m==3)  s=(len==0) ?0:((len-gap)*MAXID)/len;//gap1
8064           else if (m==4)  s=(len==0) ?0:((pos0)*MAXID)/len; //cov
8065           else if (m==5)   
8066             {
8067               s=logid_score ( sim, len);
8068             }
8069           simm[n][0]=s1;
8070           simm[n][1]=s2;
8071           simm[n][2]=s;
8072         }
8073     }
8074
8075   if ( free_ns) {vfree(ns); free_int (ls, -1);}
8076   simm[n][0]=-1;
8077   return simm;
8078 }
8079
8080 int ** fast_aln2sim_mat (Alignment *A,  char *mode)
8081 {
8082   int **simm;
8083   int p1, p2, p3, r1, r2;
8084   int gap,pos0,pos1,pos2,len,sim;
8085   int a, b, c, m;
8086   
8087   simm=declare_int (A->nseq, A->nseq);
8088
8089
8090   
8091   if (strstr (mode, "sim1"))m=0;
8092   else if (strstr (mode, "sim2"))m=1;
8093   else if (strstr (mode, "sim3"))m=2;
8094   else if (strstr (mode, "gap1"))m=3;
8095   else if (strstr (mode, "cov1"))m=4;
8096   else if (strstr (mode, "logid"))m=5;
8097   else m=0;
8098   
8099   
8100   
8101   for ( a=0; a< A->nseq-1; a++)
8102     {
8103       simm[a][a]=MAXID;
8104       for ( b=a+1; b< A->nseq; b++)
8105         {
8106           gap=pos0=pos1=pos2=len=sim=0;
8107           
8108           for ( c=0; c< A->len_aln; c++)
8109             {
8110               r1=tolower (A->seq_al[a][c]);
8111               r2=tolower (A->seq_al[b][c]);
8112               p1=(r1!='-')?1:0;
8113               p2=(r2!='-')?1:0;
8114               p3=p1+p2;
8115               if ( p3==0)continue;
8116               if ( p3==1)gap++;
8117               if ( r1==r2)sim++;
8118               pos1+=p1;
8119               pos2+=p2;
8120               pos0+=(p3==2)?1:0;
8121               len++;
8122             }
8123
8124           if (m==0)simm[a][b]=simm[b][a]=(pos0==0)?0:(sim*MAXID)/pos0; //sim1
8125           else if (m==1)  simm[a][b]=simm[b][a]=(MIN(pos1,pos2)==0)?0:(sim*MAXID)/MIN(pos1,pos2);//sim2
8126           else if (m==2)   simm[a][b]=simm[b][a]=(MAX(pos1,pos2)==0)?0:(sim*MAXID)/MAX(pos1,pos2);//sim3
8127           else if (m==3)   simm[a][b]=simm[b][a]=(len==0) ?0:((len-gap)*MAXID)/len;//gap1
8128           else if (m==4)   simm[a][b]=simm[b][a]=(len==0) ?0:((pos0)*MAXID)/len; //cov
8129           else if (m==5)   
8130             {
8131               
8132               //Inspired from Muscle +mafft 5
8133               simm[a][b]=simm[b][a]=logid_score ( sim, len);
8134             }
8135         }
8136     }
8137   return simm;
8138 }
8139 int logid_score ( int sim, int len)
8140 {
8141   float score;
8142   
8143   if ( len==0)return (int)(0.33*(float)MAXID);
8144   
8145   score=(float)sim/(float)len;
8146   if (score>0.9) score=1.0;
8147   else score=-log10 (1.0-score);
8148   
8149   score=(score*MAXID);
8150   return score;
8151 }
8152 int ** aln2sim_mat (Alignment *A, char*mode)
8153 {
8154  
8155  
8156   if ( strstr (mode, "idmat"))return fast_aln2sim_mat(A, mode);
8157   return get_sim_aln_array(A, mode);
8158 }
8159 int ** aln2cov (Alignment *A)
8160 {
8161   int a, b, c;
8162   int r1, r2, gr1, gr2, pos0, gap;
8163   int **cov;
8164   cov=declare_int (A->nseq, A->nseq);
8165   
8166   for (a=0; a< A->nseq-1; a++)
8167     {
8168       cov[a][a]=100;
8169       for ( b=a+1; b<A->nseq; b++)
8170         {
8171           for (gap=0,pos0=0,c=0;c<A->len_aln; c++)
8172             {
8173               r1=A->seq_al[a][c];
8174               r2=A->seq_al[b][c];
8175               gr1=is_gap(r1); gr2=is_gap(r2);
8176               if ( gr1+gr2==0)pos0++;
8177               else if ( gr1+gr2<2)gap++;
8178             }
8179           cov[a][b]=cov[b][a]=((gap+pos0)==0)?0:((pos0*100)/(gap+pos0));
8180         }
8181     }
8182   return cov;
8183 }
8184 int ** get_raw_sim_aln_array (Alignment *A, char *mode)
8185 {
8186   int **w;
8187   int **M;
8188   int a, b, c, r1, r2, set, max, min;
8189   
8190   w=declare_int (A->nseq, A->nseq);
8191   if (strstr(mode, "sar"))M=NULL;
8192   else M=read_matrice (mode);
8193   
8194   HERE ("RAW STUFF");
8195   
8196   for ( set=0,a=0; a< A->nseq; a++)
8197     for (b=a; b<A->nseq; b++)
8198       {
8199         if (M)
8200           {
8201             for (c=0; c<A->len_aln; c++)
8202               {
8203                 r1=A->seq_al[a][c];
8204                 r2=A->seq_al[b][c];
8205                 
8206                 if ( !is_gap(r1) && !is_gap(r2))
8207                   w[a][b]+=M[r1-'A'][r2-'A'];
8208               }
8209           }
8210         else if ( strm (mode, "sarmat2"))
8211           {
8212             w[a][b]=get_sar_sim2 (A->seq_al[a], A->seq_al[b]);
8213           }
8214         else
8215           {
8216             HERE ("ERROR: %s is an unknown mode of raw_sim\n", mode); myexit (EXIT_FAILURE);
8217           }
8218         
8219         w[b][a]=w[a][b];
8220         if (!set){min=max=w[a][b];set=1;}
8221         min=MIN(min,w[a][b]);
8222         max=MAX(max,w[a][b]);
8223       }
8224   for (a=0; a<A->nseq; a++)
8225     for (b=a; b<A->nseq; b++)
8226       {
8227         w[b][a]=((max-min)==0)?0:((w[b][a]-min)*100)/(max-min);
8228         w[a][b]=w[b][a];
8229       }
8230   free_int (M, -1);
8231   return w;
8232 }
8233 int ** get_sim_aln_array ( Alignment *A, char *mode)
8234         {
8235         int **w;
8236         int a, b;
8237         
8238
8239         w=declare_int ( A->nseq, A->nseq);
8240         
8241         for ( a=0; a< A->nseq-1; a++)
8242           {
8243             for ( b=a+1; b< A->nseq; b++)
8244               {
8245
8246                 w[a][b]=w[b][a]=generic_get_seq_sim ( A->seq_al[a], A->seq_al[b], (A->cdna_cache)?A->cdna_cache[0]:NULL, mode);
8247               }
8248           }
8249         return w;
8250         }
8251 int generic_get_seq_sim ( char *seq1, char *seq2, int*cache, char *mode)
8252 {
8253
8254   
8255    if ( strm (mode, "cdna"))
8256      return get_cdna_seq_sim ( cache, seq1, seq2,GAP_LIST, mode);                       
8257    else if ( strnm (mode, "ktup",4))
8258      return ktup_comparison (seq1, seq2,atoi(mode+4));
8259    else if ( strstr (mode, "sarmat2"))
8260      {
8261        
8262        return get_sar_sim2 (seq1, seq2);
8263      }
8264    else if ( strstr (mode, "sarmat"))
8265      return (int) get_sar_sim (seq1,seq2);
8266    else
8267      {
8268        return get_seq_sim ( seq1,seq2,GAP_LIST, mode);
8269      }
8270 }
8271 int *** get_winsim_aln_array ( Alignment *A,char *mode, int ***w)
8272         {
8273         int a, b;
8274         for ( a=0; a< A->nseq; a++)
8275                 for ( b=0; b< A->nseq; b++)
8276                         {
8277                           if ( strm (mode, "cdna"))
8278                             w[a][b]=get_cdna_seq_winsim ( A->cdna_cache[0], A->seq_al[a], A->seq_al[b],GAP_LIST, mode, w[a][b]);                        
8279                           else
8280                             w[a][b]=get_seq_winsim ( A->seq_al[a], A->seq_al[b],GAP_LIST, mode, w[a][b]);
8281                         }
8282         return w;
8283         }
8284
8285 Alignment * seq2profile (Sequence *S, int i)
8286 {
8287   Alignment *A;
8288   
8289   if ((A=seq2R_template_profile (S, i)))
8290     {
8291       return A;
8292     }
8293   else
8294     {
8295       char *tmp;
8296       FILE *fp;
8297       tmp=vtmpnam (NULL);
8298       fp=vfopen ( tmp, "w");
8299       fprintf (fp, ">%s\n%s\n", S->name[i], S->seq[i]);
8300       vfclose (fp);
8301       
8302       (S->T[i])->R=fill_R_template (S->name[i], tmp, S);
8303       
8304       return  seq2R_template_profile (S, i);
8305     }
8306 }
8307 Alignment* remove_seq_from_aln (Alignment *A, char *seq)
8308 {
8309   int a, n;
8310   for (n=0,a=0; a<A->nseq; a++)
8311     {
8312       if ( strm (seq, A->name[a]))continue;
8313       else if ( n==a);
8314       else 
8315         {
8316           sprintf (A->name[n], "%s",A->name[a]);
8317           sprintf (A->seq_al[n], "%s",A->seq_al[a]);
8318           if (A->seq_comment[a])sprintf (A->seq_comment[n], "%s", A->seq_comment[a]);
8319           if (A->aln_comment[a])sprintf (A->aln_comment[n], "%s", A->aln_comment[a]);
8320           A->order[n][0]=A->order[a][0];
8321           A->order[n][1]=A->order[a][1];
8322         }
8323       n++;
8324     }
8325   A->nseq=n;
8326   return A;
8327 }
8328                    
8329
8330 Alignment* aln2sub_aln_file (Alignment *A, int n, char **string)
8331 {
8332   char ***list;
8333   int a;
8334
8335   list=vcalloc (A->nseq, sizeof (char***));
8336   if ( n==0)return A;
8337   else if (n>1)
8338     {
8339       int l;
8340       char *buf;
8341       
8342       for (l=0,a=0; a< n; a++)l+=strlen (string[a]);
8343       buf=vcalloc ( 2*n+l+1, sizeof (char));
8344       for (a=0; a< n; a++){buf=strcat (buf,string[a]), buf=strcat ( buf, " ");}     
8345       list[0]=string2list (buf);
8346       vfree (buf);
8347     }
8348   else if ( file_exists (NULL,string[0]))
8349     {
8350       list=read_group (string[0]);
8351
8352     }
8353   else
8354     {
8355       fprintf (stderr, "\nERROR: file <%s> does not exist [FATAL:%s]\n",string[0], PROGRAM);
8356       myexit (EXIT_FAILURE);
8357     }  
8358
8359   
8360   a=0;
8361   while (list[a])
8362     {
8363       int i, b;
8364       FILE *fp;
8365       n=atoi (list[a][0]);
8366       fp=vfopen (list[a][1], "w");
8367       for (b=2; b<n; b++)
8368         {
8369           i=name_is_in_list (list[a][b], A->name, A->nseq, MAXNAMES);
8370           if (n==3)ungap (A->seq_al[i]);
8371           fprintf (fp, ">%s\n%s\n", A->name[i], A->seq_al[i]);    
8372         }
8373       vfclose (fp);
8374       free_char (list[a], -1);
8375       a++;
8376     }
8377   vfree(list);
8378   return A;
8379 }
8380 Sequence *remove_empty_sequence (Sequence *S)
8381 {
8382   int a, b;
8383   char *c;
8384   Sequence *NS;
8385   
8386   c=vcalloc ( S->max_len+1, sizeof (char));
8387   
8388   for (a=0, b=0; a< S->nseq; a++)
8389     {
8390       sprintf ( c, "%s",S->seq[a]);
8391       ungap (c);
8392       if ( strlen (c)==0)
8393         {
8394           //vfree (S->seq[a]);
8395           S->seq[a]=NULL;
8396           add_warning ( stderr, "WARNING: Sequence %s does not contain any residue: automatically removed from the set [WARNING:%s]",S->name[a], PROGRAM);
8397         }
8398     }
8399   NS=duplicate_sequence (S);
8400   free_sequence (S, S->nseq);
8401   vfree (c);
8402   return NS;
8403 }
8404 Alignment* aln2sub_seq (Alignment *A, int n, char **string)
8405 {
8406   char ***list;
8407   int a;
8408   Sequence *S=NULL;
8409     
8410   list=vcalloc (A->nseq, sizeof (char***));
8411   if ( n==0)return A;
8412   else if (n>1)
8413     {
8414       int l;
8415       char *buf;
8416       
8417       for (l=0,a=0; a< n; a++)l+=strlen (string[a]);
8418       buf=vcalloc ( 2*n+l+1, sizeof (char));
8419       for (a=0; a< n; a++){buf=strcat (buf,string[a]), buf=strcat ( buf, " ");}     
8420       list[0]=string2list (buf);
8421       vfree (buf);
8422     }
8423   else if ( file_exists (NULL,string[0]))
8424     {
8425       list=read_group (string[0]);
8426
8427     }
8428   else
8429     {
8430       fprintf (stderr, "\nERROR: file <%s> does not exist [FATAL:%s]\n",string[0], PROGRAM);
8431       myexit (EXIT_FAILURE);
8432     }  
8433
8434  
8435   
8436   a=0;
8437   while (list[a])
8438     {
8439       int t;
8440       Alignment *B;
8441       Sequence *subS;
8442       
8443       
8444       B=main_read_aln (list[a][1], NULL);
8445       t=aln2most_similar_sequence(B, "idmat");
8446       subS=extract_one_seq(B->name[t],0,0,B,KEEP_NAME);
8447       S=add_sequence (subS,S,0);
8448       free_aln (B);free_sequence (subS, -1);
8449       vremove (list[a][1]);
8450       a++;
8451     }
8452   vfree(list);
8453   return seq2aln (S, NULL, RM_GAP);
8454 }
8455
8456 Alignment * aln2collapsed_aln (Alignment * A, int n, char **string)
8457 {
8458   Alignment *B;
8459   char ***list;
8460   char **list2;
8461   char *buf=NULL;
8462   FILE *fp;
8463   int a, b,c, ns, m, l;
8464   int *collapsed;
8465   
8466   list=vcalloc (A->nseq, sizeof (char***));
8467   ns=0;
8468   if ( n==0)return A;
8469   else if (n>1)
8470     {
8471       for (l=0,a=0; a< n; a++)l+=strlen (string[a]);
8472       buf=vcalloc ( 2*n+l+1, sizeof (char));
8473       for (a=0; a< n; a++){buf=strcat (buf,string[a]), buf=strcat ( buf, " ");}
8474      
8475       list[0]=string2list (buf);ns=1;
8476       
8477     }
8478   else if ( file_exists (NULL,string[0]))
8479     {
8480       /*Format: Fasta like, the name fo the group followed with the name of the sequences
8481         ><Group name> <First Seq> <second seq> ....
8482         Groups must NOT be overlaping
8483       */
8484       l=measure_longest_line_in_file (string[0])+1; 
8485       buf=vcalloc (l, sizeof (char));
8486       ns=0;
8487       fp=vfopen (string[0], "r");
8488       while ((c=fgetc(fp))!=EOF)
8489         {
8490           buf=fgets (buf,l-1, fp);
8491           if ( c=='>')list[ns++]=string2list (buf);
8492         }
8493       vfclose (fp);
8494     }
8495   else
8496     {
8497       fprintf (stderr, "\nERROR: file <%s> does not exist [FATAL:%s]\n",string[0], PROGRAM);
8498       myexit (EXIT_FAILURE);
8499     }
8500   
8501   vfree (buf); buf=NULL;
8502
8503   /*Identify lost sequences*/
8504   collapsed=vcalloc (A->nseq, sizeof (int));
8505   for ( a=0; a< ns; a++)
8506       {
8507         m=atoi (list[a][0]); 
8508         for (b=2; b<m ; b++)
8509           {
8510             c=name_is_in_list (list[a][b], A->name, A->nseq, MAXNAMES);
8511             if ( c>=0)collapsed[c]=1;
8512           }
8513       }
8514   for ( a=0; a< A->nseq; a++)
8515     {
8516       if ( collapsed[a]==0)
8517         {
8518           list[ns]=declare_char (3, MAXNAMES);
8519           sprintf ( list[ns][0], "3");
8520           sprintf ( list[ns][1], "%s", A->name[a]);
8521           sprintf ( list[ns][2], "%s", A->name[a]);
8522           ns++;
8523         }
8524     }
8525   vfree (collapsed);
8526   
8527   
8528   
8529
8530
8531   list2=declare_char (A->nseq, 100);
8532   /*1 Collapse the alignment*/
8533   for ( a=0; a< ns; a++)
8534     {
8535       sprintf ( list2[a], "%s", list[a][2]);
8536     }
8537    B=extract_sub_aln2 ( A, ns, list2);
8538   /*2 Rename the sequences*/
8539   for ( a=0; a< ns; a++)
8540     {
8541       sprintf ( B->name[a], "%s", list[a][1]);
8542     }
8543   /*replace sequence with consensus*/
8544   
8545   for ( a=0; a< ns; a++)
8546     {
8547       m=atoi (list[a][0]);
8548       for (c=0, b=2; b<m;c++, b++)
8549         {
8550           sprintf ( list2[c], "%s", list[a][b]);
8551         }
8552       buf=sub_aln2cons_seq_mat2 ( A,m-2,list2, "blosum62mt");
8553       sprintf (B->seq_al[a], "%s", buf);     
8554     }
8555   vfree (buf);
8556
8557   free_aln (A);
8558   B->S=aln2seq(B);
8559   return B;
8560 }
8561 Alignment * aln2profile (Alignment * A)
8562     {
8563       Alignment *B=NULL;
8564       char *cons;
8565       
8566       if (!A->P)
8567         {
8568           A->P=declare_profile (AA_ALPHABET,A->len_aln+1);
8569         }
8570       B=copy_aln (A, B);
8571       free_int ((A->P)->count, -1);
8572       free_int ((A->P)->count2, -1);
8573       free_int ((A->P)->count3, -1);
8574       (A->P)->count=aln2count_mat (A);
8575       (A->P)->count2=aln2count_mat2 (A);
8576       
8577       cons=aln2cons_seq_mat (A, "blosum62mt");
8578       
8579       sprintf (B->seq_al[0], "%s", cons);
8580       B->nseq=1;
8581       (A->P)->count3=aln2count_mat2 (B);
8582       vfree (cons);
8583       free_aln (B);
8584       
8585       
8586
8587       return A;
8588           
8589     }
8590
8591 int** aln2count_mat2 ( Alignment *A)
8592 {
8593   return sub_aln2count_mat2 (A, 0, NULL);
8594 }
8595
8596 int sub_aln2nseq_prf ( Alignment *A, int ns, int *ls)
8597 {
8598   
8599   
8600   int a, c, s;
8601   Alignment *R;
8602   int n;
8603   int free_ls=0;
8604   
8605   
8606   if ( ns==0)
8607     {
8608       n=ns=A->nseq;
8609       ls=vcalloc (n, sizeof (int));
8610       for ( a=0; a<A->nseq; a++)ls[a]=a;
8611       free_ls=1;
8612     }
8613   else
8614     {
8615       n=ns;
8616     }
8617
8618   for (c=0,a=0; a<ns; a++)
8619     {
8620       s=ls[a];
8621       if ( A->S && (R=seq2R_template_profile (A->S, A->order[s][0]))!=NULL)
8622         {
8623           n+=R->nseq;
8624         }
8625       else
8626         {
8627           ;
8628         }
8629     }
8630   
8631   if ( free_ls) vfree (ls);
8632   return n;
8633 }
8634
8635 int** sub_aln2count_mat2 ( Alignment *A, int ns, int *ls)
8636 {
8637   char **p;
8638   int **count;
8639   int a, b, c, s;
8640   Alignment *R;
8641   int n;
8642   int free_ls=0;
8643   
8644   if ( ns==0)
8645     {
8646       n=ns=A->nseq;
8647       p=vcalloc ( n, sizeof (char*));
8648       ls=vcalloc (n, sizeof (int));
8649       for ( a=0; a<A->nseq; a++)ls[a]=a;
8650       free_ls=1;
8651     }
8652   else
8653     {
8654       n=ns;
8655       p=vcalloc (n, sizeof (char*));
8656     }
8657
8658   for (c=0,a=0; a<ns; a++)
8659     {
8660       s=ls[a];
8661       if ( A->S && (R=seq2R_template_profile (A->S, A->order[s][0]))!=NULL)
8662         {
8663           n+=R->nseq;
8664           p=vrealloc (p, n*sizeof (char*));
8665           for (b=0; b<R->nseq; b++)
8666             {
8667               p[c++]=R->seq_al[b];
8668             }
8669         }
8670       else
8671         {
8672           int w;
8673           w=A->order[s][4]+1;
8674           
8675           for (b=0; b<w; b++)
8676             p[c++]=A->seq_al[s];
8677         }
8678     }
8679   count=sub_aln2count_mat3 (p,c);
8680   vfree (p);
8681   if ( free_ls) vfree (ls);
8682   return count;
8683 }
8684 int** sub_aln2count_mat3 (char **al, int ns)
8685 {
8686   int **count;
8687   int used[1000];
8688   int a, b;
8689   int r;
8690   
8691   int len;
8692   int us;
8693   
8694   
8695   /*count[x][0]=n symbols in column
8696     count[x][1]=total_size of line
8697     count[x][2]=Gap frequency
8698      
8699     count[x][n]=symbol n
8700     count[x][n+1]=N occurence symbol n;
8701     count[x][n+2]=N frequence symbol n*100;
8702  
8703     special multi-channeling
8704     count[x][count[x][1]]=Nseq
8705     count[x][count[x][1]+s]=residue col x, sequence s
8706   */
8707
8708
8709   for (a=0; a< 1000; a++)used[a]=0;
8710   len=strlen (al[0]);
8711   
8712   count=declare_int (len+2,100+ns+2);
8713   count[len][0]=END_ARRAY;
8714   count[len][1]=ns;
8715   count[len][2]=len;
8716   
8717
8718   
8719   for (a=0; a<len; a++)
8720     {
8721       for (us=ns, b=0; b<ns; b++)
8722         {
8723           r=tolower (al[b][a]);
8724           
8725           if (is_gap(r))us--;
8726           else if (used[r])
8727             {
8728               count[a][used[r]*3+1]++;
8729             }
8730           else
8731             {
8732               used[r]=++count[a][0];
8733               count[a][used[r]*3]=r;
8734               count[a][used[r]*3+1]++;
8735             }
8736         }
8737       count[a][1]=count[a][0]*3+2;
8738       /*count[a][2]=(A->nseq-us)*100/A->nseq;*/
8739       count[a][2]=ns-us;
8740       
8741       for (b=3; b<count[a][1]; b+=3)
8742         {
8743           count[a][b+2]=(count[a][b+1]*100)/us;
8744           used[count[a][b]]=0;
8745         }
8746
8747      
8748       /*Option for multi channeling*/
8749       
8750       /*
8751       count[a][count[a][1]]=A->nseq;
8752       for (b=1; b<=A->nseq; b++)
8753         count [a][count[a][1]+b]=(is_gap(A->seq_al[b-1][a]))?0:A->seq_al[b-1][a];
8754       */
8755     }
8756 #ifdef XXXXXX
8757   HERE ("Display ");
8758   for (a=0; a< 5; a++)
8759     {
8760       fprintf ( stderr, "\n");
8761       for ( b=3; b< count[a][1]; b+=3)
8762         {
8763           fprintf ( stderr, "[%c %d]", count[a][b], count[a][b+1]);
8764         }
8765       fprintf ( stderr, "\n");
8766       for ( b=0; b<ns; b++)
8767         {
8768           fprintf ( stderr, "%c", al[b][a]);
8769         }
8770     }
8771   HERE ("End of Display");
8772 #endif
8773   return count;
8774 }
8775           
8776 int** aln2count_mat ( Alignment *A)
8777     { /*
8778         function documentation: start
8779         
8780         int output_freq_mat ( char *outfile, Aligmnent *A)
8781
8782         This function counts the number of residues in each column of an alignment (Prot/NA)
8783         It outputs these values in the following format
8784
8785         This format can be piped into:
8786         The routine used for computing the p-value  gmat-inf-gc-v2c
8787         
8788         function documentation: end
8789       */
8790       
8791     int a, b,x;
8792     int **freq_mat;
8793     int alp_size;
8794
8795     alp_size=sizeof (AA_ALPHABET); 
8796     freq_mat=declare_int (alp_size+2, A->len_aln);
8797       
8798
8799     for ( a=0; a<A->len_aln; a++)
8800       {
8801         for ( b=0; b< A->nseq; b++)
8802           {
8803             if ( is_gap ( A->seq_al[b][a]))freq_mat[alp_size][a]++;
8804             else
8805               {
8806                 x=tolower(A->seq_al[b][a]);
8807                 freq_mat[x-'a'][a]++;
8808                 freq_mat[alp_size+1][a]++;
8809                 
8810               }
8811           }
8812       }
8813     
8814     return freq_mat;
8815     }
8816 char *aln2random_seq (Alignment *A, int pn1, int pn2, int pn3, int gn)
8817     {
8818
8819       /* 
8820
8821          
8822          Given the frequencies in A ( read as total counts of each Residue in
8823          freq[A->nseq][A->len_aln], and pn1, pn2 and pn3:
8824           
8825                           1-Generate a new amino-acid at each position
8826                           2-Insert Gaps, using a HMM.
8827
8828          
8829          pn3=Weight of the noise induced with sub mat.
8830
8831          pn1=% noise type 1 ( Varies with entropi)
8832           n1=Ratio noise type 1
8833           
8834          T =Nseq 
8835          t1=Noise 1 expressed in Nseq
8836          al=alphabet size;
8837          ncat=number of non 0 cat for a given position
8838          ICi initial count for residue i
8839
8840          Ci=freq[seq][AA]
8841          t1=T*n1*(1-1/ncat);
8842          t2=T*n2;
8843          
8844          Ci= ICi*(T-(t1+t2))/T +(t1)/al+(t2)/al
8845          
8846       */
8847       
8848       int **freq;
8849       int **count;
8850       float T, tot_t1, tot_t2,tot_t3, n1, n2, n3;
8851       float ncat;
8852       
8853       double gf;
8854       double *init_freq;
8855       double *blur_freq;
8856       double *t1, *t2,*t3;
8857       int a, b, c, x;
8858       char *seq;
8859       int tot;
8860       /*Viterbi  Parameters */
8861       
8862       int p;
8863       int AL=0;        /*Allowed Transition*/
8864       int F=-100000; /*Forbiden Transition*/
8865
8866       int GAP_TRANSITION;
8867       int IGAP=0, IAA=1;
8868       
8869       int state,best_state=0, score, best_score=0;
8870       int p_state;
8871       int e=0;
8872       int **score_tab;
8873       int **state_tab;
8874       int nstate=2;
8875       int **transitions;
8876       
8877       int max;
8878
8879       seq=vcalloc ( A->len_aln+1, sizeof (char));     
8880       count=aln2count_mat(A);
8881       freq=aln2count_mat(A);
8882
8883       T=100;
8884
8885       n1=(float)pn1/100;
8886       n2=(float)pn2/100;
8887       n3=(float)pn3/100;
8888       
8889       for ( a=0; a< A->len_aln; a++)
8890         {
8891           for ( b=0; b<26; b++)
8892             freq[b][a]=freq[b][a]*((T)/(A->nseq-freq[26][a]));
8893           freq[26][a]= (freq[26][a]*T)/A->nseq;
8894         }
8895
8896       
8897       init_freq=vcalloc ( 26, sizeof (double));
8898       blur_freq=vcalloc ( 26, sizeof (double));
8899       
8900       tot_t1=tot_t2=tot_t3=0;
8901       
8902       t1=vcalloc ( 27, sizeof (double));
8903       t2=vcalloc ( 27, sizeof (double));
8904       t3=vcalloc ( 27, sizeof (double));
8905       for (a=0; a< A->len_aln; a++)
8906         {
8907
8908         /*Compute Frequencies*/
8909           for (tot=0, b=0; b<26; b++)
8910                 {
8911                   if ( is_aa(b+'A'))
8912                     {
8913                       init_freq[b]=freq[b][a];
8914                       tot+=freq[b][a];
8915                     }
8916                 }
8917         /*Count the number of  different amino acids*/
8918         for ( ncat=0, b=0; b<=26; b++)
8919           {
8920             ncat+=(freq[b][a]!=0)?1:0;      
8921           }
8922         /*Blurr the distribution using */
8923         blur_freq=compute_matrix_p (init_freq,tot);     
8924                 
8925         
8926         /*compute noise 1: biased with blurred content * enthropy--> keeps prosite motifs*/
8927         tot_t1=T*n1*(1-1/ncat);
8928         for (  b=0; b< 26; b++)if ( is_aa(b+'A')){t1[b]=blur_freq[b]*(1-1/ncat)*n1;}
8929         
8930         /*Compute noise 2: completely random*/
8931         tot_t2=T*n2;
8932         for (  b=0; b< 26; b++)if ( is_aa(b+'A')){t2[b]=tot_t2/21;}
8933         
8934         /*compute noise 3: biased with the sole content(pam250mt)*/
8935         tot_t3=T*n3;
8936         for (  b=0; b<26; b++)if ( is_aa(b+'A')){t3[b]=blur_freq[b]*n3;}
8937         
8938         for ( b=0; b<26; b++)
8939           {
8940             if ( is_aa('A'+b))
8941               freq[b][a]=freq[b][a]*(T-(tot_t1+tot_t2+(tot_t3)))/T+t1[b]+t2[b]+t3[b];
8942           }
8943         
8944         /*end of the loop that mutates position a*/
8945         }
8946      
8947         vfree (blur_freq);
8948         vfree (init_freq);
8949         vfree ( t3);
8950         
8951       /*1-Generate the amino acids of the new sequence new*/
8952       
8953       
8954       vsrand (0);
8955       
8956       for ( a=0; a< A->len_aln; a++)
8957         {
8958
8959           for (T=0,b=0; b<26; b++)T+=freq[b][a];
8960           x=rand ()%((int)T);
8961           for (c=0,b=0; b<26; b++)
8962             {
8963              c+=freq[b][a];
8964              if ( c>=x)
8965                {
8966                  seq[a]='A'+b;
8967                  c=-1;
8968                  break;
8969                }
8970             }
8971           if ( c!=-1)seq[a]='-';
8972         }
8973       seq[a]='\0';
8974       
8975
8976       /*2 Generate the gaps in the new sequence*/
8977       
8978       
8979
8980       if ( gn<0);
8981       else
8982         {
8983
8984           transitions=declare_int ( nstate, nstate);
8985           score_tab=declare_int ( A->len_aln+2, nstate       );
8986           state_tab=declare_int ( A->len_aln+2, nstate       );
8987           
8988           
8989           
8990           for (a=0; a<nstate;a++)
8991             for (b=0; b<nstate;b++)
8992               {transitions[a][b]=F;}
8993           
8994           GAP_TRANSITION=AL-gn;
8995
8996           transitions[IGAP ][IGAP ]=AL;
8997           transitions[IAA][IAA]=AL;
8998           transitions[IAA ][IGAP]=GAP_TRANSITION;
8999           transitions[IGAP][IAA ]=GAP_TRANSITION;
9000           
9001           
9002           for ( p=1; p<=A->len_aln; p++){for (state=0; state< nstate; state++){score_tab[p][state]=F;state_tab[p][state]=-1;} }
9003           
9004           for (p=1; p<= A->len_aln; p++)
9005             {
9006               for (max=0,a=0; a<26; a++)max=MAX(max, freq[a][p-1]);
9007               max=(max*(A->nseq-count[26][p-1]))/A->nseq;
9008               
9009               for (state=0; state< nstate; state++)
9010                 {
9011                   
9012                   
9013                   gf=freq[26][p-1];
9014                   if      ( state==IGAP)  e=gf-50;
9015                   else if ( state==IAA )  e=max-50;
9016                   for (p_state=0; p_state<nstate; p_state++)
9017                     {
9018                       score=(score_tab[p-1][p_state]==F)?F:(e+transitions[p_state][state]+score_tab[p-1][p_state]);
9019                       if(p_state==0 || score>best_score){ best_score=score;best_state=p_state;}
9020                     }
9021                   score_tab[p][state]=best_score;
9022                   state_tab[p][state]=best_state;
9023                 }
9024             }
9025           
9026           for (state=0; state<nstate; state++)
9027             {
9028               if (state==0 || score_tab[p-1][state]>best_score){best_score=score_tab[p-1][state]; best_state=state;}
9029             }
9030           
9031           for (p=A->len_aln; p>0;)
9032             {
9033               if ( best_state==IGAP)
9034                 {
9035                   seq[p-1]='-';
9036                 }
9037               else if ( best_state==IAA)
9038                 {
9039                   seq[p-1]=seq[p-1];
9040                 }
9041               best_state=state_tab[p][best_state];
9042               p--;
9043             }
9044         }
9045       
9046       free_int (freq, -1);
9047       return seq;
9048     }
9049
9050 /********************************************************************/
9051 /*                                                                  */
9052 /*                      Weighting functions                         */
9053 /*                                                                  */
9054 /*                                                                  */
9055 /*                                                                  */
9056 /********************************************************************/
9057 Alignment * master_trimseq( Alignment *A, Sequence *S,char *mode)
9058      {
9059        Alignment *NA;
9060        char *p;
9061        int a, b;
9062        int use_aln=0, upper_sim=0, min_nseq=0, lower_sim=0;
9063        float f_upper_sim, f_lower_sim;
9064        char weight_mode[1000];
9065        char method[1000];
9066        int statistics=0;
9067        int trim_direction=TOP;
9068        float **sim_weight;
9069        int *seq_list;
9070        int table=0;
9071        
9072        
9073      
9074
9075      /*
9076        mode: 
9077            (trim)_<seq or aln>_%<percentage of tot weight to keep>_n<number of seq to keep>_w<weight mode>
9078      */
9079      
9080
9081      
9082      seq_list=vcalloc ( S->nseq, sizeof (int));
9083      for ( a=0; a< A->nseq; a++)
9084        {
9085          seq_list[a]=1;
9086        }
9087      
9088
9089      use_aln=aln_is_aligned(A);
9090      
9091      if ( mode[0]=='\0')
9092        {
9093         
9094          upper_sim=50;
9095          lower_sim=0;
9096          min_nseq=0;
9097          sprintf (weight_mode, "pwsim");
9098          sprintf ( method, "clustering2");
9099        }
9100      else 
9101        {
9102         
9103          upper_sim=lower_sim=min_nseq;
9104          sprintf (weight_mode, "pwsim");
9105          sprintf ( method, "clustering2");
9106        }
9107
9108      /*
9109       U or % (deprecated) Upper bound for pairwise similarity
9110       L or m (depercated) Lower  bound for pairwise similarity
9111       n max number of sequences
9112       N max number of sequences as a fraction of thet total
9113       S print Statistics
9114       T print Table of distances
9115      */
9116
9117      
9118
9119      while ( (p=strtok(mode, "_")))
9120            {         
9121              mode=NULL;
9122              if (strm (p, "seq"))use_aln=0;
9123              else if ( strm(p,"aln"))use_aln=1;
9124              else if  (p[0]=='s')statistics=1;
9125              else if  (p[0]=='t')table=1;
9126              else if  (p[0]=='U')upper_sim=atoi(p+1);
9127              else if  (p[0]=='L')lower_sim=atoi(p+1);
9128              else if  (p[0]=='n')min_nseq=atoi(p+1);
9129              else if  (p[0]=='N')min_nseq=atoi(p+1)*-1;
9130              else if  (p[0]=='B')trim_direction=BOTTOM;
9131              else if  (p[0]=='T')trim_direction=TOP;
9132              else if  (p[0]=='W')sprintf (weight_mode, "%s", p+1);
9133              else if  (p[0]=='M')sprintf (method, "%s", p+1);
9134              else if  (p[0]=='K')
9135                {
9136                  
9137                  while ((p=strtok(NULL, ":")))
9138                    {
9139                      
9140                      if ( p[0]=='#')
9141                        {
9142                          seq_list[atoi(p+1)-1]=2;
9143                        }
9144                      else if ( (a=name_is_in_list (p, A->name, A->nseq, 100))!=-1)
9145
9146                        {
9147                          seq_list[a]=2;
9148                        } 
9149                    }
9150                }
9151            }
9152      
9153      if ( !upper_sim && !min_nseq && !lower_sim)upper_sim=50;
9154      
9155      
9156
9157      if  (!S)
9158        {
9159          fprintf ( stderr, "\ntrimseq requires a set of sequences[FATAL:%s]\n", PROGRAM);
9160          crash("");
9161        }
9162      
9163      else if ( min_nseq> S->nseq)
9164        {
9165          min_nseq=S->nseq;
9166        }
9167      else if ( min_nseq<0)
9168        {
9169          if ( min_nseq<-100)
9170            {
9171              add_warning ( stderr, "\nWARNING: trimseq: Nseq(N)  max_val=100%% [Automatic reset]\n");
9172              min_nseq=-100;
9173            }
9174          
9175          min_nseq=(int)((float)S->nseq*((float)min_nseq/100)*-1);
9176        }
9177
9178
9179      NA=seq2subseq3 (A, S,use_aln,lower_sim,upper_sim,min_nseq,trim_direction, weight_mode,&sim_weight, seq_list );
9180      
9181      if ( table)
9182        {
9183          fprintf ( stderr, "\nSIMILARITY MATRIX\n");
9184          for ( a=0; a< A->nseq-1; a++)
9185            for ( b=a+1; b< A->nseq; b++)
9186              {
9187                fprintf ( stderr, "%15s Vs %15s : %3.2f %% id\n", A->name[a], A->name[b], 100-sim_weight[a][b]);
9188              }
9189        }
9190      if ( statistics)
9191        {
9192          f_upper_sim=(upper_sim>100)?((float)upper_sim/(float)100):upper_sim;
9193          f_lower_sim=(upper_sim>100)?((float)lower_sim/(float)100):lower_sim;
9194          
9195          fprintf ( stderr, "\nTRIM Informations:\n");
9196          fprintf ( stderr, "\tUse...........: %s\n",(use_aln)?"multiple_aln":"pairwise_aln");
9197          fprintf ( stderr, "\tcluster_mode..: %s\n"  ,method);
9198          fprintf ( stderr, "\tsim_mode......: %s\n"  ,weight_mode);
9199          fprintf ( stderr, "\tlower_id_bound: %.2f%%\n"  ,(f_lower_sim==0)?-1:f_lower_sim);
9200          fprintf ( stderr, "\tupper_id_bound: %.2f%%\n",(f_upper_sim==0)?-1:f_upper_sim);
9201          fprintf ( stderr, "\tnseq_kept.....: %d (out of %d)\n"  ,NA->nseq, S->nseq);
9202          fprintf ( stderr, "\treduction.....: %d%% of original set\n"  ,(NA->nseq*100)/S->nseq);
9203          fprintf ( stderr, "\tTrim_direction: From %s \n"  ,(trim_direction==BOTTOM)?"Bottom":"Top");
9204        }
9205
9206      return NA;
9207    }
9208
9209 Alignment *sim_filter (Alignment *A, char *in_mode, char *seq)
9210 {
9211   int **sim, **cov;
9212   int *list;
9213   int *keep;
9214   int maxnseq, nseq_ratio, nc;
9215   int new_nseq;
9216   int a, s, n, k;
9217   Alignment *R;
9218   char *mode;
9219   int outlayers;
9220   int direction=1;//remove the higher than
9221   int coverage=0; //remove based on coverage
9222   static char *field;
9223   int maxsim, minsim, maxcov, mincov;
9224   
9225   if ( !field) field=vcalloc (1000, sizeof (char));
9226   
9227   mode=vcalloc ( strlen (in_mode)+10, sizeof (char));
9228   sprintf ( mode, "_%s_", in_mode);
9229   
9230   strget_param ( mode, "_I", "100", "%d", &maxsim);
9231   strget_param ( mode, "_i", "0", "%d",  &minsim);
9232   strget_param ( mode, "_C", "100", "%d",  &maxcov);
9233   strget_param ( mode, "_c", "0", "%d",  &mincov);
9234   
9235  
9236   
9237     
9238   
9239   keep=vcalloc ( A->nseq, sizeof (int));
9240   list=vcalloc ( A->nseq, sizeof (int));
9241  
9242  
9243   
9244
9245   
9246   
9247   if (!seq)s=0;
9248   else s=name_is_in_list (seq, A->name, A->nseq, 100);
9249   if (s==-1) 
9250     {
9251     
9252       if ( s==-1)printf_exit (EXIT_FAILURE, stderr, "ERROR: %s is not a valid sequence", seq);
9253     }
9254   else
9255     keep[s]=1;
9256   
9257   //get the distances
9258   if ( strstr (mode, "_seq_"))
9259     {
9260       char **seq;
9261       int **M;
9262     
9263       M=read_matrice ("blosum62mt");
9264       seq=declare_char (A->nseq, A->len_aln+1);
9265       for (a=0; a<A->nseq; a++)
9266         {
9267           sprintf ( seq[a], "%s", A->seq_al[a]);
9268           ungap (seq[a]);
9269         }
9270       
9271       sim=declare_int (A->nseq, A->nseq);
9272       cov=declare_int (A->nseq, A->nseq);
9273       
9274       for (a=0; a<A->nseq; a++)
9275         {
9276           if ( s!=a)
9277             {
9278               sim[s][a]=sim[a][s]=idscore_pairseq(seq[s], seq[a],-12, -1,M,"sim");
9279               cov[s][a]=cov[a][s]=idscore_pairseq(seq[s], seq[a],-12, -1,M,"cov");
9280               
9281             }
9282         }
9283       free_char (seq, -1);
9284       free_int (M,-1);
9285     }
9286   else 
9287     {
9288       sim=aln2sim_mat (A, "idmat");
9289       cov=aln2cov (A);
9290     }
9291   
9292   for (a=0; a< A->nseq; a++)
9293     {
9294       if (a==s)continue;
9295       else 
9296         {
9297           if ( sim[s][a]>maxsim || sim[s][a]<minsim|| cov[s][a]<mincov||cov[s][a]>maxcov)keep[a]=-1;
9298           else keep[a]=1;
9299         }
9300     }
9301
9302   for ( n=0, a=0; a< A->nseq; a++)
9303     {
9304       if ( keep[a]!=-1)
9305         {
9306           list[n++]=a;
9307         }
9308     }
9309
9310   R=extract_sub_aln (A, n, list);
9311   free_int (sim, -1); free_int (cov, -1);vfree (list);
9312   
9313   return R;
9314 }
9315         
9316
9317 static int find_worst_seq ( int **sim, int n, int *keep, int max, int direction);
9318 Alignment *simple_trimseq (Alignment *A, Alignment *K, char *in_mode, char *seq_list, int **sim)
9319 {
9320   int *list;
9321   int *keep;
9322   int maxnseq, maxsim, nseq_ratio, nc;
9323   int new_nseq;
9324   int a,b, s, n, k;
9325   Alignment *R;
9326   char *mode;
9327   int outlayers;
9328   int direction=1;//remove the higher than
9329   int coverage=0; //remove based on coverage
9330   static char *field;
9331   int *tot_avg;
9332   int KeepN=0;
9333   int Print=0;
9334   
9335   if ( !field) field=vcalloc (1000, sizeof (char));
9336   
9337   mode=vcalloc ( strlen (in_mode)+10, sizeof (char));
9338   sprintf ( mode, "_%s_", in_mode);
9339   
9340   strget_param ( mode, "_%%", "0", "%d", &maxsim);
9341   strget_param ( mode, "_n", "0", "%d",  &maxnseq);
9342   strget_param ( mode, "_N", "0", "%d",  &nseq_ratio);
9343   strget_param ( mode, "_F", "0", "%d",  &nc);
9344   strget_param ( mode, "_O", "0", "%d",  &outlayers);
9345   strget_param ( mode, "_K", "0", "%d",  &KeepN);
9346   
9347   strget_param ( mode, "_f", "NAME", "%s", field);
9348
9349   if ( strstr (mode, "_P_"))Print=1;
9350   
9351   if ( strstr (mode, "_min"))direction=-1;
9352   else direction=1;
9353   
9354   if ( strstr (mode, "_cov"))coverage=1;
9355   else coverage=0;
9356   
9357  
9358   if ( nseq_ratio)
9359     {
9360       maxnseq=(A->nseq*nseq_ratio)/100;
9361       maxsim=0;
9362     }
9363   else if ( maxnseq)
9364     {
9365       maxsim=0;
9366     }
9367   else if ( !maxsim)
9368     {
9369       maxsim=100;
9370     }
9371     
9372   
9373   keep=vcalloc ( A->nseq, sizeof (int));
9374   list=vcalloc ( A->nseq, sizeof (int));
9375  
9376  
9377   
9378  
9379   /*Remove Sequences that do not have at least one residue in the first and last nc columns*/
9380   if ( nc)
9381     {
9382       int left, right, full_n,x, y;
9383       int *full_list;
9384       
9385       Alignment *F;
9386       
9387       full_list=vcalloc ( A->nseq, sizeof (int));
9388       full_n=0;
9389       for (x=0; x< A->nseq; x++)
9390         {
9391           for ( left=0,y=0; y<MIN(A->len_aln,nc); y++)
9392             if (!is_gap(A->seq_al[x][y]))left=1;
9393           
9394           for ( right=0,y=MAX(0,(A->len_aln-nc)); y<A->len_aln; y++)
9395             if (!is_gap(A->seq_al[x][y]))right=1;
9396           
9397           if ( left && right)full_list[full_n++]=x;
9398         }
9399       F=extract_sub_aln (A, full_n, full_list);
9400       free_aln (A);
9401       vfree (full_list);
9402       A=F;
9403     }
9404           
9405   /*Reorder the sequences according to the tree order: hopefully better phylogenetic coverage after trim*/
9406   if (strstr (mode, "_T"))
9407     {
9408       NT_node **T;
9409       Sequence *O;
9410       
9411       if (!sim)sim=sim_array2dist_array ( NULL, MAXID);
9412       T=int_dist2nj_tree (sim, A->name, A->nseq, NULL);
9413       O=tree2seq (T[3][0], NULL);
9414       A=reorder_aln (A, O->name, O->nseq);
9415       
9416       free_int (sim, -1);
9417       free_sequence (O, -1);
9418     }
9419   
9420   if ( coverage==0)
9421     {
9422       if ( strstr (mode, "seq_") && !sim)sim=seq2comp_mat (aln2seq(A), "blosum62mt", "sim");
9423       else sim=aln2sim_mat (A, "idmat");
9424     }
9425   else
9426     {
9427       int b;
9428       if ( strstr (mode, "seq_") && !sim)sim=seq2comp_mat (aln2seq(A), "blosum62mt", "cov");
9429       else sim=aln2cov (A);
9430     
9431     }
9432
9433
9434   if ( K && K->nseq>0)
9435     {
9436       for ( a=0; a< K->nseq; a++)
9437         if ( (k=name_is_in_list (K->name[a], A->name, A->nseq, MAXNAMES+1))!=-1)
9438           {
9439
9440             keep[k]=1;
9441           }
9442     }
9443   if ( seq_list)
9444     {
9445       for ( a=0; a< A->nseq; a++)
9446         {
9447           if (strstr (field, "NAME") && perl_strstr (A->name[a], seq_list)){keep[a]=1;}
9448           else if (strstr (field, "COMMENT") && A->seq_comment && perl_strstr(A->seq_comment[a], seq_list)){keep[a]=1;}
9449           else if (strstr (field, "SEQ") && perl_strstr((A->S)->seq[a], seq_list)){keep[a]=1;}
9450         }
9451  
9452     }
9453   for (a=0; a<KeepN; a++)keep[a]=1;
9454   
9455   if (Print)
9456     {
9457       for ( a=0; a< A->nseq; a++)
9458         if ( keep[a]) fprintf ( stderr, "\nFORCED KEEP %s", A->name[a]);
9459     }
9460   
9461   new_nseq=A->nseq;
9462   
9463   
9464   while ( (s=find_worst_seq (sim, A->nseq, keep, maxsim, direction))!=-1 && new_nseq>maxnseq)
9465     {
9466       for ( a=0; a< A->nseq; a++)sim[a][s]=sim[s][a]=-1;
9467       keep[s]=-1;
9468       new_nseq--;
9469     }
9470   
9471   /*Trim Outlayers*/
9472   if (outlayers!=0)
9473     {
9474      int nn, b;
9475       tot_avg=vcalloc ( A->nseq, sizeof (int));
9476       
9477       for (a=0; a<A->nseq; a++)
9478         {
9479           if ( keep[a]==-1)tot_avg[a]=-1;
9480           else
9481             {
9482               for (nn=0, b=0; b< A->nseq; b++)
9483                 {
9484                   if (a==b || keep[b]==-1)continue;
9485                   else
9486                     {
9487                       tot_avg[a]+=sim[a][b];
9488                       nn++;
9489                     }
9490                 }
9491               tot_avg[a]=(nn==0)?-1:(tot_avg[a])/nn;
9492             }
9493         }
9494       for ( a=0; a<A->nseq; a++)
9495         {
9496           if (tot_avg[a]!=-1 && tot_avg[a]<outlayers)
9497             {
9498               fprintf ( stderr, "\nREMOVED OUTLAYER: %3d %% avg similarity with remaining sequences [Seq %s]", tot_avg[a],A->name[a]);
9499               keep[a]=-1;
9500             }
9501         }
9502       vfree ( tot_avg);
9503     }
9504
9505   for ( n=0, a=0; a< A->nseq; a++)
9506     {
9507       if ( keep[a]!=-1)
9508         {
9509           list[n++]=a;
9510         }
9511     }
9512
9513   R=extract_sub_aln (A, n, list);
9514   free_int (sim, -1); vfree (list);
9515   
9516   return R;
9517 }
9518         
9519 int find_worst_seq ( int **sim, int n, int *keep,int max,int direction)
9520 {
9521   int **sc;
9522   int a, b, r=0;
9523   int si;
9524   
9525   sc=declare_int (n, 2);
9526   if (direction==-1)max=100-max;
9527   
9528   for ( a=0; a< n; a++) sc[a][0]=a;
9529   for ( a=0; a< n-1; a++)
9530     {
9531       for ( b=a+1; b<n; b++)
9532         {
9533           
9534           if (sim[a][b]>=0)si=(direction==-1)?100-sim[a][b]:sim[a][b];
9535           else si=sim[a][b];
9536           if ( si>max)
9537                 {
9538                   if ( keep[a]!=1)sc[a][1]+=si;
9539                   if ( keep[b]!=1)sc[b][1]+=si;
9540                 }
9541         }
9542     }
9543   
9544   sort_int_inv ( sc, 2, 1, 0, n-1);
9545   if ( sc[0][1]>0)r=sc[0][0];
9546   else r=-1;
9547   
9548   free_int (sc, -1);
9549   if (r!=-1 && keep && keep[r])return -1;
9550   else return r;
9551 }
9552
9553 int find_worst_seq_old ( int **sim, int n, int *keep,int max,int direction)
9554 {
9555   int **sc;
9556   int a, b, r=0;
9557   
9558   sc=declare_int (n, 2);
9559   
9560   for ( a=0; a< n; a++) sc[a][0]=a;
9561   for ( a=0; a< n-1; a++)
9562     {
9563       for ( b=a+1; b<n; b++)
9564         {
9565           if ( direction==1)
9566             {
9567               if ( sim[a][b]>max)
9568                 {
9569                   if ( keep[a]!=1)sc[a][1]+=sim[a][b]; 
9570                   if ( keep[b]!=1)sc[b][1]+=sim[a][b];
9571                 }
9572             }
9573           else if ( direction == -1)
9574             {
9575               if ( sim[a][b]<max && sim[a][b]>=0)
9576                 {
9577                   if ( keep[a]!=1)sc[a][1]+=sim[a][b]; 
9578                   if ( keep[b]!=1)sc[b][1]+=sim[a][b];
9579                 }
9580             }
9581         }
9582     }
9583   
9584   if ( direction ==1) //remove max
9585     {
9586       sort_int_inv ( sc, 2, 1, 0, n-1);
9587       if ( sc[0][1]>0)r=sc[0][0];
9588       else r=-1;
9589       
9590     }
9591   else if ( direction ==-1)//remove min
9592     {
9593       sort_int_inv ( sc, 2, 1, 0, n-1);
9594       if ( sc[0][1]>=0)r=sc[0][0];
9595       else r=-1;
9596       HERE ("** %d %d\n", r,sc[0][1]); 
9597     }
9598   free_int (sc, -1);
9599   if (r!=-1 && keep && keep[r])return -1;
9600   else return r;
9601 }
9602
9603       
9604 Alignment * trimseq( Alignment *A, Sequence *S,char *mode)
9605    {
9606      Alignment *NA;
9607      char *p;
9608      int a, b;
9609      int use_aln=0, upper_sim=0, min_nseq=0, lower_sim=0;
9610      char weight_mode[1000];
9611      char method[1000];
9612      int statistics=0;
9613      int trim_direction=TOP;
9614      float **sim_weight;
9615      int *seq_list;
9616      int table=0;
9617      int print_name=0;
9618      float f_lower_sim, f_upper_sim;
9619      
9620          
9621
9622      /*
9623        mode: 
9624            (trim)_<seq or aln>_%<percentage of tot weight to keep>_n<number of seq to keep>_w<weight mode>
9625      */
9626      
9627
9628      
9629      seq_list=vcalloc ( S->nseq, sizeof (int));
9630      for ( a=0; a< A->nseq; a++)
9631        {
9632          seq_list[a]=1;
9633        }
9634      
9635
9636      use_aln=aln_is_aligned(A);
9637      
9638      
9639      if ( mode[0]=='\0')
9640        {
9641         
9642          upper_sim=50;
9643          lower_sim=0;
9644          min_nseq=0;
9645          sprintf (weight_mode, "pwsim_fragment");
9646          sprintf ( method, "clustering2");
9647        }
9648      else 
9649        {
9650         
9651          upper_sim=lower_sim=min_nseq;
9652          sprintf (weight_mode, "pwsim_fragment");
9653          sprintf ( method, "clustering2");
9654        }
9655
9656      /*
9657       U or % (deprecated) Upper bound for pairwise similarity
9658       L or m (depercated) Lower  bound for pairwise similarity
9659       n max number of sequences
9660       N max number of sequences as a fraction of thet total
9661       S print Statistics
9662       T print Table of distances
9663      */
9664
9665      
9666
9667      while ( (p=strtok(mode, "_")))
9668            {         
9669              mode=NULL;
9670              if (strm (p, "seq"))use_aln=0;
9671              else if ( strm(p,"aln"))use_aln=1;
9672              else if  (p[0]=='s')statistics=1;
9673              else if  (p[0]=='t')table=1;
9674              else if  (p[0]=='p')print_name=1;
9675              else if  (p[0]=='U')upper_sim=atoi(p+1);
9676              else if  (p[0]=='L')lower_sim=atoi(p+1);
9677              else if  (p[0]=='n')min_nseq=atoi(p+1);
9678              else if  (p[0]=='N')min_nseq=atoi(p+1)*-1;
9679              else if  (p[0]=='B')trim_direction=BOTTOM;
9680              else if  (p[0]=='T')trim_direction=TOP;
9681              else if  (p[0]=='W')sprintf (weight_mode, "%s", p+1);
9682              else if  (p[0]=='M')sprintf (method, "%s", p+1);
9683              else if  (p[0]=='K')
9684                {
9685                  
9686                  while ((p=strtok(NULL, ":")))
9687                    {
9688                      
9689                      if ( (a=name_is_in_list (p, A->name, A->nseq, 100))!=-1)
9690                        {
9691                          seq_list[a]=2;
9692                        } 
9693                    }
9694                }
9695            }
9696      
9697      if ( !upper_sim && !min_nseq && !lower_sim)upper_sim=50;
9698      
9699      
9700
9701      if  (!S)
9702        {
9703          fprintf ( stderr, "\ntrimseq requires a set of sequences[FATAL:%s]\n", PROGRAM);
9704          crash("");
9705        }
9706      
9707      else if ( min_nseq> S->nseq)
9708        {
9709          min_nseq=S->nseq;
9710        }
9711      else if ( min_nseq<0)
9712        {
9713          if ( min_nseq<-100)
9714            {
9715              add_warning ( stderr, "\nWARNING: trimseq: Nseq(N)  max_val=100%% [Automatic reset]\n");
9716              min_nseq=-100;
9717            }
9718          
9719          min_nseq=(int)((float)S->nseq*((float)min_nseq/100)*-1);
9720        }
9721
9722
9723      NA=seq2subseq2 (A, S,use_aln,lower_sim,upper_sim,min_nseq,trim_direction, weight_mode,&sim_weight, seq_list );
9724      
9725      if ( table)
9726        {
9727          fprintf ( stderr, "\nSIMILARITY MATRIX\n");
9728          for ( a=0; a< A->nseq-1; a++)
9729            for ( b=a+1; b< A->nseq; b++)
9730              {
9731                fprintf ( stderr, "%15s Vs %15s : %3.2f %% id\n", A->name[a], A->name[b], 100-sim_weight[a][b]);
9732              }
9733        }
9734      
9735      NA=seq_name2removed_seq_name(S, NA,sim_weight);
9736
9737      if ( print_name)
9738        {
9739          fprintf ( stderr, "\nList of sequences with their closest removed neighbors\n");
9740          for ( a=0; a< NA->nseq; a++)fprintf ( stderr, "\n%s: %s\n", NA->name[a], NA->seq_comment[a]);
9741        }
9742      
9743      if ( statistics)
9744        {
9745          f_lower_sim=(lower_sim>100)?(float)lower_sim/100:lower_sim;
9746          f_upper_sim=(upper_sim>100)?(float)upper_sim/100:upper_sim;
9747
9748          fprintf ( stderr, "\nTRIM seq Informations:\n");
9749          fprintf ( stderr, "\tUse...........: %s\n",(use_aln)?"multiple_aln":"pairwise_aln");
9750          fprintf ( stderr, "\tcluster_mode..: %s\n"  ,method);
9751          fprintf ( stderr, "\tsim_mode......: %s\n"  ,weight_mode);
9752          fprintf ( stderr, "\tlower_id_bound: %.2f%%\n"  ,(f_lower_sim==0)?-1:f_lower_sim);
9753          fprintf ( stderr, "\tupper_id_bound: %.2f%%\n",(f_upper_sim==0)?-1:f_upper_sim);
9754          fprintf ( stderr, "\tnseq_kept.....: %d (out of %d)\n"  ,NA->nseq, S->nseq);
9755          fprintf ( stderr, "\treduction.....: %d%% of original set\n"  ,(NA->nseq*100)/S->nseq);
9756          fprintf ( stderr, "\tTrim_direction: From %s \n"  ,(trim_direction==BOTTOM)?"Bottom":"Top");
9757        }
9758
9759      return NA;
9760    }
9761     
9762 Alignment * tc_trimseq( Alignment *A, Sequence *S,char *mode)
9763    {
9764      Alignment *NA;
9765      Sequence  *TS;
9766      char *trimfile, *alnfile;
9767      int *seq_list;
9768      int a, nseq=0, sim=0;
9769      char *p;
9770      char command[100000];
9771      char keep_list[10000];
9772      
9773      int top, bottom, middle, pmiddle;
9774      
9775      keep_list[0]='\0';
9776     
9777      seq_list=vcalloc ( S->nseq, sizeof (int));
9778      for ( a=0; a< A->nseq; a++)
9779        {
9780          seq_list[a]=1;
9781        }
9782      
9783      trimfile=vtmpnam (NULL);
9784      alnfile=vtmpnam (NULL);
9785      if ( !aln_is_aligned (A))
9786        {
9787          fprintf ( stderr, "\ntrimTC: computation of an Approximate MSA  [");
9788          A=compute_tcoffee_aln_quick ( A, NULL);
9789          fprintf ( stderr, "DONE]\n");
9790        }
9791      output_clustal_aln (alnfile, A);
9792      
9793     
9794      while ( (p=strtok(mode, "#")))
9795            {         
9796              mode=NULL;
9797
9798                      
9799              if (p[0]=='%' || p[0]=='S')sim=(p[1]=='%')?atoi(p+2):atoi(p+1);
9800              else if  (p[0]=='n' || p[0]=='N')nseq=atoi(p+1);
9801              else if  (p[0]=='K')
9802                {
9803                  if ( (a=name_is_in_list (p+1, A->name, A->nseq, 100))!=-1)
9804                    {
9805                      seq_list[a]=2;
9806                    }  
9807                  
9808                }
9809            }
9810      if ( nseq ==0 && sim ==0)
9811        {
9812          fprintf ( stderr, "\nERROR: trimTC\nIndicate the maximum number of sequences Nnseq\nOR the maximum average similarity of the chosen sequencesSx\nEX: +trimTC S20 OR +trimTC N5"); 
9813          fprintf ( stderr, "\n[FATAL:%s]", PROGRAM);
9814          myexit (EXIT_FAILURE);
9815        }
9816      
9817      for ( a=0; a<A->nseq; a++)if (seq_list[a]==2){strcat ( keep_list, A->name[a]);strcat ( keep_list," ");}
9818      
9819      if ( sim)
9820        {
9821          sprintf ( command , "%s -infile %s -trim  -trimfile=%s  -split_score_thres %d -convert -iterate 0 ",get_string_variable("t_coffee"), alnfile, trimfile,sim);
9822          if ( keep_list[0]){strcat ( command, " -seq_to_keep ");strcat ( command, keep_list);}
9823          my_system ( command);
9824          TS=read_sequences (trimfile);
9825        }
9826      else if ( nseq && A->nseq>nseq)
9827        {
9828          
9829          top=100;bottom=0;
9830          pmiddle=0;middle=50;
9831          
9832          sprintf ( command , "%s -infile %s -trim  -trimfile=%s  -split_score_thres %d -convert -iterate 0",get_string_variable("t_coffee"), alnfile, trimfile,middle);
9833          if ( keep_list[0]){strcat ( command, " -seq_to_keep ");strcat ( command, keep_list);}
9834          my_system ( command);
9835          
9836          TS=read_sequences (trimfile);
9837          fprintf ( stderr, "\n\tTrimTC: Sim %d Nseq %d\t",middle, TS->nseq);
9838          
9839          if ( TS->nseq>nseq)top=middle;
9840          else if ( TS->nseq<nseq)bottom=middle;
9841          pmiddle=middle;
9842          middle=(top-bottom)/2+bottom;
9843          
9844          while (TS->nseq!=nseq && pmiddle!=middle)
9845            {
9846              
9847              sprintf ( command , "%s -infile %s -trim  -trimfile=%s  -split_score_thres %d -convert -iterate 0 ",get_string_variable("t_coffee"), alnfile, trimfile,middle);
9848              if ( keep_list[0]){strcat ( command, " -seq_to_keep ");strcat ( command, keep_list);}
9849              my_system ( command);
9850              free_sequence (TS, -1);
9851              TS=read_sequences (trimfile);
9852              fprintf ( stderr, "\n\tTrimTC: Sim %d Nseq %d\t", middle, TS->nseq);
9853              
9854              if ( TS->nseq>nseq)top=middle;
9855              else if ( TS->nseq<nseq)bottom=middle;
9856              pmiddle=middle;
9857              middle=(top-bottom)/2+bottom;
9858            }
9859        }
9860      else
9861        {
9862          TS=aln2seq (A);
9863        }
9864      NA=seq2aln (TS, NULL, 1);
9865      vremove ( alnfile);
9866      fprintf ( stderr, "\n");
9867      
9868      return NA;
9869    }   
9870
9871 Alignment* seq2subseq3( Alignment *A, Sequence *S,int use_aln, int int_lower_sim,int int_upper_sim, int min_nseq, int trim_direction, char *weight_mode, float ***sim_weight, int *seq_list)
9872 {
9873   int a, b;
9874   int new_nseq;
9875
9876   /*OUTPUT*/
9877   char **seq, **name;
9878   Sequence *NS;
9879   Alignment *NA;
9880   float sim, lower_sim, upper_sim;
9881   
9882   lower_sim=(int_lower_sim>100)?(float)int_lower_sim/100:int_lower_sim;
9883   upper_sim=(int_upper_sim>100)?(float)int_upper_sim/100:int_upper_sim;
9884
9885   sim_weight[0]=get_weight   ((use_aln)?A:NULL, S, weight_mode);
9886   
9887   name=declare_char (S->nseq, (MAXNAMES+1));
9888   seq= declare_char (S->nseq, S->max_len+1);
9889   
9890   /*
9891     Remove every sequence that is more than upper_sim and less than lower_sim similar to the master sequences
9892     the master sequence(s) are those for which seq_list[x]==2
9893   */
9894
9895
9896   
9897
9898   new_nseq=A->nseq;
9899   
9900
9901   for (a=0; a< A->nseq; a++)
9902     {
9903       if ( seq_list[a]==2)
9904         {
9905         
9906           for ( b=0; b< A->nseq;b++)
9907             {
9908               sim=100-sim_weight[0][a][b];
9909               if (seq_list[b]==1 && (sim>upper_sim || sim<lower_sim))
9910                 {
9911                  seq_list[b]=0;
9912                  new_nseq--;
9913                 }
9914             }
9915           
9916         }
9917     }
9918   
9919   /*Prepare the new sequence List*/
9920
9921   for (b=0, a=0; a<S->nseq; a++) 
9922           {
9923             if ( seq_list[a])
9924               {
9925                 sprintf ( name[b], "%s", S->name[a]);
9926                 sprintf ( seq[b] , "%s",(use_aln)?A->seq_al[a]: S->seq[a] );
9927                 b++;
9928               }
9929           }
9930   
9931   
9932   NS=fill_sequence_struc (new_nseq,seq,name);
9933   NA=seq2aln(NS,NULL,1);         
9934   
9935   if ( use_aln && A)
9936     {
9937       NA=realloc_aln2  ( NA,A->max_n_seq,A->len_aln+1);
9938       
9939       for (b=0, a=0; a<S->nseq; a++) 
9940         {
9941           if ( seq_list[a])
9942             {
9943               sprintf ( NA->seq_al[b] , "%s",A->seq_al[a]);
9944               b++;
9945               }
9946         }
9947
9948       NA->len_aln=A->len_aln;
9949       ungap_aln(NA);
9950     }
9951   
9952
9953   return NA;
9954 }
9955 Alignment* seq2subseq2( Alignment *A, Sequence *S,int use_aln, int int_lower_sim,int int_upper_sim, int min_nseq, int trim_direction, char *weight_mode, float ***sim_weight, int *seq_list)
9956 {
9957   int a, b;
9958   int new_nseq;
9959   int seq_index=0;
9960   /*OUTPUT*/
9961   char **seq, **name;
9962   Sequence *NS;
9963   Alignment *NA;
9964   float lower_sim, upper_sim;
9965   
9966   lower_sim=(int_lower_sim>100)?(float)int_lower_sim/100:int_lower_sim;
9967   upper_sim=(int_upper_sim>100)?(float)int_upper_sim/100:int_upper_sim;
9968
9969  
9970   sim_weight[0]=get_weight   ((use_aln)?A:NULL, S, weight_mode);
9971   
9972   name=declare_char (S->nseq, (MAXNAMES+1));
9973   seq= declare_char (S->nseq, S->max_len+1);
9974   
9975   /*
9976     1 REMOVE OUTLAYERS
9977     2 REMOVE CLOSELY RELATED SEQUENCES
9978     3 IF STILL TOO MANY SEQUENCES:
9979       REMOVE THE MOST CLOSELY RELATED ONES
9980   */
9981
9982
9983   /*1 Remove outlayers*/
9984   
9985   new_nseq=A->nseq;
9986  
9987  
9988   /*1 Remove outlayers*/
9989   while ( lower_sim && (extreme_seq(BOTTOM,A,sim_weight[0],seq_list, &seq_index) <lower_sim) && ((new_nseq)>min_nseq) && seq_index!=-1)
9990     {
9991   
9992       if ( seq_list[seq_index]==1)
9993         {
9994           seq_list[seq_index]=0;
9995           new_nseq--;
9996         }
9997     }
9998    /*2 Remove close relative*/
9999   
10000  
10001   while ( upper_sim && (extreme_seq(TOP, A,sim_weight[0],seq_list, &seq_index)>upper_sim) && ((new_nseq)>min_nseq)&& seq_index!=-1)
10002     { 
10003   
10004       if ( seq_list[seq_index]==1)
10005         {
10006           seq_list[seq_index]=0;
10007           new_nseq--;
10008         }
10009     }
10010
10011
10012   /*Remove extra sequences*/
10013   
10014   while ( min_nseq>0 && new_nseq>min_nseq && seq_index!=-1)
10015     {
10016      
10017       extreme_seq(trim_direction, A,sim_weight[0],seq_list, &seq_index);
10018   
10019       if ( seq_index==-1)break;
10020       if ( seq_list[seq_index]==1)
10021         {
10022           seq_list[seq_index]=0;
10023           new_nseq--;
10024         }
10025     }
10026
10027
10028   /*Prepare the new sequence List*/
10029
10030   for (b=0, a=0; a<S->nseq; a++) 
10031           {
10032             if ( seq_list[a])
10033               {
10034                 sprintf ( name[b], "%s", S->name[a]);
10035                 sprintf ( seq[b] , "%s",(use_aln)?A->seq_al[a]: S->seq[a] );
10036                 b++;
10037               }
10038           }
10039   
10040   
10041   NS=fill_sequence_struc (new_nseq,seq,name);
10042   NA=seq2aln(NS,NULL,1);         
10043   
10044   if ( use_aln && A)
10045     {
10046       NA=realloc_aln2  ( NA,A->max_n_seq,A->len_aln+1);
10047       
10048       for (b=0, a=0; a<S->nseq; a++) 
10049         {
10050           if ( seq_list[a])
10051             {
10052               sprintf ( NA->seq_al[b],"%s",A->seq_al[a]);
10053               b++;
10054               }
10055         }
10056
10057       NA->len_aln=A->len_aln;
10058       ungap_aln(NA);
10059     }
10060   
10061
10062   return NA;
10063 }
10064
10065 float extreme_seq (int direction, Alignment *A,float **sim_weight,int *seq_list, int *seq_index)
10066 {
10067   
10068   /*find the closest relative of each sequence
10069     Return:
10070           Direction= BOTTOM: the sequence whose closest relative is the most distant
10071           Direction= TOP:    the sequence whose closest relative is the closest
10072   weight: different sequences=100
10073           similar sequences  =0
10074   */
10075   int a, b;
10076  
10077   float top_sim,bottom_sim, best_sim, sim;
10078   int   top_seq, bottom_seq;
10079   
10080   bottom_seq=top_seq=seq_index[0]=-1;
10081   top_sim=-1;
10082   bottom_sim=101;
10083   
10084   for (a=0; a< A->nseq; a++)
10085     {
10086       if (seq_list[a]!=1)continue;
10087
10088       for ( best_sim=0, b=0; b< A->nseq; b++)
10089         {
10090           if ( a==b || !seq_list[b])continue;
10091           
10092           sim=100-sim_weight[a][b];
10093           if (sim>best_sim)
10094             {
10095               best_sim=sim;
10096             }
10097         }
10098
10099       if ( best_sim>top_sim)
10100         {
10101           top_seq=a;
10102           top_sim=best_sim;
10103         }
10104      
10105       if ( best_sim<bottom_sim)
10106         {
10107           bottom_seq=a;
10108           bottom_sim=best_sim;
10109         }
10110       
10111     }
10112   if ( direction==BOTTOM  ){seq_index[0]= bottom_seq; return bottom_sim;}
10113   else if ( direction==TOP){seq_index[0]= top_seq; return top_sim;}
10114   else
10115     {
10116       seq_index[0]=-1;
10117       return -1;
10118     }
10119 }
10120   
10121   
10122       
10123       
10124 Alignment* seq2subseq1( Alignment *A, Sequence *S,int use_aln, int percent,int max_nseq, int ms,char *weight_mode)
10125    {
10126      float **pw_weight,**sim_weight, **seq_weight;
10127      int a,b,c,d;
10128      float sum, chosen,last_chosen, last_nchosen,nchosen;
10129      int condition1, condition2;
10130      Sequence *NS;
10131      Alignment *NA;
10132      char **name, **seq;
10133      float score, best_score;
10134      int best_seq=0;
10135      int *seq_list, *used_seq_list;
10136      
10137      /*
10138        mode: 
10139            (trim)_<seq or aln>_%<percentage of tot weight to keep>_n<number of seq to keep>_w<weight mode>
10140      */
10141      
10142      sim_weight=get_weight   ((use_aln)?A:NULL, S, weight_mode);
10143      pw_weight=declare_float (S->nseq, S->nseq);
10144      seq_weight=declare_float ( S->nseq, 2);
10145
10146      
10147      for (best_score=0,a=0; a<S->nseq; a++)
10148        {
10149          for ( b=0; b<S->nseq; b++)
10150            {
10151              if ( a==b)continue;
10152              seq_weight[a][0]+=sim_weight[a][b];
10153            }
10154          seq_weight[a][0]=seq_weight[a][0]/(S->nseq-1);
10155          score=seq_weight[a][0]=100-seq_weight[a][0];
10156          
10157          if ( score>best_score)
10158            {
10159              best_seq=a;
10160              best_score=score;
10161            }
10162
10163        }
10164       for (a=0; a<S->nseq; a++)
10165        {
10166          for ( b=0; b<S->nseq; b++)
10167            {
10168              if ( a==b)continue;
10169              pw_weight[a][b]=sim_weight[a][b]*seq_weight[a][0]*seq_weight[b][0]/(100*100);
10170              
10171            }
10172        }
10173       
10174  
10175      seq_list=vcalloc ( S->nseq, sizeof (int));
10176      used_seq_list=vcalloc ( S->nseq, sizeof (int));
10177
10178     
10179
10180      name=declare_char (S->nseq, (MAXNAMES+1));
10181      seq= declare_char (S->nseq, S->max_len+1);
10182      
10183      /*compute the normalization factor*/
10184      for (sum=0,d=0; d< S->nseq; d++)
10185            {
10186              for (score=0,c=0; c<S->nseq; c++)
10187                {
10188                  if ( c!=d)
10189                    score=MAX(score, 100-sim_weight[c][d]);
10190                }
10191              sum+=score;
10192            }
10193      sum=sum/S->nseq;
10194      /*chose the first sequence */
10195      for ( best_score=0,a=0; a< S->nseq; a++)
10196        {
10197          for (score=0, b=0; b< S->nseq; b++)
10198            {
10199              score+=100-sim_weight[a][b];
10200            }
10201          if ( score>best_score)
10202            {
10203              best_seq=a;
10204              best_score=score;
10205            }
10206          
10207        }
10208
10209
10210      last_chosen=chosen=((best_score/S->nseq)*100)/sum;
10211      nchosen=last_nchosen=1;
10212      seq_list[0]=best_seq;
10213      used_seq_list[best_seq]=1;
10214
10215      sprintf ( name[0],"%s", S->name[seq_list[0]]);
10216      sprintf ( seq[0],"%s", S->seq[seq_list[0]]);
10217      nchosen=last_nchosen=1;
10218      
10219
10220      fprintf ( stderr, "\nTRIM:\n");
10221      fprintf ( stderr, "\n1-Chosen Sequences\n");
10222      /*Assemble the list of sequences*/
10223      for (a=1; a< S->nseq; a++)
10224        {
10225          for (best_score=0,b=0; b< S->nseq; b++)
10226            {
10227              if (used_seq_list[b]);
10228              else
10229                {
10230                  score=pw_weight[seq_list[0]][b]+1;
10231                  for (c=0; c<a; c++)
10232                    score=MIN(score,pw_weight[seq_list[c]][b]);
10233                    
10234                  if ( score>=best_score)
10235                    {
10236                    best_seq=b;
10237                    best_score=score;
10238                    }
10239                
10240                }
10241            }
10242          seq_list[a]=best_seq;
10243          used_seq_list[best_seq]=1;
10244          
10245          
10246
10247          for ( chosen=0,d=0; d< S->nseq; d++)
10248            {
10249              for (score=0, c=0; c<=a; c++)
10250                {
10251                  if ( seq_list[c]!=d)
10252                    score=MAX(score, 100-sim_weight[seq_list[c]][d]);
10253                }
10254              chosen+=score;
10255              
10256            }
10257          
10258          chosen=((chosen/S->nseq)*100)/sum;
10259          nchosen=a+1;
10260                  
10261          condition1= (int)chosen<=(int)percent || !percent;
10262          condition2=(nchosen)<=max_nseq     || !max_nseq;
10263          
10264          if (condition1 && condition2)
10265            {
10266              fprintf ( stderr, "\tADD %s (set score: %.2f %%)\n", S->name[seq_list[a]], chosen);
10267              sprintf ( name[a],"%s", S->name[seq_list[a]]);
10268              sprintf ( seq[a],"%s", S->seq[seq_list[a]]);
10269              
10270            }
10271          else
10272            {
10273              break;      
10274            }
10275          last_chosen=chosen;
10276          last_nchosen=nchosen;
10277        }
10278        
10279      NS=fill_sequence_struc (last_nchosen,seq,name);
10280      NA=seq2aln(NS,NULL,1);      
10281      fprintf ( stderr, "\n2-Informations:\n");
10282      fprintf ( stderr, "\tUse...........: %s\n",(use_aln)?"multiple_aln":"pairwise_aln");
10283      fprintf ( stderr, "\tweight_mode...: %s\n"  ,weight_mode);
10284      fprintf ( stderr, "\tpercent_weight: %.2f%% (max=%d%%)\n",last_chosen,percent);
10285      fprintf ( stderr, "\tn_seq.........: %d\n"  ,NS->nseq);
10286      fprintf ( stderr, "\treduction.....: %d%% of original set\n"  ,(NS->nseq*100)/S->nseq);
10287      
10288      return NA;
10289    }   
10290 Sequence  * seq_weight2species_weight (Alignment *A, Sequence *S)
10291 {
10292   float *wsp;
10293   float *wseq;
10294   int a,b;
10295   
10296   S->W=declare_weights(S->nseq);
10297   if (!A->S || !(A->S)->W)aln2voronoi_weights (A);
10298   
10299   wseq=((A->S)->W)->SEQ_W;
10300   wsp=(S->W)->SEQ_W;
10301   for ( a=0; a< S->nseq; a++)
10302     {
10303       for (b=0; b<A->nseq; b++)
10304         if ( strstr (A->name[b], S->name[a]))wsp[a]+=wseq[b];
10305     }
10306   for (a=0; a<S->nseq; a++)
10307     fprintf ( stderr, "\nVoronoi Weights: Species %s ---> %.2f\n", S->name[a], wsp[a]);
10308   return S;
10309 }
10310 Alignment * aln2voronoi_weights (Alignment *A)
10311 {
10312   int a, b, c;
10313   float t=0;
10314   int **tab;
10315   float *w;
10316   
10317   tab=declare_int (256, A->nseq+1);
10318   if (A->S)free_sequence (A->S, (A->S)->nseq);
10319   A->S=aln2seq(A);
10320   (A->S)->W=declare_weights (A->nseq);
10321   w=((A->S)->W)->SEQ_W;
10322  
10323   for (a=0; a<A->len_aln; a++)
10324     {
10325       for ( b=0; b<A->nseq; b++)
10326         {
10327           c= A->seq_al[b][a];
10328           if (!is_gap(c))
10329             {
10330               c=tolower(c);
10331               tab[c][++tab[c][0]]=b;
10332             }
10333         }
10334       for (c=0; c<256; c++)
10335         {
10336           if (tab[c][0])
10337             {
10338               for (b=1; b<=tab[c][0]; b++)
10339                 {
10340                   w[tab[c][b]]+=(float)1/(float)tab[c][0];
10341                   t+=(float)1/(float)tab[c][0];
10342                 }
10343             }
10344           tab[c][0]=0;
10345         }
10346     }
10347   for (a=0; a<A->nseq; a++)
10348     {
10349       w[a]=(w[a]/t)*A->nseq;
10350     }
10351   
10352   return A;
10353 }
10354             
10355 float ** get_weight ( Alignment *A, Sequence *S, char *mode)
10356 {
10357  char *aln_name;
10358  char *weight_name;
10359  char *seq_name;
10360  char command[LONG_STRING];
10361  char program[LONG_STRING];
10362  float **weight;
10363  FILE *fp;
10364  int c;
10365   
10366  if ( !mode || !mode[0] || strm (mode, "msa"))
10367       {
10368         if ( getenv ( "SEQ2MSA_WEIGHT")==NULL)sprintf (program, "%s",SEQ2MSA_WEIGHT);
10369         else sprintf ( program, "%s", (getenv ( "SEQ2MSA_WEIGHT")));   
10370       }
10371  else if ( strm(mode, "pwsim") ||strm(mode, "pwsim_fragment") )
10372       {
10373         return seq2pwsim (A, S, mode);
10374       }
10375  else
10376      {
10377        if (getenv (mode))sprintf ( program, "%s", (getenv (mode)));
10378        else fprintf ( stderr, "\nERROR: %s is not a valid mode for weight computation [FATAL:%s]", mode, PROGRAM);
10379      }
10380
10381  /*MSA weights*/
10382  seq_name=vtmpnam(NULL);
10383  aln_name=vtmpnam(NULL);
10384  weight_name=vtmpnam(NULL);
10385  weight=declare_float (S->nseq+1, 2);
10386  
10387
10388   
10389   if (A)
10390     {
10391       output_clustal_aln (seq_name,A);
10392       output_fasta_seq   (aln_name,A);
10393       sprintf ( command, "%s %s -i %s -w %s", program, seq_name, aln_name, weight_name);
10394     }
10395   else
10396     {
10397       A=seq2aln(S,A,1);
10398       output_fasta_seq   (seq_name,A);
10399       sprintf ( command, "%s %s -w %s", program, seq_name, weight_name);
10400     }
10401   
10402  
10403   my_system ( command);
10404   
10405   fp=vfopen( weight_name, "r");
10406   while ( (c=fgetc(fp))!='$');
10407   c=fgetc(fp);
10408   c=0;
10409   while ( (fscanf (fp, "%*s %f\n",&(weight[c][1])))==1)
10410     {weight[c][0]=c;c++;}
10411   vfclose (fp);
10412   
10413   
10414   return weight;
10415 }
10416
10417 float **seq2pwsim (        Alignment *A, Sequence *S, char *mode)
10418 {
10419   int a, b, c;
10420   float d,t;
10421   float  **W;
10422   Alignment *B;
10423   W=declare_float (S->nseq, S->nseq);
10424
10425
10426
10427   for (a=0; a< S->nseq; a++)
10428         for ( b=a; b<S->nseq; b++)
10429           {
10430             if ( a==b){d=1;}
10431             else if (!A)
10432               {
10433
10434                 B=align_two_sequences ((S)->seq[a], (S)->seq[b],"pam250mt", -10, -1, "fasta_pair_wise");
10435                 for (t=0,d=0,c=0; c<B->len_aln; c++)
10436                   {
10437                     d+=(B->seq_al[0][c]==B->seq_al[1][c] && !is_gap(B->seq_al[0][c]));
10438                     t+=(!is_gap(B->seq_al[0][c]) && !is_gap(B->seq_al[1][c]));
10439                   }
10440                 t=(strm ( mode, "pwsim_fragment"))?B->len_aln:t;
10441                 
10442                 d=d/((t==0)?1:t);
10443                 free_aln(B);
10444               }
10445             else
10446               {
10447                 for (t=0,d=0,c=0; c<A->len_aln; c++)
10448                   {
10449                     d+=(A->seq_al[a][c]==A->seq_al[b][c] && !is_gap(A->seq_al[a][c]));
10450                     t+=(!is_gap(A->seq_al[a][c]) && !is_gap(A->seq_al[b][c]));
10451                   }
10452                 d=d/((t==0)?1:t);
10453               }
10454           
10455
10456             W[a][b]=W[b][a]=(1-d)*100;
10457           }
10458  
10459   
10460   return W;
10461
10462 }
10463  
10464 float **seq2pwsim_fragment (       Alignment *A, Sequence *S, char *mode)
10465 {
10466
10467   
10468   int a, b, c;
10469   float d,t;
10470   float  **W;
10471   Alignment *B;
10472   W=declare_float (S->nseq, S->nseq);
10473
10474
10475
10476
10477   for (a=0; a< S->nseq; a++)
10478         for ( b=a; b<S->nseq; b++)
10479           {
10480             if ( a==b){d=1;}
10481             else if (!A)
10482               {
10483
10484                 B=align_two_sequences ((S)->seq[a], (S)->seq[b],"pam250mt", -10, -1, "fasta_pair_wise");
10485                 for (t=0,d=0,c=0; c<B->len_aln; c++)
10486                   {
10487                     d+=(B->seq_al[0][c]==B->seq_al[1][c] && !is_gap(B->seq_al[0][c]));
10488                     t+=(!is_gap(B->seq_al[0][c]) && !is_gap(B->seq_al[1][c]));
10489                   }
10490         
10491                 d=d/((t==0)?1:t);
10492                 free_aln(B);
10493               }
10494             else
10495               {
10496                 for (t=0,d=0,c=0; c<A->len_aln; c++)
10497                   {
10498                     d+=(A->seq_al[a][c]==A->seq_al[b][c] && !is_gap(A->seq_al[a][c]));
10499                     t+=(!is_gap(A->seq_al[a][c]) && !is_gap(A->seq_al[b][c]));
10500                   }
10501                 d=d/((t==0)?1:t);
10502               }
10503           
10504
10505             W[a][b]=W[b][a]=(1-d)*100;
10506           }
10507  
10508   
10509   return W;
10510
10511
10512
10513 /********************************************************************/
10514 /*                                                                  */
10515 /*                      AMINO ACID FUNCTIONS                        */
10516 /*                                                                  */
10517 /*                                                                  */
10518 /*                                                                  */
10519 /********************************************************************/
10520 //Builds an extended alphabet from a string
10521 char** string2alphabet (char *string, int depth, int *falp_size)
10522 {
10523   int max_s;
10524   int a, b,c, l, n;
10525   char buf[1000];
10526   char **alp;
10527   int alp_size;
10528   
10529   char ***alp2;
10530   int *alp2_size;
10531   
10532   int *array;
10533   char **falp;
10534   
10535   
10536   l=strlen (string);
10537   array=vcalloc ( 256, sizeof (int));
10538   
10539
10540   max_s=l+1;
10541   falp_size[0]=0;
10542   falp=declare_char (l+1, 2);
10543   
10544   alp=declare_char(l,2);
10545   alp_size=0;
10546   
10547   array=vcalloc ( 256, sizeof (int));
10548   for (a=0;a<l; a++)
10549     {
10550       if (!array[(int)string[a]])
10551         {
10552           array[(int)string[a]]=1;
10553           sprintf (alp[alp_size++], "%c", string[a]);
10554           sprintf (falp[falp_size[0]++], "%c", string[a]);
10555         }
10556     }
10557   sprintf ( falp[falp_size[0]++], "*");
10558   vfree (array);
10559   
10560   if ( depth==1)
10561     {
10562       free_char (alp, -1);
10563       return falp;
10564     }
10565   alp2=vcalloc ( depth, sizeof (char**));
10566   alp2_size=vcalloc (depth, sizeof (int));
10567   
10568   for (a=0; a<depth; a++)
10569     {
10570       alp2[a]=alp;
10571       alp2_size[a]=alp_size;
10572     }
10573   
10574
10575   for (a=2; a<=depth; a++)
10576     {
10577       char ***result_array;
10578       
10579       result_array=generate_array_string_list (a, alp2, alp2_size, &n, NULL, NO_OVERLAP);
10580       max_s+=n+1;
10581       falp=vrealloc (falp, sizeof (char**)*max_s);
10582       for (b=0; b<n; b++)
10583         {
10584           buf[0]='\0';
10585           for (c=0; c<a; c++)
10586             {
10587               strcat (buf, result_array[b][c]);
10588             }
10589           falp[falp_size[0]]=vcalloc (strlen (buf)+1, sizeof (char));
10590           sprintf ( falp[falp_size[0]++], "%s", buf);
10591           vfree ( result_array[b]);
10592         }
10593       vfree (result_array);
10594       
10595     }
10596
10597   falp[falp_size[0]]=vcalloc (2, sizeof (char));
10598   sprintf ( falp[falp_size[0]++], "*");
10599   free_char (alp, -1);
10600   return falp;
10601 }
10602
10603 char** make_group_aa (int *ngroup, char *mode)
10604         {
10605 /*mode:         indicates which matrix will be used for the grouping*/
10606 /*n_group:      pointer to the number of groups                     */
10607 /*return value: an array of strings containing the AA of each group */
10608
10609
10610         int **matrix;
10611         int a, b,c,is_in;
10612         char buf[28];
10613         char **group_list;
10614         char *matrix_name;
10615         int extend=0;
10616         matrix_name=vcalloc ( 100, sizeof (char));
10617
10618         if (ngroup[0]==-1)extend=1;
10619         
10620         ngroup[0]=0;
10621         group_list=declare_char ( 100, 27);
10622         
10623         if (extend)
10624           {
10625             sprintf ( group_list[ngroup[0]++], "gG");
10626             sprintf ( group_list[ngroup[0]++], "pP");
10627             sprintf ( group_list[ngroup[0]++], "aA");
10628             sprintf ( group_list[ngroup[0]++], "cC");
10629             sprintf ( group_list[ngroup[0]++], "dD");
10630             sprintf ( group_list[ngroup[0]++], "eE");
10631             
10632             sprintf ( group_list[ngroup[0]++], "fF"); 
10633             sprintf ( group_list[ngroup[0]++], "hH");
10634             sprintf ( group_list[ngroup[0]++], "iI");
10635             sprintf ( group_list[ngroup[0]++], "kK");
10636             sprintf ( group_list[ngroup[0]++], "lL");
10637             sprintf ( group_list[ngroup[0]++], "mM");
10638             sprintf ( group_list[ngroup[0]++], "nN");
10639             sprintf ( group_list[ngroup[0]++], "qQ");
10640             sprintf ( group_list[ngroup[0]++], "rR");
10641             
10642             sprintf ( group_list[ngroup[0]++], "sS");
10643             sprintf ( group_list[ngroup[0]++], "tT");
10644             sprintf ( group_list[ngroup[0]++], "vV");
10645             sprintf ( group_list[ngroup[0]++], "wW");
10646             sprintf ( group_list[ngroup[0]++], "*");
10647           }
10648         
10649         if ( mode && mode[0]=='_'){mode++;sprintf ( matrix_name, "%s", mode);}
10650
10651         if (mode==NULL || mode[0]=='\0')sprintf ( matrix_name, "idmat");
10652         else if ( strstr (mode, "sim") || strm (mode, "idmat") || mode==NULL)
10653           { 
10654             sprintf ( group_list[ngroup[0]++], "aA");
10655             sprintf ( group_list[ngroup[0]++], "bB");
10656             sprintf ( group_list[ngroup[0]++], "cC");
10657             sprintf ( group_list[ngroup[0]++], "dD");
10658             sprintf ( group_list[ngroup[0]++], "eE");
10659             sprintf ( group_list[ngroup[0]++], "fF");
10660             sprintf ( group_list[ngroup[0]++], "gG");
10661             sprintf ( group_list[ngroup[0]++], "hH");
10662             sprintf ( group_list[ngroup[0]++], "iI");
10663             sprintf ( group_list[ngroup[0]++], "jJ");
10664             sprintf ( group_list[ngroup[0]++], "kK");
10665             sprintf ( group_list[ngroup[0]++], "lL");
10666             sprintf ( group_list[ngroup[0]++], "mM");
10667             sprintf ( group_list[ngroup[0]++], "nN");
10668             sprintf ( group_list[ngroup[0]++], "oO");
10669             sprintf ( group_list[ngroup[0]++], "pP");
10670             sprintf ( group_list[ngroup[0]++], "qQ");
10671             sprintf ( group_list[ngroup[0]++], "rR");
10672             sprintf ( group_list[ngroup[0]++], "sS");
10673             sprintf ( group_list[ngroup[0]++], "tT");
10674             sprintf ( group_list[ngroup[0]++], "uU");
10675             sprintf ( group_list[ngroup[0]++], "vV");
10676             sprintf ( group_list[ngroup[0]++], "wW");
10677             sprintf ( group_list[ngroup[0]++], "xX");
10678             sprintf ( group_list[ngroup[0]++], "yY");
10679             sprintf ( group_list[ngroup[0]++], "zZ");
10680             vfree (matrix_name);
10681             return group_list;
10682           }
10683         else if ( strm (mode, "simple"))
10684              {
10685                sprintf ( group_list[ngroup[0]++], "avilmAVILM");
10686                  sprintf ( group_list[ngroup[0]++], "dekrDEKR");
10687                  sprintf ( group_list[ngroup[0]++], "stcnqhSTCNQH");
10688                  sprintf ( group_list[ngroup[0]++], "wfyWFY");
10689                  sprintf ( group_list[ngroup[0]++], "gG");
10690                  sprintf ( group_list[ngroup[0]++], "pP");
10691                  vfree (matrix_name);
10692                  return group_list;
10693              }
10694
10695         else if ( strm (mode, "mafft"))
10696              {
10697                 
10698                
10699                sprintf ( group_list[ngroup[0]++],"agjopstAGJOPST");
10700                sprintf ( group_list[ngroup[0]++],"ilmvILMV");
10701                sprintf ( group_list[ngroup[0]++],"bdenqzBDENQZ");
10702                sprintf ( group_list[ngroup[0]++],"hkrHKR");
10703                sprintf ( group_list[ngroup[0]++],"fwyFWY");
10704                sprintf ( group_list[ngroup[0]++],"cC");
10705                vfree (matrix_name);
10706                return group_list;
10707              }
10708         else if ( strm (mode, "clustalw"))
10709              {
10710                  
10711                  sprintf ( group_list[ngroup[0]++],"astaASTA");
10712                  sprintf ( group_list[ngroup[0]++],"bneqkBNEQK");
10713                  sprintf ( group_list[ngroup[0]++],"cnhqkCNHQK");
10714                  sprintf ( group_list[ngroup[0]++],"dndeqDNDEQ");
10715                  sprintf ( group_list[ngroup[0]++],"eqhrkEQHRK");
10716                  sprintf ( group_list[ngroup[0]++],"fmilvFMILV");
10717                  sprintf ( group_list[ngroup[0]++],"gmilfGMILF");
10718                  sprintf ( group_list[ngroup[0]++],"hhyHHY");
10719                  sprintf ( group_list[ngroup[0]++],"ifywIFYW");
10720                  sprintf ( group_list[ngroup[0]++],"jcJC");
10721                  sprintf ( group_list[ngroup[0]++],"kpKP");
10722                  vfree (matrix_name);
10723                  return group_list;
10724              }
10725         else if ( strm (mode, "polarity"))
10726              {
10727                  
10728                sprintf ( group_list[ngroup[0]++],"eqrsdnkhtEQRSDNKHT");
10729                sprintf ( group_list[ngroup[0]++],"pP");
10730                sprintf ( group_list[ngroup[0]++],"gG");
10731                sprintf ( group_list[ngroup[0]++],"cC");
10732                sprintf ( group_list[ngroup[0]++],"fywFYW");
10733                sprintf ( group_list[ngroup[0]++],"iavlmIAVLM");
10734                vfree (matrix_name);
10735                return group_list;
10736              }
10737         else if ( strm (mode, "vasiliky"))
10738              {
10739                  ngroup[0]=0;
10740                  sprintf ( group_list[ngroup[0]++], "rkRK");
10741                  sprintf ( group_list[ngroup[0]++], "deDE");
10742                  sprintf ( group_list[ngroup[0]++], "qhQH");
10743                  sprintf ( group_list[ngroup[0]++], "vilmVILM");
10744                  sprintf ( group_list[ngroup[0]++], "fyFY");
10745                  sprintf ( group_list[ngroup[0]++], "sS");
10746                  sprintf ( group_list[ngroup[0]++], "wW");
10747                  sprintf ( group_list[ngroup[0]++], "aA");
10748                  sprintf ( group_list[ngroup[0]++], "cC");
10749                  sprintf ( group_list[ngroup[0]++], "gG");
10750                  sprintf ( group_list[ngroup[0]++], "nN");
10751                  sprintf ( group_list[ngroup[0]++], "pP");
10752                  sprintf ( group_list[ngroup[0]++], "tT");
10753                  vfree (matrix_name);
10754                  return group_list;
10755              }
10756         else if ( strm (mode, "clustalw_col"))
10757              {
10758                  sprintf ( group_list[ngroup[0]++], "staSTA");
10759                  sprintf ( group_list[ngroup[0]++], "neqkNEQK");
10760                  sprintf ( group_list[ngroup[0]++], "nhqkNHQK");
10761                  sprintf ( group_list[ngroup[0]++], "ndeqNDEQ");
10762                  sprintf ( group_list[ngroup[0]++], "qhrkQHRK");
10763                  sprintf ( group_list[ngroup[0]++], "milvMILV");
10764                  sprintf ( group_list[ngroup[0]++], "milfMILF");
10765                  sprintf ( group_list[ngroup[0]++], "hyHY");
10766                  sprintf ( group_list[ngroup[0]++], "fywFYW");
10767                  sprintf ( group_list[ngroup[0]++], "gG");
10768                  sprintf ( group_list[ngroup[0]++], "pP");
10769                  sprintf ( group_list[ngroup[0]++], "cC");
10770                  vfree (matrix_name);
10771                  
10772                  return group_list;
10773              }
10774         else if ( strm (mode, "clustalw_dot"))
10775              {
10776                  sprintf ( group_list[ngroup[0]++], "csaCSA");
10777                  sprintf ( group_list[ngroup[0]++], "atvATV");
10778                  sprintf ( group_list[ngroup[0]++], "sagSAG");
10779                  sprintf ( group_list[ngroup[0]++], "stnkSTNK");
10780                  sprintf ( group_list[ngroup[0]++], "stpaSTPA");
10781                  sprintf ( group_list[ngroup[0]++], "sgndSGND");
10782                  sprintf ( group_list[ngroup[0]++], "sndeqkSNDEQK");
10783                  sprintf ( group_list[ngroup[0]++], "ndeqhkNDEQHK");
10784                  sprintf ( group_list[ngroup[0]++], "neqhrkNEQHRK");
10785                  sprintf ( group_list[ngroup[0]++], "fvlimFVLIM");
10786                  sprintf ( group_list[ngroup[0]++], "hfyHFY");
10787                  vfree (matrix_name);
10788                  return group_list;
10789              }
10790         else if ( strm (mode, "make_all"))
10791              {
10792                  ngroup[0]=1;
10793                  sprintf ( group_list[0], "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
10794                  vfree (matrix_name);
10795                  return group_list;
10796              }
10797         else sprintf ( matrix_name, "%s", mode);
10798         
10799         matrix=read_matrice ( matrix_name); 
10800         
10801         for ( a=0;a< 26; a++)
10802                 {
10803                 if ( matrix[a][a]>0)
10804                         {
10805                         for ( c=0,b=0;b< 26; b++)
10806                                 {
10807                                 
10808                                 if ( matrix[a][b]>0 && matrix[b][b]>0)
10809                                         {
10810                                         buf[c++]=b+'A';
10811                                         buf[c++]=b+'a';
10812                                         }
10813                                 }
10814                         buf[c]='\0';
10815                         for ( is_in=0,b=0; b< ngroup[0]; b++)if ( strcmp (buf, group_list[b])==0)is_in=1;
10816                         if (is_in==0)sprintf ( group_list[ngroup[0]++], "%s", buf);
10817                                         
10818                         }
10819                 }
10820         free_int (matrix, -1); 
10821         vfree (matrix_name);
10822                  
10823         return group_list;
10824         }
10825 char** make_group_aa_upgma (char*matrix, int max_n)
10826         {
10827           char **group_list;
10828           int **mat;
10829           int *used;
10830           int a, b, ba, bb, best, set, l, n;
10831           l=26;
10832           
10833           group_list=declare_char (l+1, l+1);
10834           for (a=0; a<l; a++)group_list[a][0]='a'+a;
10835           mat=read_matrice(matrix);
10836           used=vcalloc ( l, sizeof (int));
10837           n=l;
10838                   
10839           while (n>max_n)
10840             {
10841               for (set=0,a=0; a<l-1; a++)
10842                 for (b=a+1; b<l; b++)
10843                   {
10844                     if (used[a]||used[b])continue;
10845                     
10846                     if (set==0 || mat[a][b]>best)
10847                       {
10848                         best=mat[a][b];
10849                         ba=a;
10850                         bb=b;
10851                         set=1;
10852                       }
10853                   }
10854             
10855               for (a=0; a<l; a++)
10856                 {
10857                   mat[ba][a]=mat[a][ba]=(mat [ba][a]+mat[bb][a])/2;
10858                   used[bb]=1;
10859                 }
10860               strcat (group_list[ba], group_list[bb]);
10861               vfree (group_list[bb]);
10862               group_list[bb]=NULL;
10863           
10864               n--;
10865             }
10866         
10867           for (n=0,a=0; a<l; a++)
10868             {
10869               if ( group_list[a])
10870                 group_list[n++]=group_list[a];
10871             }
10872           vfree (used); free_int (mat, -1);
10873           return group_list;
10874         }
10875
10876 int find_group_aa_distribution (char *col, int nseq,int n_group, char **gl,  int *distrib, char *mode )
10877         {
10878         static int *distribution;
10879         static char **lgl;
10880         static int ln_group;
10881         int a, b, c;
10882         int *d;
10883         char **gl2;
10884         int n_group2;
10885         
10886         
10887         
10888         if ( lgl==NULL)
10889                 lgl=make_group_aa ( &ln_group, mode);
10890                 
10891                 if ( gl==NULL)
10892                 {
10893                 gl2=lgl;
10894                 n_group2=ln_group;
10895                 }
10896         else
10897                 {
10898                 gl2=gl;
10899                 n_group2=n_group;
10900                 }
10901         
10902         if ( distribution==NULL || ln_group<n_group)distribution=vcalloc ( n_group2, sizeof (int));
10903         if ( distrib==NULL)d=distribution;
10904         else d=distrib;
10905         
10906         
10907         for ( a=0; a< n_group2; a++)d[a]=0;
10908         
10909         for ( a=0; a< nseq; a++)
10910                 {
10911                 for ( b=0; b< n_group2; b++)
10912                         d[b]+=is_in_set (col[a], gl2[b]);
10913                 }
10914         c=d[0];
10915         for ( a=0; a< n_group2; a++)
10916                 c=(d[a]>c)?d[a]:c;
10917         return c;
10918         }
10919
10920
10921
10922 int is_in_same_group_aa ( char r1, char r2, int n_group, char **gl, char *mode)
10923         {
10924         int a;
10925         static char **lgl;
10926         static int ln_group;
10927         
10928         char **gl2;
10929         int n_group2;
10930         
10931         /*use mode=idmat for similarity based on id*/
10932
10933         r1=toupper(r1);
10934         r2=toupper(r2);
10935         if (mode==NULL)return (r1==r2)?1:0;
10936         
10937         if ( strm (mode, "clean"))
10938              {
10939              free_char (lgl, -1);
10940              lgl=NULL;
10941              ln_group=0;
10942              return 0;
10943              }
10944         else if ( strstr (mode, "cov"))
10945           {
10946             return 1;
10947           }
10948         
10949         if ( lgl==NULL)
10950                 {
10951                   lgl=make_group_aa ( &ln_group, mode);
10952                 }
10953                 
10954         if ( gl==NULL)
10955                 {
10956                 gl2=lgl;
10957                 n_group2=ln_group;
10958                 }
10959         else
10960                 {
10961                 gl2=gl;
10962                 n_group2=n_group;
10963                 }
10964         
10965         for ( a=0; a< n_group2; a++)
10966                 if ( is_in_set ( r1, gl2[a]) && is_in_set ( r2, gl2[a]))return 1;
10967                 return 0;
10968         }
10969                         
10970
10971 Alignment * gene2prot (Alignment *A){return A; }
10972 char * test_gene2prot (Constraint_list *CL, int s1)
10973        {
10974            int a, b,q, nal;
10975            int F=-10000000; /*FORBIDEN STATE*/
10976            int AL=0;       /*ALLOWED STATE*/
10977            int SPLICE_PENALTY=1000;
10978            int FRAME_PENALTY=1000;
10979            
10980
10981            int START,  ORF1,  ORF2, ORF3, s5NC; 
10982            int s3NC,ORF3_G1, ORF3_T2, ORF3_NC, ORF3_A3, ORF3_T4;
10983            int U1_G1,   U1_T2,   U1_NC,   U1_A3,   U1_T4;
10984            int U2_G1,   U2_T2,   U2_NC,   U2_A3,   U2_T4;
10985            int U1,     U2, U3,  U4, U5, END;
10986            
10987            int nstate=0;
10988            int **transitions;
10989            int **v_tab;
10990            int **v_tab_p;
10991            int **last_coding;
10992            int **last_t4;
10993            int *potential;
10994            int v;
10995
10996            int orf1, orf2, orf3, ncp, p, state, pstate, e, best_state_p=0, best_state_v=0, best_pstate_p=0, best_pstate_v;
10997            char *seq, *seq2, *seq3;
10998            int l;
10999            int  *is_coding;
11000            int *is_t4;
11001            char *codon;
11002            int s, r, s2, r2, w2;
11003            
11004            static int *entry;
11005            int tot=0;
11006            
11007            seq=vcalloc ( strlen ((CL->S)->seq[s1])+1, sizeof (char));
11008            seq2=vcalloc ( strlen ((CL->S)->seq[s1])+1, sizeof (char));
11009            seq3=vcalloc ( strlen ((CL->S)->seq[s1])+1, sizeof (char));
11010            sprintf ( seq, "%s", (CL->S)->seq[s1]);
11011            ungap (seq);
11012
11013            l=strlen (seq);
11014            for ( a=0; a< l; a++) seq[a]=tolower ( seq[a]);
11015            for ( a=0; a< l; a++) seq[a]=(seq[a]=='t')?'u': seq[a];
11016            
11017
11018            potential=vcalloc (l+1, sizeof (int));
11019            
11020            for (nal=0, s=0; s<(CL->S)->nseq; s++)
11021              {
11022                for ( r=1; r<=(CL->S)->len[s]; r++)
11023                  {
11024                    for ( b=1; b<CL->residue_index[s1][r][0]; b++)
11025                      {
11026                        
11027                        s2=CL->residue_index[s][r][b+SEQ2];
11028                        r2=CL->residue_index[s][r][b+R2];
11029                        w2=CL->residue_index[s][r][b+WE];
11030                        if (s==s1)potential[r-1]+=w2;
11031                        else if ( s2==s1)potential[r2-1]+=w2;
11032                        tot+=w2;
11033                        nal++;
11034                      }
11035                  }
11036              }
11037            
11038            
11039            SPLICE_PENALTY=10000;
11040            FRAME_PENALTY=1000;
11041
11042            
11043            nstate=0;
11044            START=nstate++;  ORF1=nstate++;  ORF2=nstate++; ORF3=nstate++; s5NC=nstate++; 
11045            s3NC=nstate++;
11046            ORF3_G1=nstate++;U1_G1=nstate++;U2_G1=nstate++; 
11047            ORF3_T2=nstate++;U1_T2=nstate++;U2_T2=nstate++;
11048            ORF3_NC=nstate++;U1_NC=nstate++;U2_NC=nstate++; 
11049            ORF3_A3=nstate++;U1_A3=nstate++;U2_A3=nstate++; 
11050            ORF3_T4=nstate++;U1_T4=nstate++;U2_T4=nstate++;
11051            
11052            
11053            U1=nstate++;     U2=nstate++; U3=nstate++;  U4=nstate++; U5=nstate++;  
11054            END=nstate++;
11055            
11056            is_coding=vcalloc ( nstate, sizeof (int));
11057            is_coding[ORF1]=is_coding[ORF2]=is_coding[ORF3]=is_coding[U1]=is_coding[U2]=1;
11058            is_coding[U3]=is_coding[U4]=is_coding[U5]=1;
11059            
11060            is_t4=vcalloc ( nstate, sizeof (int));
11061            is_t4[ORF3_T4]=is_t4[U1_T4]=is_t4[U2_T4]=1;
11062            transitions=declare_int ( nstate, nstate);
11063            for (a=0; a< nstate; a++)
11064                    for ( b=0; b< nstate; b++)transitions[a][b]=F;
11065            
11066            transitions[START][ORF1]=AL;
11067            transitions[START][s5NC]=AL-FRAME_PENALTY;
11068            transitions[s5NC][s5NC]=AL;
11069
11070            transitions[s5NC][ORF1]=AL-FRAME_PENALTY;
11071
11072            transitions[ORF1][ORF2]=AL;
11073            transitions[ORF2][ORF3]=AL;
11074            transitions[ORF3][U1]=AL;
11075            transitions[ORF3][ORF1]=AL;
11076            transitions[ORF3][ORF3_G1]=AL-SPLICE_PENALTY;
11077            
11078            
11079            transitions[ORF3_G1][ORF3_T2]=AL;
11080            transitions[ORF3_T2][ORF3_NC]=AL;
11081            transitions[ORF3_NC][ORF3_NC]=AL;
11082            transitions[ORF3_NC][ORF3_A3]=AL;
11083            transitions[ORF3_A3][ORF3_T4]=AL;
11084            transitions[ORF3_T4][ORF1]=AL-SPLICE_PENALTY;
11085
11086            transitions[U1][U2]=AL;
11087            transitions[U1][U1_G1]=AL-SPLICE_PENALTY;
11088            transitions[U1_G1][U1_T2]=AL;
11089            transitions[U1_T2][U1_NC]=AL;
11090            transitions[U1_NC][U1_NC]=AL;
11091            transitions[U1_NC][U1_A3]=AL;
11092            transitions[U1_A3][U1_T4]=AL;
11093            transitions[U1_T4][U3]=AL-SPLICE_PENALTY;
11094            transitions[U3][U4]=AL;
11095            transitions[U4][ORF1]=AL;
11096            
11097            transitions[U2][U2_G1]=AL-SPLICE_PENALTY;
11098            transitions[U2_G1][U2_T2]=AL;
11099            transitions[U2_T2][U2_NC]=AL;
11100            transitions[U2_NC][U2_NC]=AL;
11101            transitions[U2_NC][U2_A3]=AL;
11102            transitions[U2_A3][U2_T4]=AL;
11103            transitions[U2_T4][U5]=AL-SPLICE_PENALTY;
11104            transitions[U5][ORF1]=AL;
11105            
11106            transitions[ORF3][s3NC]=AL-FRAME_PENALTY;
11107            transitions[ORF3][END]=AL;
11108            transitions[s3NC][END]=AL;
11109
11110                    
11111            v_tab=declare_int ( l+1,nstate);
11112            v_tab_p=declare_int ( l+1,nstate);
11113            last_coding=declare_int ( l+1,nstate);
11114            last_t4=declare_int ( l+1,nstate);
11115
11116            for (a=0; a< l; a++) potential[a]-=200;
11117
11118            codon=vcalloc ( 4, sizeof (char));
11119            best_pstate_p=START;
11120            best_pstate_v=0;
11121            nal=0;
11122            for ( p=1; p<=l; p++)
11123                {
11124                if  (translate_dna_codon (seq+(p-1), 'x')=='x' || p>(l-2))orf1=F;
11125                else orf1=potential[p-1];
11126
11127                if  (p<2 || translate_dna_codon (seq+(p-2), 'x')=='x' || p>(l-1))orf2=F;
11128                else orf2=potential[p-1];
11129
11130                
11131                if  (p<3 || translate_dna_codon (seq+(p-3), 'x')=='x' || p>l)orf3=F;
11132                else orf3=potential[p-1];
11133                
11134                if ( best_int (3, 1, &a, orf1, orf2, orf3)!=F)ncp=-best_int (3, 1, &a, orf1, orf2, orf3);
11135                else ncp=1000;
11136                
11137                for ( state=0; state< nstate; state++)
11138                    {
11139                        
11140                        if      ( state==ORF1)e=orf1;
11141                        else if ( state==ORF2)e=orf2;
11142                        else if ( state==ORF3)e=orf3;
11143                        else if ( state>=U1 && state<=U3)
11144                            {
11145                            e=0;
11146                            }
11147                        else if ( state==U4)
11148                           {
11149                               codon[2]=seq[p-1];
11150                               codon[1]=seq[last_coding[p-1][U3]-1];
11151                               codon[0]=seq[last_coding[p-2][U1_T4]-1];
11152                               if ( translate_dna_codon (codon, 'x')=='x')e=F;
11153                               else e=0;
11154                           }
11155                        else if ( state==U5)
11156                           {
11157                               codon[2]=seq[p-1];
11158                               codon[1]=seq[last_coding[p-1][U2_T4]-1];
11159                               q=seq[last_coding[p-1][U2_T4]];
11160                               codon[0]=seq[last_coding[q-1][U1]-1];
11161                               if ( translate_dna_codon (codon, 'x')=='x')e=F;
11162                               else e=0;
11163                           }
11164
11165                        else if (state>=ORF3_G1 && state<=U2_G1)e=(p<l-1 && seq[p-1]=='g' && seq[p]=='u')?ncp:F;
11166                        else if ( state>=ORF3_T2 && state<=U2_T2)
11167                            {
11168                            e=(p>1 && seq[p-2]=='g' && seq[p-1]=='u')?ncp:F;
11169                            }
11170                        else if ( state>=ORF3_A3 && state<=U2_A3)e=(seq[p-1]=='a')?ncp:F;
11171                        else if ( state>=ORF3_T4 && state<=U2_T4)e=(seq[p-1]=='u')?ncp:F;
11172                        else e=ncp;
11173                        
11174                        for ( pstate=0; pstate<nstate; pstate++)
11175                            {
11176                                if (e==F ||  transitions[pstate][state]==F || v_tab[p-1][pstate]==F)v=F;
11177                                else v=e+transitions[pstate][state]+v_tab[p-1][pstate];
11178                                     
11179                                if ( pstate==0 || v>best_pstate_v)
11180                                   {best_pstate_v=v;best_pstate_p=pstate;}
11181                            }
11182                       v_tab[p][state]=best_pstate_v;
11183                       v_tab_p[p][state]=best_pstate_p; 
11184                       
11185                       if (!is_coding[state])last_coding[p][state]=last_coding[p-1][best_pstate_p];
11186                       else if (is_coding[state])last_coding[p][state]=p;
11187                       
11188                       if (!is_t4[state])
11189                          {
11190                              if (is_coding[state] && last_t4[p-1][best_pstate_p]==0)last_t4[p][state]=p;
11191                              else last_t4[p][state]=last_t4[p-1][best_pstate_p];
11192                          }
11193                       else if (is_t4[state])last_t4[p][state]=p;
11194                       
11195                       if (state==0 ||best_pstate_v>best_state_v ){best_state_p=state; best_state_v=best_pstate_v;}
11196                    }
11197                }
11198            tot=0;
11199            for ( p=l; p>0; p--)
11200                    {
11201                        if ( best_state_p>=ORF1 &&  best_state_p<=ORF3){seq2[tot++]=tolower (seq[p-1]);}
11202                        else if ( best_state_p>=U1 && best_state_p<=U5){seq2[tot++]=tolower (seq[p-1]);}
11203                        if (best_state_p==ORF1)seq[p-1]=toupper (seq[p-1]);
11204                        else if (best_state_p==ORF2 || best_state_p==ORF3)seq[p-1]=tolower (seq[p-1]);
11205                        else if ( best_state_p==ORF3_NC || best_state_p==U1_NC ||  best_state_p==U2_NC) seq[p-1]='.';
11206                        else if ( best_state_p==U1 || best_state_p==U2 || best_state_p==U3 || best_state_p==U4 || best_state_p==U5) seq[p-1]=best_state_p-U1+'1';
11207                        else seq[p-1]=toupper (seq[p-1]);
11208                        best_state_p=v_tab_p[p][best_state_p];
11209                    }
11210
11211            for ( a=0, b=tot-1; b>=0; b--, a++)
11212                seq3[a]=seq2[b];
11213            
11214            fprintf ( stderr, "\n%s\n", seq);
11215            fprintf ( stderr, "\nN coding=%d\n", tot);
11216            for ( a=0; a< tot; a+=3)
11217                 {
11218                 b=translate_dna_codon (seq3+a, 'x');
11219                 fprintf ( stderr, "%c",b);
11220                 if ( b=='x'){fprintf ( stderr, "\n");myexit (EXIT_SUCCESS);}
11221                 }
11222             
11223             fprintf ( stderr, "\n");      
11224             myexit (EXIT_SUCCESS);
11225             return 0;
11226             
11227                
11228             
11229        }
11230 Alignment * dna_aln2_3frame_cdna_aln(Alignment *A,int *ns,int **l_s)
11231 {
11232   Alignment *B;
11233   int a;
11234   B=realloc_aln2 (NULL,6,strlen(A->seq_al[l_s[0][0]])+strlen(A->seq_al[l_s[1][0]]));
11235   for ( a=0; a< 3; a++)  
11236     {    
11237       B->seq_al[a]=translate_dna_seq (A->seq_al[l_s[0][0]]+a, 0, 'o',B->seq_al[a]);
11238       B->seq_al[a+3]=translate_dna_seq (A->seq_al[l_s[1][0]]+a, 0, 'o',B->seq_al[a+3]);
11239     }
11240   for ( a=1; a<3; a++)
11241     {
11242       if ( strlen(B->seq_al[a])<strlen(B->seq_al[0])) B->seq_al[a]=strcat ( B->seq_al[a], "x");
11243       if ( strlen(B->seq_al[a+3])<strlen(B->seq_al[3])) B->seq_al[a+3]=strcat ( B->seq_al[a+3], "x");
11244     }
11245   
11246   B->nseq=6;
11247   B->len_aln=strlen (B->seq_al[0]);
11248   return B;
11249 }
11250
11251 //JM_ADD
11252 //For normal distribution scan
11253 #ifndef PI
11254 #define PI 3.141592653589793238462643
11255 #endif
11256
11257 double normal(double x, double mean, double std)
11258 {
11259         return (1/(std*sqrt(2.0*PI)))*exp((-0.5*(x-mean)*(x-mean))/(std*std));
11260
11261
11262 int ** get_sim_aln_array_normal_distribution ( Alignment *A, char *mode, int *STD, int *CENTER)
11263         {
11264         int **w;
11265         int a, b;
11266         
11267
11268         w=declare_int ( A->nseq, A->nseq);
11269         
11270         for ( a=0; a< A->nseq-1; a++)
11271           {
11272             for ( b=a+1; b< A->nseq; b++)
11273               {
11274
11275                 w[a][b]=w[b][a]=generic_get_seq_sim_normal_distribution ( A->seq_al[a], A->seq_al[b], (A->cdna_cache)?A->cdna_cache[0]:NULL, mode, STD, CENTER);
11276               }
11277           }
11278         return w;
11279         }
11280 int generic_get_seq_sim_normal_distribution ( char *seq1, char *seq2, int*cache, char *mode, int *STD, int *CENTER)
11281 {
11282   return get_seq_sim_distribution ( seq1,seq2,GAP_LIST, mode, STD, CENTER);
11283 }
11284
11285 int get_seq_sim_distribution ( char *string1, char *string2, char *ignore, char *in_mode, int *STD, int *CENTER)
11286         {
11287         int len1;
11288         int a;
11289         int pos0, gap=0;
11290         int p1, p2;
11291         int r=0,r1=0,r2=0;
11292         char *p;
11293         char mode[1000];
11294
11295         double sim;
11296
11297         
11298         sprintf ( mode, "%s", in_mode);
11299         
11300         /*mode: <mat>__<sim_mode>
11301           mat: idscore to get the alignment done
11302                any legal cw matrix
11303           sim_mode: sim1->identities/matches
11304                     sim2->identities/min len     
11305         */
11306
11307         
11308         if ( (p=strstr (mode, "_"))!=NULL)
11309           {
11310             p[0]='\0';
11311             p++;
11312           }
11313
11314             
11315         if (strstr (mode, "idscore"))
11316           {
11317             static int **mat;
11318             if (!mat) mat=read_matrice ("blosum62mt");
11319             return idscore_pairseq (string1, string2, -12, -1, mat,mode);
11320           }
11321         
11322         len1=strlen (string1);
11323         for ( sim=pos0=0,a=0; a< len1; a++)
11324                 {
11325                   r1=string1[a];
11326                   r2=string2[a];
11327                   p1=1-is_in_set (r1, ignore);
11328                   p2=1-is_in_set (r2, ignore);
11329                   if (p1 && p2)
11330                         {
11331                             pos0++;
11332                             if (is_in_same_group_aa(r1,r2,0, NULL, mode))
11333                             {                 
11334                               sim += normal(a, *CENTER, *STD);
11335                             }
11336                         }
11337                   else if (p1+p2==1)
11338                     {
11339                       gap++;
11340                     }
11341                 }
11342         
11343         if ( p==NULL || strm (p, "sim1") || strm (p, "sim"))
11344           {
11345             r=(pos0==0)?0:(sim*MAXID);
11346           }
11347 /*      else if ( strm (p, "sim2"))
11348           {
11349             r=(pos1==0 || pos2==0)?0:(sim*MAXID)/MIN(pos1,pos2);
11350           }
11351         else if ( strm (p, "sim3"))
11352           {
11353             r=(pos1==0 || pos2==0)?0:(sim*MAXID)/MAX(pos1,pos2);
11354           }
11355         else if ( strm (p, "gap1"))
11356           {
11357             r=(len1==0)?MAXID:(gap*MAXID)/len1;
11358             r=MAXID-r;
11359           }
11360         else if ( strm (p, "logid"))
11361           {
11362             r=logid_score (pos0, sim);
11363           }*/
11364         return r;
11365         
11366         }       
11367
11368
11369
11370 Alignment *aln2clean_pw_aln (Alignment *A, OveralnP *F)// char *mode, int t, int f, int p1,int p2, int p3, char *fsa_mode)
11371 {
11372   int **C, **T;
11373   int a, b, c;
11374   Alignment *B;
11375   
11376   
11377   if (F->t==0)F->t=2;
11378   
11379   C=declare_int ( A->nseq, A->len_aln);
11380   T=declare_int ( A->nseq, A->len_aln);
11381   B=copy_aln (A, NULL);
11382   
11383   for (a=0; a< A->nseq;a++)
11384     {
11385       for (b=0; b<A->nseq; b++)
11386         {
11387           int *w;
11388           w=pw_aln2clean_aln_weight (A->seq_al[a], A->seq_al[b], 1,F);//f,p1, p2, p3, fsa_mode);
11389           for (c=0; c<A->len_aln; c++)
11390             {
11391               if (A->seq_al[a][c]=='-')continue;
11392               C[a][c]+=w[c];
11393               T[a][c]++;
11394             }
11395           vfree (w);
11396         }
11397     }
11398   
11399   
11400   
11401   for (a=0; a<A->nseq; a++)
11402     {
11403       for (b=0; b<A->len_aln; b++)
11404         {
11405           int c;
11406           c=A->seq_al[a][b];
11407           if ( c=='-');
11408           else if (T[a][b]==0);
11409           else
11410             {
11411               int r;
11412               r=(C[a][b]*10)/T[a][b];
11413               r=(r==10)?9:r;
11414               if (!F->mode || strm (F->mode, "number"))
11415                 B->seq_al[a][b]='0'+r;
11416               else if ( F->mode && (strm (F->mode, "unalign") ||strm (F->mode, "unalign2")))
11417                 B->seq_al[a][b]='0'+r;
11418               else if ( F->mode && strm (F->mode, "lower") )
11419                 {
11420                   if (r<=F->t)B->seq_al[a][b]=tolower (B->seq_al[a][b]);
11421                   else B->seq_al[a][b]=toupper (B->seq_al[a][b]);
11422                 }
11423             }
11424         }
11425     }
11426
11427   if (F->mode && strm (F->mode, "unalign"))
11428     {
11429       A=unalign_aln (A, B, F->t);
11430       free_aln (B);
11431       B=copy_aln (A, NULL);
11432     }
11433   else if (F->mode && strm (F->mode, "unalign2"))
11434     {
11435       A=unalign_aln_2 (A, B, F->t);
11436       free_aln (B);
11437       B=copy_aln (A, NULL);
11438     }
11439   
11440   
11441  
11442   free_int (C, -1);
11443   free_int (T, -1);
11444  
11445   return B;
11446 }
11447         
11448 char **pw_aln2clean_pw_aln_fsa1 (char ** aln, OveralnP *F);
11449 char **pw_aln2clean_pw_aln_fsa2 (char ** aln, OveralnP *F);
11450
11451 int  * pw_aln2clean_aln_weight ( char *seq1, char *seq2, int w, OveralnP *F)
11452 {
11453   char **aln;
11454   int *weight;
11455   int l, a;
11456     
11457   if ( (l=strlen (seq1)) !=strlen (seq2))
11458     {
11459       HERE ("\n%s\n%s\n", seq1, seq2);
11460       printf_exit ( EXIT_FAILURE, stderr, "\nERROR: Comparing unaligned sequences [FATAL:%s]", PROGRAM);
11461       
11462     }
11463
11464   aln=declare_char (2, l+1);
11465   sprintf ( aln[0], "%s", seq1);
11466   sprintf ( aln[1], "%s", seq2);
11467   
11468  
11469   aln=pw_aln2clean_pw_aln (aln, F);
11470   
11471   weight=vcalloc (l+1, sizeof (int));
11472   for (a=0; a<l; a++)
11473     {
11474       if ( aln[0][a] || seq1[a]=='x' || seq1[a]=='X' || seq2[a]=='x' || seq2[a]=='X')weight[a]=w;
11475     }
11476   free_char (aln, -1);
11477   
11478   return weight;
11479 }
11480   
11481   
11482 char **pw_aln2clean_pw_aln (char ** aln, OveralnP *F)
11483 {
11484   
11485   if ( strm (F->model, "fsa2"))return pw_aln2clean_pw_aln_fsa2 (aln,F);
11486   else if ( strm (F->model, "fsa1"))return pw_aln2clean_pw_aln_fsa1 (aln,F);
11487   else return pw_aln2clean_pw_aln_fsa1 (aln,F);
11488 }
11489
11490 char **pw_aln2clean_pw_aln_fsa2 (char ** aln, OveralnP *FO)
11491 {
11492   int a, b, c, d, l, id;
11493   int c1, c2, e0, e1,tb, obs;
11494   int T0, T1,T2;
11495   int **mat, **tran, **p, **t, *s, *ids;
11496   int ns, ps, cs;
11497   int S, M1, M2, m1, m2,B1, B2,G1,G2, K;
11498   int F=-9999999;
11499   int MID_EXON_FACTOR=50;
11500   int best;
11501   static int **smat;    
11502   int model_type=1;
11503   int *translate;
11504
11505   if ( getenv ("MID_EXON_FACTOR"))MID_EXON_FACTOR=atoi (getenv ("MID_EXON_FACTOR"));
11506   
11507   
11508   
11509   if (!smat)smat=read_matrice ( "blosum62mt");
11510   
11511   l=strlen (aln[0]);
11512   
11513   if ( l!=strlen (aln[1]))
11514     {
11515       printf_exit ( EXIT_FAILURE, stderr, "\nERROR: unaligned strings");
11516     }
11517   
11518   
11519  
11520   s=vcalloc (l, sizeof (int));
11521   ids=vcalloc (l, sizeof (int));
11522   
11523   //record the id level of each posotion
11524   for (b=0; b<l; b++)
11525     {
11526       c1=tolower(aln[0][b]);c2=tolower(c2=aln[1][b]);
11527       
11528       if (c1=='-' || c2=='-' || c1=='X' || c2=='X' || c1!=c2)ids[b]=0;
11529       else ids[b]=1;
11530     }
11531   
11532   //record the state of each position: M, m, T, gap
11533   for (id=0,b=0,a=0;a<l; a++)
11534     {
11535       c1=aln[0][a];c2=aln[1][a];
11536       if (islower (c1))s[a]=3;
11537       else if (c1=='-' || c2=='-' || c1=='X' || c2=='X')s[a]=2;
11538       else
11539         {
11540           int sc;
11541           sc=smat[c1-'A'][c2-'A'];
11542           if (sc>=2){id++; s[a]=1;}
11543           else {s[a]=0;}
11544           b++;
11545         }
11546     }
11547   
11548   if (b==0) 
11549     {
11550       vfree(s);vfree (ids);
11551       return aln;
11552     }
11553   
11554   
11555   
11556   FO->p1=(FO->p1==0)?5:FO->p1;
11557   FO->p2=(FO->p2==0)?15:FO->p2;
11558   FO->p3=(FO->p3==0)?0:FO->p3;
11559   FO->p4=(FO->p4==0)?100:FO->p4;
11560   
11561   
11562   T1=100*(float)id/(float)b;
11563   T2=(FO->f==0)?30:T1*(float)((float)FO->f/(float)100);
11564   T2=MAX(T2,20);
11565   
11566   //0: unaligned
11567   //1: aligned
11568   //2: gap
11569   //3: exon boundary
11570   
11571   ns=0;
11572   S=ns++;
11573   M1=ns++;//1 matched  aligned 
11574   m1=ns++;//2 mmatched aligned
11575   M2=ns++;//3 matched  unaligned
11576   m2=ns++;//4 mmatched unaligned
11577   B1=ns++;//5 transition aligned
11578   B2=ns++;//6 transition unaligned
11579   
11580   mat=declare_int (ns, 4);
11581   tran=declare_int (ns, ns);
11582   p=declare_int (l+1, ns);
11583   t=declare_int (l+1, ns);
11584       
11585   //emission Values
11586   mat[M1][0]=F; //non id
11587   mat[M1][1]=T1;//id
11588   mat[M1][2]=0; //gap
11589   mat[M1][3]=F; //transition
11590   
11591   mat[M2][0]=F;
11592   mat[M2][1]=T2;
11593   mat[M2][2]=0;
11594   mat[M2][3]=F;
11595   
11596   mat[m1][0]=100-T1;
11597   mat[m1][1]=F;
11598   mat[m1][2]=0;
11599   mat[m1][3]=F;
11600   
11601   mat[m2][0]=100-T2;
11602   mat[m2][1]=F;
11603   mat[m2][2]=0;
11604   mat[m1][3]=F;
11605   
11606   mat[B1][0]=F;
11607   mat[B1][1]=F;
11608   mat[B1][2]=F;
11609   mat[B1][3]=0;
11610   
11611   mat[B2][0]=F;
11612   mat[B2][1]=F;
11613   mat[B2][2]=F;
11614   mat[B2][3]=0;
11615   
11616   //transition values
11617   tran[S][m1]=0;
11618   tran[S][m2]=0;
11619   tran[S][M1]=0;
11620   tran[S][M2]=0;
11621   tran[S][B1]=0;
11622   tran[S][B2]=0;
11623   
11624   
11625   tran[M1][m1]= 0;
11626   tran[M1][m2]=-FO->p4;
11627   tran[M1][M1]=+FO->p2;
11628   tran[M1][M2]= F;
11629   tran[M1][S ]= F;
11630   tran[M1][B1]= 0;
11631   tran[M1][B2]=-FO->p1;
11632       
11633   tran[M2][m1]= F;
11634   tran[M2][m2]=+FO->p3;
11635   tran[M2][M1]= F;
11636   tran[M2][M2]= 0;
11637   tran[M2][S] = F;
11638   tran[M2][B1]= F;
11639   tran[M2][B2]= 0;
11640   
11641   
11642   tran[m1][m1]= 0;
11643   tran[m1][m2]= F;
11644   tran[m1][M1]= 0;
11645   tran[m1][M2]= F;
11646   tran[m1][S] = F;
11647   tran[m1][B1]= 0;
11648   tran[m1][B2]=-FO->p1;
11649   
11650   tran[m2][m1]=  F;
11651   tran[m2][m2]=  0;
11652   tran[m2][M1]= -FO->p4;
11653   tran[m2][M2]= +FO->p3;
11654   tran[m2][S] =  F;
11655   tran[m2][B1]=  F;
11656   tran[m2][B2]=  0;
11657   
11658   tran[B1][m1]=  0;
11659   tran[B1][m2]=  F;
11660   tran[B1][M1]=  0;
11661   tran[B1][M2]=  F;
11662   tran[B1][S]=   F;
11663   tran[B1][B1]=  F;
11664   tran[B1][B2]=  F;
11665   
11666   tran[B2][m1]= -FO->p1;
11667   tran[B2][m2]=  0;
11668   tran[B2][M1]= -FO->p1;
11669   tran[B2][M2]=  0;
11670   tran[B2][S]=   F;
11671   tran[B2][B1]=  F;
11672   tran[B2][B2]=  F;
11673   
11674   translate=vcalloc (ns, sizeof (int));
11675   translate[M1]=1;
11676   translate[m1]=1;
11677   translate[M2]=0;
11678   translate[m2]=0;
11679   translate[B1]=1;
11680   translate[B2]=0;
11681   
11682   for (a=1;a<=l; a++)
11683     {
11684       obs=s[a-1];
11685       
11686       for (cs=0; cs<ns; cs++)
11687         {
11688           for (ps=0; ps<ns; ps++)
11689             {
11690               c=p[a-1][ps]+mat[cs][obs]+tran[ps][cs];
11691               if (ps==0 || c>=best){t[a][cs]=ps;best=p[a][cs]=c;}
11692             }
11693           
11694         }
11695     }
11696   
11697   
11698   for (a=0; a<ns; a++)
11699     {
11700       if (a==0 || p[l][a]>=best){tb=a;best=p[l][a];}
11701     }
11702   
11703   for (a=l; a>0; a--)
11704     {
11705       int v;
11706       int p2;
11707            
11708       p2=a-1;
11709       aln[0][p2]=aln[1][p2]=translate[tb];
11710       tb=t[a][tb];
11711       
11712     }
11713   
11714   free_int (p, -1);
11715   vfree(s);
11716   free_int (t, -1);
11717   free_int (mat, -1);
11718   free_int (tran, -1);
11719   vfree (translate);
11720   return aln;
11721 }
11722 char **pw_aln2clean_pw_aln_fsa1 (char ** aln, OveralnP *FO)
11723 {
11724   int a, b, c, d, l, id;
11725   int c1, c2, e0, e1,tb, obs;
11726   int T0, T1,T2;
11727   int **mat, **tran, **p, **t, **s;
11728   int ns, ps, cs;
11729   int S, M1, M2, m1, m2, K;
11730   int F=-9999999;
11731   int best;
11732   static int **smat;    
11733   int *translate;
11734
11735   
11736   if (!smat)smat=read_matrice ( "blosum62mt");
11737   
11738   l=strlen (aln[0]);
11739   
11740   if ( l!=strlen (aln[1]))
11741     {
11742       printf_exit ( EXIT_FAILURE, stderr, "\nERROR: unaligned strings");
11743     }
11744   
11745  
11746   s=declare_int (l+1, 2);
11747   for (id=0,b=0,a=0;a<l; a++)
11748     {
11749       c1=aln[0][a];c2=aln[1][a];
11750       
11751       if ( c1=='-' || c2=='-' || c1=='x' || c1=='X' || c2=='x' || c2=='X')continue;
11752       else 
11753         {
11754           int sc;
11755           sc=smat[c1-'A'][c2-'A'];
11756           if (sc>=2){id++; s[b][0]=1;}
11757           else {s[b][0]=0;}
11758           s[b][1]=a;
11759           b++;
11760           
11761         }
11762     }
11763   if (b==0) 
11764     {
11765       free_int (s, -1);
11766       return aln;
11767     }
11768   FO->f=(FO->f==0)?30:FO->f;
11769   FO->p1=(FO->p1==0)?90:FO->p1;
11770   FO->p2=(FO->p2==0)?15:FO->p2;
11771   FO->p3=(FO->p3==0)?0:FO->p3;
11772
11773   l=b;//length of the ungapped aln
11774   T1=100*(float)id/(float)b;
11775   T2=FO->f;//T1*f;
11776  
11777   
11778   
11779   //0: unaligned
11780   //1: aligned
11781   
11782   
11783   ns=0;
11784   S=ns++;
11785   M1=ns++;//1 matched  aligned 
11786   m1=ns++;//2 mmatched aligned
11787   M2=ns++;//3 matched  unaligned
11788   m2=ns++;//4 mmatched unaligned
11789   
11790   mat=declare_int (ns, 2);
11791   tran=declare_int (ns, ns);
11792   p=declare_int (l+1, ns);
11793   t=declare_int (l+1, ns);
11794   
11795   
11796   mat[M1][0]=F;
11797   mat[M1][1]=T1;
11798   
11799   mat[M2][0]=F;
11800   mat[M2][1]=T2;
11801   
11802   mat[m1][0]=100-T1;
11803   mat[m1][1]=F;
11804   
11805   mat[m2][0]=100-T2;
11806   mat[m2][1]=F;
11807   
11808   
11809   tran[S][m1]=0;
11810   tran[S][m2]=0;
11811   tran[S][M1]=0;
11812   tran[S][M2]=0;
11813   
11814   
11815   tran[M1][m1]= 0;
11816   tran[M1][m2]=-FO->p1;// -P;
11817   tran[M1][M1]=+FO->p2;
11818   tran[M1][M2]= F;
11819   tran[M1][S] = F;
11820   
11821   tran[M2][m1]= F;
11822   tran[M2][m2]=+FO->p3;
11823   tran[M2][M1]= F;
11824   tran[M2][M2]= 0;
11825   tran[M2][S]=  F;
11826   
11827   tran[m1][m1]= 0;
11828   tran[m1][m2]= F;
11829   tran[m1][M1]= 0;
11830   tran[m1][M2]= F;
11831   tran[m1][S]=  F;
11832       
11833   tran[m2][m1]= F;
11834   tran[m2][m2]= 0;
11835   tran[m2][M1]=-FO->p1;
11836   tran[m2][M2]=+FO->p3;
11837   tran[m2][S]=  F;
11838   
11839   translate=vcalloc (ns, sizeof (int));
11840   translate[M1]=1;
11841   translate[m1]=1;
11842   translate[M2]=0;
11843   translate[m2]=0;
11844   translate[S]=1;
11845   
11846   
11847   for (a=1;a<=l; a++)
11848     {
11849       obs=s[a-1][0];
11850       
11851       for (cs=0; cs<ns; cs++)
11852         {
11853           for (ps=0; ps<ns; ps++)
11854             {
11855               c=p[a-1][ps]+mat[cs][obs]+tran[ps][cs];
11856               if (ps==0 || c>=best){t[a][cs]=ps;best=p[a][cs]=c;}
11857             }
11858           
11859         }
11860     }
11861   
11862   
11863   for (a=0; a<ns; a++)
11864     {
11865       if (a==0 || p[l][a]>=best){tb=a;best=p[l][a];}
11866     }
11867   for (a=l; a>0; a--)
11868     {
11869       int p2=s[a-1][1];
11870       aln[0][p2]=aln[1][p2]=translate[tb];
11871       
11872       tb=t[a][tb];
11873     }
11874   
11875   
11876   free_int (p, -1);
11877   free_int (s, -1);
11878   free_int (t, -1);
11879   free_int (mat, -1);
11880   free_int (tran, -1);
11881   vfree (translate);
11882   return aln;
11883 }
11884 float* analyze_overaln ( Alignment *iA, Alignment *iB, char *mode, int filter, int f, int p1,int p2, int p3)
11885 {
11886   Alignment *C, *D;
11887   Alignment *A, *B;
11888   OveralnP *F;
11889
11890   F=vcalloc (1, sizeof (OveralnP));
11891   F->p1=p1;
11892   F->p2=p2;
11893   F->p3=p3;
11894   F->f=f;
11895   F->t=filter;
11896   sprintf (F->mode, "%s", mode);
11897     
11898   
11899   float *r;
11900   A=copy_aln (iA, NULL);
11901   B=copy_aln (iB, NULL);
11902   
11903   C=aln2gap_cache (A,0);
11904   A=filter_aln_upper_lower (A, C, 0, 0);
11905   D=aln2clean_pw_aln (B, F);
11906   r=aln2pred (A,D,mode);
11907   free_aln (C);
11908   free_aln (D);
11909   free_aln (A);
11910   free_aln (B);
11911   return r;
11912 }
11913 float* aln2pred ( Alignment *A, Alignment*B, char *mode)
11914 {
11915   int a, b, c, d, i, l, salp, s, n;
11916   static char **list, *buf1, *buf2, *alp, *alp_lu;
11917   static int ***r;
11918   int T, N;
11919   int fp, fn, tn, tp;
11920   int tfp, tfn, ttn, ttp;
11921   float sp, sn, sen2, best, result;
11922   int print=1;
11923   float *fresult;
11924
11925   fresult=vcalloc ( 3, sizeof (float));
11926   
11927   if ( mode && strstr (mode, "case"))
11928     {
11929       A=aln2case_aln (A,"u","l");
11930       B=aln2case_aln (B,"u","l");
11931     }
11932   
11933   if (mode && strstr (mode, "printaln"))
11934     {
11935       Sequence *S;
11936       Alignment *C;
11937       S=aln2seq (A);
11938       C=copy_aln (B, NULL);
11939       for (a=0; a<B->nseq; a++)
11940         {
11941           i=name_is_in_list (C->name[a], S->name, S->nseq, 100);
11942           if ( i==-1)
11943             for (b=0; b<C->len_aln; b++) C->seq_al[a][b]='-';
11944           else
11945             for (d=0,b=0; b<C->len_aln; b++)
11946               {
11947                 if ( !is_gap (C->seq_al[a][b]))
11948                   {
11949                     if (C->seq_al[a][b]==S->seq[i][d])C->seq_al[a][b]=toupper(C->seq_al[a][b]);
11950                     d++;
11951                   }
11952               }
11953         }
11954       print_aln (C);
11955     }
11956   
11957   vfree (alp);vfree (alp_lu);
11958   alp=vcalloc ( 256, sizeof (char));
11959   alp_lu=vcalloc ( 256, sizeof (char));
11960
11961   for (c=0; c<2; c++)
11962     {
11963       Alignment *AL;
11964       AL=(c==0)?A:B;
11965       for (salp=0,a=0; a<AL->nseq; a++)
11966         {
11967           for (b=0; b<AL->len_aln; b++)
11968             {
11969               c=AL->seq_al[a][b];
11970               if (!is_gap(c) && !alp[c])
11971                 {
11972                   salp++;
11973                   alp_lu[salp]=c;
11974                   alp[c]=salp;
11975                 }
11976             }
11977         }
11978     }
11979   
11980   vfree (buf1); vfree(buf2);
11981   buf1=vcalloc ( A->len_aln+1, sizeof (char));
11982   buf2=vcalloc ( B->len_aln+1, sizeof (char));
11983   
11984   free_arrayN ((void **)r, 3);
11985   r=declare_arrayN(3, sizeof (int),A->nseq,salp+1,salp+1);
11986   free_char ( list, -1);
11987   list=declare_char ( A->nseq, 100);
11988   for (n=0,a=0; a< A->nseq; a++)
11989     {
11990       for ( b=0; b<B->nseq; b++)
11991         {
11992           if ( strm (A->name[a], B->name[b]))
11993             {
11994               sprintf ( buf1, "%s", A->seq_al[a]);
11995               sprintf ( buf2, "%s", B->seq_al[b]);
11996               ungap (buf1); ungap (buf2);
11997               if ((l=strlen (buf1))!=strlen (buf2))continue;
11998               else
11999                 {
12000                   sprintf ( list[n], "%s", A->name[a]);
12001                   for (c=0; c<l; c++)
12002                     {
12003                       int c1, c2;
12004                       c1=buf1[c];
12005                       c2=buf2[c];
12006                       r[n][alp[c1]][alp[c2]]++;
12007                     }
12008                   n++;
12009                 }
12010             }
12011         }
12012     }
12013   
12014
12015   
12016   for ( s=1; s<=salp; s++)
12017     {
12018       char type[4];
12019       sprintf (type, "_%c_", alp_lu[s]);
12020       ttp=ttn=tfp=tfn=0;
12021       for (a=0; a<n; a++)
12022         {
12023           tp=tn=fp=fn=0;
12024           for (b=1; b<=salp; b++)
12025             {
12026               for (c=1; c<=salp; c++)
12027                     {
12028                       if ( b==s && c==s)     tp+=r[a][b][c];
12029                       else if ( b==s && c!=s)fn+=r[a][b][c];
12030                       else if ( b!=s && c==s)fp+=r[a][b][c];
12031                       else if ( b!=s && b!=s)tn+=r[a][b][c];
12032                     }
12033               
12034             }
12035           
12036           ttp+=tp;
12037           ttn+=tn;
12038           tfp+=fp;
12039           tfn+=fn;
12040           rates2sensitivity (tp, tn, fp, fn, &sp, &sn, &sen2, &best);
12041           if ( mode && strstr (mode, "printstat"))fprintf ( stdout, ">%s S=%c sp=%6.2f sn=%6.2f sen2=%6.2f best=%6.2f\n", list[a],alp_lu[s],sp, sn, sen2, best);
12042         }
12043       
12044       rates2sensitivity (ttp, ttn, tfp, tfn, &sp, &sn, &sen2, &best);
12045       if (mode && strstr (mode, "printstat"))fprintf ( stdout, ">TOT S=%c sp=%6.2f sn=%6.2f re=%6.2f best=%6.2f\n", alp_lu[s],sp, sn, sen2, best);
12046       
12047       if ( mode && strstr (mode, type))
12048         {
12049           fresult[0]=sn;
12050           fresult[1]=sp;
12051           fresult[2]=sen2;
12052         }
12053     }
12054   return fresult;
12055 }
12056
12057 Alignment * mark_exon_boundaries  (Alignment *A, Alignment *E)
12058 {
12059   char *buf, *buf2;
12060   int a, b, c, i, l;
12061   
12062   buf2=vcalloc ( E->len_aln+1, sizeof (char));
12063   buf =vcalloc ( E->len_aln+1, sizeof (char));
12064   
12065   for (a=0; a< A->nseq; a++)
12066     {
12067       i=name_is_in_list (A->name[a], E->name, E->nseq, 100);
12068       if ( i==-1) continue;
12069       sprintf (buf, "%s", E->seq_al[i]);
12070       ungap (buf);
12071       l=strlen (buf);
12072       //clean buf2
12073       for (c=0, b=0; b<l; b++)if (buf[b]!='o' && buf[b]!='b' && buf[b]!='j')buf2[c++]=toupper(buf[b]);
12074       buf2[c]='\0';
12075       
12076       //lowercase the boundaries of buf2;
12077       for ( c=0,b=0; b<l; b++)
12078         {
12079           //ENSEMBL: o: 0, b:1 j:2
12080           if (buf[b]=='b' || buf[b]=='o' && c>=1)buf2[c-1]=tolower(buf2[c-1]);
12081           else if (buf[b]=='j' &&c<l)buf2[c+1]=tolower(buf2[c+1]);
12082           else c++;
12083         }
12084       
12085       for (c=0,b=0; b<A->len_aln; b++)
12086         {
12087           if (!is_gap(A->seq_al[a][b]))
12088             {
12089               A->seq_al[a][b]=buf2[c++];
12090             }
12091         }
12092     }
12093   vfree (buf);
12094   vfree (buf2);
12095   return A;
12096 }
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571
12572
12573
12574
12575
12576
12577
12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638
12639
12640
12641
12642
12643
12644
12645
12646
12647
12648
12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
12686
12687
12688
12689
12690
12691
12692
12693
12694
12695
12696
12697
12698
12699
12700
12701
12702
12703
12704
12705
12706
12707
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
12727
12728
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
12777
12778
12779
12780
12781
12782
12783
12784
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833
12834
12835
12836
12837
12838
12839
12840
12841
12842
12843
12844
12845
12846
12847
12848
12849
12850
12851
12852
12853
12854
12855
12856
12857
12858
12859
12860
12861
12862
12863
12864
12865
12866
12867
12868
12869
12870
12871
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893
12894
12895
12896
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927
12928
12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955
12956
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978
12979
12980
12981
12982
12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997
12998
12999
13000
13001
13002
13003
13004
13005
13006
13007
13008
13009
13010
13011
13012
13013
13014
13015
13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
13041
13042
13043
13044
13045
13046
13047
13048
13049
13050
13051
13052
13053
13054
13055
13056
13057
13058
13059
13060
13061
13062
13063
13064
13065
13066
13067
13068
13069
13070
13071
13072
13073
13074
13075
13076
13077
13078
13079
13080
13081
13082
13083
13084
13085
13086
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096
13097
13098
13099
13100
13101
13102
13103
13104
13105
13106
13107
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
13146
13147
13148
13149
13150
13151
13152
13153
13154
13155
13156
13157
13158
13159
13160
13161
13162
13163
13164
13165
13166
13167
13168
13169
13170
13171
13172
13173
13174
13175
13176
13177
13178
13179
13180
13181
13182
13183
13184
13185
13186
13187
13188
13189
13190
13191
13192
13193
13194
13195
13196
13197
13198
13199
13200
13201
13202
13203
13204
13205
13206
13207
13208
13209
13210
13211
13212
13213
13214
13215
13216
13217
13218
13219
13220
13221
13222
13223
13224
13225
13226
13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238
13239
13240
13241
13242
13243
13244
13245
13246
13247
13248
13249
13250
13251
13252
13253
13254
13255
13256
13257
13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268
13269
13270
13271
13272
13273
13274
13275
13276
13277
13278
13279
13280
13281
13282
13283
13284
13285
13286
13287
13288
13289
13290
13291
13292
13293
13294
13295
13296
13297
13298
13299
13300
13301
13302
13303
13304
13305
13306
13307
13308
13309
13310
13311
13312
13313
13314
13315
13316
13317
13318
13319
13320
13321
13322
13323
13324
13325
13326
13327
13328
13329
13330
13331
13332
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
13364
13365
13366
13367
13368
13369
13370
13371
13372
13373
13374
13375
13376
13377
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
13391
13392
13393
13394
13395
13396
13397
13398
13399
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
13421
13422
13423
13424
13425
13426
13427
13428
13429
13430
13431
13432
13433
13434
13435
13436
13437
13438
13439
13440
13441
13442
13443
13444
13445
13446
13447
13448
13449
13450
13451
13452
13453
13454
13455
13456
13457
13458
13459
13460
13461
13462
13463
13464
13465
13466
13467
13468
13469
13470
13471
13472
13473
13474
13475
13476
13477
13478
13479
13480
13481
13482
13483
13484
13485
13486
13487
13488
13489
13490
13491
13492
13493
13494
13495
13496
13497
13498
13499
13500
13501
13502
13503
13504
13505
13506
13507
13508
13509
13510
13511
13512
13513
13514
13515
13516
13517
13518
13519
13520
13521
13522
13523
13524
13525
13526
13527
13528
13529
13530
13531
13532
13533
13534
13535
13536
13537
13538
13539
13540
13541
13542
13543
13544
13545
13546
13547
13548
13549
13550
13551
13552
13553
13554
13555
13556
13557
13558
13559
13560
13561
13562
13563
13564
13565
13566
13567
13568
13569
13570
13571
13572
13573
13574
13575
13576
13577
13578
13579
13580
13581
13582
13583
13584
13585
13586
13587
13588
13589
13590
13591
13592
13593
13594
13595
13596
13597
13598
13599
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621
13622
13623
13624
13625
13626
13627
13628
13629
13630
13631
13632
13633
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643
13644
13645
13646
13647
13648
13649
13650
13651
13652
13653
13654
13655
13656
13657
13658
13659
13660
13661
13662
13663
13664
13665
13666
13667
13668
13669
13670
13671
13672
13673
13674
13675
13676
13677
13678
13679
13680
13681
13682
13683
13684
13685
13686
13687
13688
13689
13690
13691
13692
13693
13694
13695
13696
13697
13698
13699
13700
13701
13702
13703
13704
13705
13706
13707
13708
13709
13710
13711
13712
13713
13714
13715
13716
13717
13718
13719
13720
13721
13722
13723
13724
13725
13726
13727
13728
13729
13730
13731
13732
13733
13734
13735
13736
13737
13738
13739
13740
13741
13742
13743
13744
13745
13746
13747
13748
13749
13750
13751
13752
13753
13754
13755
13756
13757
13758
13759
13760
13761
13762
13763
13764
13765
13766
13767
13768
13769
13770
13771
13772
13773
13774
13775
13776
13777
13778
13779
13780
13781
13782
13783
13784
13785
13786
13787
13788
13789
13790
13791
13792
13793
13794
13795
13796
13797
13798
13799
13800
13801
13802
13803
13804
13805
13806
13807
13808
13809
13810
13811
13812
13813
13814
13815
13816
13817
13818
13819
13820
13821
13822
13823
13824
13825
13826
13827
13828
13829
13830
13831
13832
13833
13834
13835
13836
13837
13838
13839
13840
13841
13842
13843
13844
13845
13846
13847
13848
13849
13850
13851
13852
13853
13854
13855
13856
13857
13858
13859
13860
13861
13862
13863
13864
13865
13866
13867
13868
13869
13870
13871
13872
13873
13874
13875
13876
13877
13878
13879
13880
13881
13882
13883
13884
13885
13886
13887
13888
13889
13890
13891
13892
13893
13894
13895
13896
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908
13909
13910
13911
13912
13913
13914
13915
13916
13917
13918
13919
13920
13921
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931
13932
13933
13934
13935
13936
13937
13938
13939
13940
13941
13942
13943
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962
13963
13964
13965
13966
13967
13968
13969
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979
13980
13981
13982
13983
13984
13985
13986
13987
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
14000
14001
14002
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037
14038
14039
14040
14041
14042
14043
14044
14045
14046
14047
14048
14049
14050
14051
14052
14053
14054
14055
14056
14057
14058
14059
14060
14061
14062
14063
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075
14076
14077
14078
14079
14080
14081
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091
14092
14093
14094
14095
14096
14097
14098
14099
14100
14101
14102
14103
14104
14105
14106
14107
14108
14109
14110
14111
14112
14113
14114
14115
14116
14117
14118
14119
14120
14121
14122
14123
14124
14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143
14144
14145
14146
14147
14148
14149
14150
14151
14152
14153
14154
14155
14156
14157
14158
14159
14160
14161
14162
14163
14164
14165
14166
14167
14168
14169
14170
14171
14172
14173
14174
14175
14176
14177
14178
14179
14180
14181
14182
14183
14184
14185
14186
14187
14188
14189
14190
14191
14192
14193
14194
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205
14206
14207
14208
14209
14210
14211
14212
14213
14214
14215
14216
14217
14218
14219
14220
14221
14222
14223
14224
14225
14226
14227
14228
14229
14230
14231
14232
14233
14234
14235
14236
14237
14238
14239
14240
14241
14242
14243
14244
14245
14246
14247
14248
14249
14250
14251
14252
14253
14254
14255
14256
14257
14258
14259
14260
14261
14262
14263
14264
14265
14266
14267
14268
14269
14270
14271
14272
14273
14274
14275
14276
14277
14278
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302
14303
14304
14305
14306
14307
14308
14309
14310
14311
14312
14313
14314
14315
14316
14317
14318
14319
14320
14321
14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
14333
14334
14335
14336
14337
14338
14339
14340
14341
14342
14343
14344
14345
14346
14347
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
14361
14362
14363
14364
14365
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
14384
14385
14386
14387
14388
14389
14390
14391
14392
14393
14394
14395
14396
14397
14398
14399
14400
14401
14402
14403
14404
14405
14406
14407
14408
14409
14410
14411
14412
14413
14414
14415
14416
14417
14418
14419
14420
14421
14422
14423
14424
14425
14426
14427
14428
14429
14430
14431
14432
14433
14434
14435
14436
14437
14438
14439
14440
14441
14442
14443
14444
14445
14446
14447
14448
14449
14450
14451
14452
14453
14454
14455
14456
14457
14458
14459
14460
14461
14462
14463
14464
14465
14466
14467
14468
14469
14470
14471
14472
14473
14474
14475
14476
14477
14478
14479
14480
14481
14482
14483
14484
14485
14486
14487
14488
14489
14490
14491
14492
14493
14494
14495
14496
14497
14498
14499
14500
14501
14502
14503
14504
14505
14506
14507
14508
14509
14510
14511
14512
14513
14514
14515
14516
14517
14518
14519
14520
14521
14522
14523
14524
14525
14526
14527
14528
14529
14530
14531
14532
14533
14534
14535
14536
14537
14538
14539
14540
14541
14542
14543
14544
14545
14546
14547
14548
14549
14550
14551
14552
14553
14554
14555
14556
14557
14558
14559
14560
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571
14572
14573
14574
14575
14576
14577
14578
14579
14580
14581
14582
14583
14584
14585
14586
14587
14588
14589
14590
14591
14592
14593
14594
14595
14596
14597
14598
14599
14600
14601
14602
14603
14604
14605
14606
14607
14608
14609
14610
14611
14612
14613
14614
14615
14616
14617
14618
14619
14620
14621
14622
14623
14624
14625
14626
14627
14628
14629
14630
14631
14632
14633
14634
14635
14636
14637
14638
14639
14640
14641
14642
14643
14644
14645
14646
14647
14648
14649
14650
14651
14652
14653
14654
14655
14656
14657
14658
14659
14660
14661
14662
14663
14664
14665
14666
14667
14668
14669
14670
14671
14672
14673
14674
14675
14676
14677
14678
14679
14680
14681
14682
14683
14684
14685
14686
14687
14688
14689
14690
14691
14692
14693
14694
14695
14696
14697
14698
14699
14700
14701
14702
14703
14704
14705
14706
14707
14708
14709
14710
14711
14712
14713
14714
14715
14716
14717
14718
14719
14720
14721
14722
14723
14724
14725
14726
14727
14728
14729
14730
14731
14732
14733
14734
14735
14736
14737
14738
14739
14740
14741
14742
14743
14744
14745
14746
14747
14748
14749
14750
14751
14752
14753
14754
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764
14765
14766
14767
14768
14769
14770
14771
14772
14773
14774
14775
14776
14777
14778
14779
14780
14781
14782
14783
14784
14785
14786
14787
14788
14789
14790
14791
14792
14793
14794
14795
14796
14797
14798
14799
14800
14801
14802
14803
14804
14805
14806
14807
14808
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
14819
14820
14821
14822
14823
14824
14825
14826
14827
14828
14829
14830
14831
14832
14833
14834
14835
14836
14837
14838
14839
14840
14841
14842
14843
14844
14845
14846
14847
14848
14849
14850
14851
14852
14853
14854
14855
14856
14857
14858
14859
14860
14861
14862
14863
14864
14865
14866
14867
14868
14869
14870
14871
14872
14873
14874
14875
14876
14877
14878
14879
14880
14881
14882
14883
14884
14885
14886
14887
14888
14889
14890
14891
14892
14893
14894
14895
14896
14897
14898
14899
14900
14901
14902
14903
14904
14905
14906
14907
14908
14909
14910
14911
14912
14913
14914
14915
14916
14917
14918
14919
14920
14921
14922
14923
14924
14925
14926
14927
14928
14929
14930
14931
14932
14933
14934
14935
14936
14937
14938
14939
14940
14941
14942
14943
14944
14945
14946
14947
14948
14949
14950
14951
14952
14953
14954
14955
14956
14957
14958
14959
14960
14961
14962
14963
14964
14965
14966
14967
14968
14969
14970
14971
14972
14973
14974
14975
14976
14977
14978
14979
14980
14981
14982
14983
14984
14985
14986
14987
14988
14989
14990
14991
14992
14993
14994
14995
14996
14997
14998
14999
15000
15001
15002
15003
15004
15005
15006
15007
15008
15009
15010
15011
15012
15013
15014
15015
15016
15017
15018
15019
15020
15021
15022
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032
15033
15034
15035
15036
15037
15038
15039
15040
15041
15042
15043
15044
15045
15046
15047
15048
15049
15050
15051
15052
15053
15054
15055
15056
15057
15058
15059
15060
15061
15062
15063
15064
15065
15066
15067
15068
15069
15070
15071
15072
15073
15074
15075
15076
15077
15078
15079
15080
15081
15082
15083
15084
15085
15086
15087
15088
15089
15090
15091
15092
15093
15094
15095
15096
15097
15098
15099
15100
15101
15102
15103
15104
15105
15106
15107
15108
15109
15110
15111
15112
15113
15114
15115
15116
15117
15118
15119
15120
15121
15122
15123
15124
15125
15126
15127
15128
15129
15130
15131
15132
15133
15134
15135
15136
15137
15138
15139
15140
15141
15142
15143
15144
15145
15146
15147
15148
15149
15150
15151
15152
15153
15154
15155
15156
15157
15158
15159
15160
15161
15162
15163
15164
15165
15166
15167
15168
15169
15170
15171
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196
15197
15198
15199
15200
15201
15202
15203
15204
15205
15206
15207
15208
15209
15210
15211
15212
15213
15214
15215
15216
15217
15218
15219
15220
15221
15222
15223
15224
15225
15226
15227
15228
15229
15230
15231
15232
15233
15234
15235
15236
15237
15238
15239
15240
15241
15242
15243
15244
15245
15246
15247
15248
15249
15250
15251
15252
15253
15254
15255
15256
15257
15258
15259
15260
15261
15262
15263
15264
15265
15266
15267
15268
15269
15270
15271
15272
15273
15274
15275
15276
15277
15278
15279
15280
15281
15282
15283
15284
15285
15286
15287
15288
15289
15290
15291
15292
15293
15294
15295
15296
15297
15298
15299
15300
15301
15302
15303
15304
15305
15306
15307
15308
15309
15310
15311
15312
15313
15314
15315
15316
15317
15318
15319
15320
15321
15322
15323
15324
15325
15326
15327
15328
15329
15330
15331
15332
15333
15334
15335
15336
15337
15338
15339
15340
15341
15342
15343
15344
15345
15346
15347
15348
15349
15350
15351
15352
15353
15354
15355
15356
15357
15358
15359
15360
15361
15362
15363
15364
15365
15366
15367
15368
15369
15370
15371
15372
15373
15374
15375
15376
15377
15378
15379
15380
15381
15382
15383
15384
15385
15386
15387
15388
15389
15390
15391
15392
15393
15394
15395
15396
15397
15398
15399
15400
15401
15402
15403
15404
15405
15406
15407
15408
15409
15410
15411
15412
15413
15414
15415
15416
15417
15418
15419
15420
15421
15422
15423
15424
15425
15426
15427
15428
15429
15430
15431
15432
15433
15434
15435
15436
15437
15438
15439
15440
15441
15442
15443
15444
15445
15446
15447
15448
15449
15450
15451
15452
15453
15454
15455
15456
15457
15458
15459
15460
15461
15462
15463
15464
15465
15466
15467
15468
15469
15470
15471
15472
15473
15474
15475
15476
15477
15478
15479
15480
15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497
15498
15499
15500
15501
15502
15503
15504
15505
15506
15507
15508
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518
15519
15520
15521
15522
15523
15524
15525
15526
15527
15528
15529
15530
15531
15532
15533
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
15581
15582
15583
15584
15585
15586
15587
15588
15589
15590
15591
15592
15593
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
15629
15630
15631
15632
15633
15634
15635
15636
15637
15638
15639
15640
15641
15642
15643
15644
15645
15646
15647
15648
15649
15650
15651
15652
15653
15654
15655
15656
15657
15658
15659
15660
15661
15662
15663
15664
15665
15666
15667
15668
15669
15670
15671
15672
15673
15674
15675
15676
15677
15678
15679
15680
15681
15682
15683
15684
15685
15686
15687
15688
15689
15690
15691
15692
15693
15694
15695
15696
15697
15698
15699
15700
15701
15702
15703
15704
15705
15706
15707
15708
15709
15710
15711
15712
15713
15714
15715
15716
15717
15718
15719
15720
15721
15722
15723
15724
15725
15726
15727
15728
15729
15730
15731
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744
15745
15746
15747
15748
15749
15750
15751
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763
15764
15765
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
15864
15865
15866
15867
15868
15869
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
15887
15888
15889
15890
15891
15892
15893
15894
15895
15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916
15917
15918
15919
15920
15921
15922
15923
15924
15925
15926
15927
15928
15929
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
15963
15964
15965
15966
15967
15968
15969
15970
15971
15972
15973
15974
15975
15976
15977
15978
15979
15980
15981
15982
15983
15984
15985
15986
15987
15988
15989
15990
15991
15992
15993
15994
15995
15996
15997
15998
15999
16000
16001
16002
16003
16004
16005
16006
16007
16008
16009
16010
16011
16012
16013
16014
16015
16016
16017
16018
16019
16020
16021
16022
16023
16024
16025
16026
16027
16028
16029
16030
16031
16032
16033
16034
16035
16036
16037
16038
16039
16040
16041
16042
16043
16044
16045
16046
16047
16048
16049
16050
16051
16052
16053
16054
16055
16056
16057
16058
16059
16060
16061
16062
16063
16064
16065
16066
16067
16068
16069
16070
16071
16072
16073
16074
16075
16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087
16088
16089
16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104
16105
16106
16107
16108
16109
16110
16111
16112
16113
16114
16115
16116
16117
16118
16119
16120
16121
16122
16123
16124
16125
16126
16127
16128
16129
16130
16131
16132
16133
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150
16151
16152
16153
16154
16155
16156
16157
16158
16159
16160
16161
16162
16163
16164
16165
16166
16167
16168
16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
16183
16184
16185
16186
16187
16188
16189
16190
16191
16192
16193
16194
16195
16196
16197
16198
16199
16200
16201
16202
16203
16204
16205
16206
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
16224
16225
16226
16227
16228
16229
16230
16231
16232
16233
16234
16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
16248
16249
16250
16251
16252
16253
16254
16255
16256
16257
16258
16259
16260
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
16273
16274
16275
16276
16277
16278
16279
16280
16281
16282
16283
16284
16285
16286
16287
16288
16289
16290
16291
16292
16293
16294
16295
16296
16297
16298
16299
16300
16301
16302
16303
16304
16305
16306
16307
16308
16309
16310
16311
16312
16313
16314
16315
16316
16317
16318
16319
16320
16321
16322
16323
16324
16325
16326
16327
16328
16329
16330
16331
16332
16333
16334
16335
16336
16337
16338
16339
16340
16341
16342
16343
16344
16345
16346
16347
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357
16358
16359
16360
16361
16362
16363
16364
16365
16366
16367
16368
16369
16370
16371
16372
16373
16374
16375
16376
16377
16378
16379
16380
16381
16382
16383
16384
16385
16386
16387
16388
16389
16390
16391
16392
16393
16394
16395
16396
16397
16398
16399
16400
16401
16402
16403
16404
16405
16406
16407
16408
16409
16410
16411
16412
16413
16414
16415
16416
16417
16418
16419
16420
16421
16422
16423
16424
16425
16426
16427
16428
16429
16430
16431
16432
16433
16434
16435
16436
16437
16438
16439
16440
16441
16442
16443
16444
16445
16446
16447
16448
16449
16450
16451
16452
16453
16454
16455
16456
16457
16458
16459
16460
16461
16462
16463
16464
16465
16466
16467
16468
16469
16470
16471
16472
16473
16474
16475
16476
16477
16478
16479
16480
16481
16482
16483
16484
16485
16486
16487
16488
16489
16490
16491
16492
16493
16494
16495
16496
16497
16498
16499
16500
16501
16502
16503
16504
16505
16506
16507
16508
16509
16510
16511
16512
16513
16514
16515
16516
16517
16518
16519
16520
16521
16522
16523
16524
16525
16526
16527
16528
16529
16530
16531
16532
16533
16534
16535
16536
16537
16538
16539
16540
16541
16542
16543
16544
16545
16546
16547
16548
16549
16550
16551
16552
16553
16554
16555
16556
16557
16558
16559
16560
16561
16562
16563
16564
16565
16566
16567
16568
16569
16570
16571
16572
16573
16574
16575
16576
16577
16578
16579
16580
16581
16582
16583
16584
16585
16586
16587
16588
16589
16590
16591
16592
16593
16594
16595
16596
16597
16598
16599
16600
16601
16602
16603
16604
16605
16606
16607
16608
16609
16610
16611
16612
16613
16614
16615
16616
16617
16618
16619
16620
16621
16622
16623
16624
16625
16626
16627
16628
16629
16630
16631
16632
16633
16634
16635
16636
16637
16638
16639
16640
16641
16642
16643
16644
16645
16646
16647
16648
16649
16650
16651
16652
16653
16654
16655
16656
16657
16658
16659
16660
16661
16662
16663
16664
16665
16666
16667
16668
16669
16670
16671
16672
16673
16674
16675
16676
16677
16678
16679
16680
16681
16682
16683
16684
16685
16686
16687
16688
16689
16690
16691
16692
16693
16694
16695
16696
16697
16698
16699
16700
16701
16702
16703
16704
16705
16706
16707
16708
16709
16710
16711
16712
16713
16714
16715
16716
16717
16718
16719
16720
16721
16722
16723
16724
16725
16726
16727
16728
16729
16730
16731
16732
16733
16734
16735
16736
16737
16738
16739
16740
16741
16742
16743
16744
16745
16746
16747
16748
16749
16750
16751
16752
16753
16754
16755
16756
16757
16758
16759
16760
16761
16762
16763
16764
16765
16766
16767
16768
16769
16770
16771
16772
16773
16774
16775
16776
16777
16778
16779
16780
16781
16782
16783
16784
16785
16786
16787
16788
16789
16790
16791
16792
16793
16794
16795
16796
16797
16798
16799
16800
16801
16802
16803
16804
16805
16806
16807
16808
16809
16810
16811
16812
16813
16814
16815
16816
16817
16818
16819
16820
16821
16822
16823
16824
16825
16826
16827
16828
16829
16830
16831
16832
16833
16834
16835
16836
16837
16838
16839
16840
16841
16842
16843
16844
16845
16846
16847
16848
16849
16850
16851
16852
16853
16854
16855
16856
16857
16858
16859
16860
16861
16862
16863
16864
16865
16866
16867
16868
16869
16870
16871
16872
16873
16874
16875
16876
16877
16878
16879
16880
16881
16882
16883
16884
16885
16886
16887
16888
16889
16890
16891
16892
16893
16894
16895
16896
16897
16898
16899
16900
16901
16902
16903
16904
16905
16906
16907
16908
16909
16910
16911
16912
16913
16914
16915
16916
16917
16918
16919
16920
16921
16922
16923
16924
16925
16926
16927
16928
16929
16930
16931
16932
16933
16934
16935
16936
16937
16938
16939
16940
16941
16942
16943
16944
16945
16946
16947
16948
16949
16950
16951
16952
16953
16954
16955
16956
16957
16958
16959
16960
16961
16962
16963
16964
16965
16966
16967
16968
16969
16970
16971
16972
16973
16974
16975
16976
16977
16978
16979
16980
16981
16982
16983
16984
16985
16986
16987
16988
16989
16990
16991
16992
16993
16994
16995
16996
16997
16998
16999
17000
17001
17002
17003
17004
17005
17006
17007
17008
17009
17010
17011
17012
17013
17014
17015
17016
17017
17018
17019
17020
17021
17022
17023
17024
17025
17026
17027
17028
17029
17030
17031
17032
17033
17034
17035
17036
17037
17038
17039
17040
17041
17042
17043
17044
17045
17046
17047
17048
17049
17050
17051
17052
17053
17054
17055
17056
17057
17058
17059
17060
17061
17062
17063
17064
17065
17066
17067
17068
17069
17070
17071
17072
17073
17074
17075
17076
17077
17078
17079
17080
17081
17082
17083
17084
17085
17086
17087
17088
17089
17090
17091
17092
17093
17094
17095
17096
17097
17098
17099
17100
17101
17102
17103
17104
17105
17106
17107
17108
17109
17110
17111
17112
17113
17114
17115
17116
17117
17118
17119
17120
17121
17122
17123
17124
17125
17126
17127
17128
17129
17130
17131
17132
17133
17134
17135
17136
17137
17138
17139
17140
17141
17142
17143
17144
17145
17146
17147
17148
17149
17150
17151
17152
17153
17154
17155
17156
17157
17158
17159
17160
17161
17162
17163
17164
17165
17166
17167
17168
17169
17170
17171
17172
17173
17174
17175
17176
17177
17178
17179
17180
17181
17182
17183
17184
17185
17186
17187
17188
17189
17190
17191
17192
17193
17194
17195
17196
17197
17198
17199
17200
17201
17202
17203
17204
17205
17206
17207
17208
17209
17210
17211
17212
17213
17214
17215
17216
17217
17218
17219
17220
17221
17222
17223
17224
17225
17226
17227
17228
17229
17230
17231
17232
17233
17234
17235
17236
17237
17238
17239
17240
17241
17242
17243
17244
17245
17246
17247
17248
17249
17250
17251
17252
17253
17254
17255
17256
17257
17258
17259
17260
17261
17262
17263
17264
17265
17266
17267
17268
17269
17270
17271
17272
17273
17274
17275
17276
17277
17278
17279
17280
17281
17282
17283
17284
17285
17286
17287
17288
17289
17290
17291
17292
17293
17294
17295
17296
17297
17298
17299
17300
17301
17302
17303
17304
17305
17306
17307
17308
17309
17310
17311
17312
17313
17314
17315
17316
17317
17318
17319
17320
17321
17322
17323
17324
17325
17326
17327
17328
17329
17330
17331
17332
17333
17334
17335
17336
17337
17338
17339
17340
17341
17342
17343
17344
17345
17346
17347
17348
17349
17350
17351
17352
17353
17354
17355
17356
17357
17358
17359
17360
17361
17362
17363
17364
17365
17366
17367
17368
17369
17370
17371
17372
17373
17374
17375
17376
17377
17378
17379
17380
17381
17382
17383
17384
17385
17386
17387
17388
17389
17390
17391
17392
17393
17394
17395
17396
17397
17398
17399
17400
17401
17402
17403
17404
17405
17406
17407
17408
17409
17410
17411
17412
17413
17414
17415
17416
17417
17418
17419
17420
17421
17422
17423
17424
17425
17426
17427
17428
17429
17430
17431
17432
17433
17434
17435
17436
17437
17438
17439
17440
17441
17442
17443
17444
17445
17446
17447
17448
17449
17450
17451
17452
17453
17454
17455
17456
17457
17458
17459
17460
17461
17462
17463
17464
17465
17466
17467
17468
17469
17470
17471
17472
17473
17474
17475
17476
17477
17478
17479
17480
17481
17482
17483
17484
17485
17486
17487
17488
17489
17490
17491
17492
17493
17494
17495
17496
17497
17498
17499
17500
17501
17502
17503
17504
17505
17506
17507
17508
17509
17510
17511
17512
17513
17514
17515
17516
17517
17518
17519
17520
17521
17522
17523
17524
17525
17526
17527
17528
17529
17530
17531
17532
17533
17534
17535
17536
17537
17538
17539
17540
17541
17542
17543
17544
17545
17546
17547
17548
17549
17550
17551
17552
17553
17554
17555
17556
17557
17558
17559
17560
17561
17562
17563
17564
17565
17566
17567
17568
17569
17570
17571
17572
17573
17574
17575
17576
17577
17578
17579
17580
17581
17582
17583
17584
17585
17586
17587
17588
17589
17590
17591
17592
17593
17594
17595
17596
17597
17598
17599
17600
17601
17602
17603
17604
17605
17606
17607
17608
17609
17610
17611
17612
17613
17614
17615
17616
17617
17618
17619
17620
17621
17622
17623
17624
17625
17626
17627
17628
17629
17630
17631
17632
17633
17634
17635
17636
17637
17638
17639
17640
17641
17642
17643
17644
17645
17646
17647
17648
17649
17650
17651
17652
17653
17654
17655
17656
17657
17658
17659
17660
17661
17662
17663
17664
17665
17666
17667
17668
17669
17670
17671
17672
17673
17674
17675
17676
17677
17678
17679
17680
17681
17682
17683
17684
17685
17686
17687
17688
17689
17690
17691
17692
17693
17694
17695
17696
17697
17698
17699
17700
17701
17702
17703
17704
17705
17706
17707
17708
17709
17710
17711
17712
17713
17714
17715
17716
17717
17718
17719
17720
17721
17722
17723
17724
17725
17726
17727
17728
17729
17730
17731
17732
17733
17734
17735
17736
17737
17738
17739
17740
17741
17742
17743
17744
17745
17746
17747
17748
17749
17750
17751
17752
17753
17754
17755
17756
17757
17758
17759
17760
17761
17762
17763
17764
17765
17766
17767
17768
17769
17770
17771
17772
17773
17774
17775
17776
17777
17778
17779
17780
17781
17782
17783
17784
17785
17786
17787
17788
17789
17790
17791
17792
17793
17794
17795
17796
17797
17798
17799
17800
17801
17802
17803
17804
17805
17806
17807
17808
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
17819
17820
17821
17822
17823
17824
17825
17826
17827
17828
17829
17830
17831
17832
17833
17834
17835
17836
17837
17838
17839
17840
17841
17842
17843
17844
17845
17846
17847
17848
17849
17850
17851
17852
17853
17854
17855
17856
17857
17858
17859
17860
17861
17862
17863
17864
17865
17866
17867
17868
17869
17870
17871
17872
17873
17874
17875
17876
17877
17878
17879
17880
17881
17882
17883
17884
17885
17886
17887
17888
17889
17890
17891
17892
17893
17894
17895
17896
17897
17898
17899
17900
17901
17902
17903
17904
17905
17906
17907
17908
17909
17910
17911
17912
17913
17914
17915
17916
17917
17918
17919
17920
17921
17922
17923
17924
17925
17926
17927
17928
17929
17930
17931
17932
17933
17934
17935
17936
17937
17938
17939
17940
17941
17942
17943
17944
17945
17946
17947
17948
17949
17950
17951
17952
17953
17954
17955
17956
17957
17958
17959
17960
17961
17962
17963
17964
17965
17966
17967
17968
17969
17970
17971
17972
17973
17974
17975
17976
17977
17978
17979
17980 /******************************COPYRIGHT NOTICE*******************************/
17981 /*© Centro de Regulacio Genomica */
17982 /*and */
17983 /*Cedric Notredame */
17984 /*Fri Feb 18 08:27:45 CET 2011 - Revision 596. */
17985 /*All rights reserved.*/
17986 /*This file is part of T-COFFEE.*/
17987 /**/
17988 /*    T-COFFEE is free software; you can redistribute it and/or modify*/
17989 /*    it under the terms of the GNU General Public License as published by*/
17990 /*    the Free Software Foundation; either version 2 of the License, or*/
17991 /*    (at your option) any later version.*/
17992 /**/
17993 /*    T-COFFEE is distributed in the hope that it will be useful,*/
17994 /*    but WITHOUT ANY WARRANTY; without even the implied warranty of*/
17995 /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*/
17996 /*    GNU General Public License for more details.*/
17997 /**/
17998 /*    You should have received a copy of the GNU General Public License*/
17999 /*    along with Foobar; if not, write to the Free Software*/
18000 /*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/
18001 /*...............................................                                                                                      |*/
18002 /*  If you need some more information*/
18003 /*  cedric.notredame@europe.com*/
18004 /*...............................................                                                                                                                                     |*/
18005 /**/
18006 /**/
18007 /*      */
18008 /******************************COPYRIGHT NOTICE*******************************/