6 #include "io_lib_header.h"
7 #include "util_lib_header.h"
8 #include "define_header.h"
9 #include "dp_lib_header.h"
10 /* extern char name0[], name1[]; */
11 /* extern int match, mismh; */
15 static Constraint_list *CL;
18 static Alignment *Aln;
20 static int *seqc0, *seqc1;
21 static int min0,min1,max0,max1,mins;
23 static void* sim_vcalloc( size_t nobj, size_t size);
24 static void sim_free_all ();
25 static int sim_reset_static_variable ();
26 static int big_pass(int *A,int *B,int M,int N,int K, int nseq) ;
27 static int locate(int *A,int *B,int nseq);
28 static int small_pass(int *A,int *B,int count,int nseq);
29 static int no_cross ();
30 static int diff_sim( int *A,int *B,int M,int N,int tb,int te);
31 int calcons(int *aa0,int n0,int *aa1,int n1,int *res,int *nc,int *nident, Alignment *A, int *ns, int **l_s, Constraint_list *CL);
36 #define min(x,y) ((x)<=(y) ? (x) : (y))
37 //#define TC_SCORE_SIM(x,y) TC_SCORE (x,y)
39 static int q, r; /* gap penalties */
40 static int qr; /* qr = q + r */
44 typedef struct ONE { int COL ; struct ONE *NEXT ;} pair, *pairptr;
45 pairptr *row, z, z1; /* for saving used aligned pairs */
48 #define PAIRNULL (pairptr)NULL
51 typedef struct SIM_NODE
60 int SIM_RIGHT; } vertex,
67 vertexptr *LIST; /* an array for saving k best scores */
68 vertexptr low = 0; /* lowest score node in LIST */
69 vertexptr most = 0; /* latestly accessed node in LIST */
70 static int numnode; /* the number of nodes in LIST */
72 static int *CC, *DD; /* saving matrix scores */
73 static int *RR, *SS, *EE, *FF; /* saving start-points */
74 static int *HH, *WW; /* saving matrix scores */
75 static int *II, *JJ, *XX, *YY; /* saving start-points */
76 static int m1, mm, n1, nn; /* boundaries of recomputed area */
77 static int rl, cl; /* left and top boundaries */
78 static int lmin; /* minimum score in LIST */
79 static int flag; /* indicate if recomputation necessary*/
81 /* DIAG() assigns value to x if (ii,jj) is never used before */
82 #define DIAG(ii, jj, x, value) \
83 { for ( tt = 1, z = row[(ii)]; z != PAIRNULL; z = z->NEXT ) \
84 if ( z->COL == (jj) ) \
90 /* replace (ss1, xx1, yy1) by (ss2, xx2, yy2) if the latter is large */
91 #define ORDER(ss1, xx1, yy1, ss2, xx2, yy2) \
93 { ss1 = ss2; xx1 = xx2; yy1 = yy2; } \
97 { xx1 = xx2; yy1 = yy2; } \
99 if ( xx1 == xx2 && yy1 < yy2 ) \
104 /* The following definitions are for function diff() */
106 static int zero = 0; /* int type zero */
107 #define gap(k) ((k) <= 0 ? 0 : q+r*(k)) /* k-symbol indel score */
109 static int *sapp; /* Current script append ptr */
110 static int last; /* Last script op appended */
112 static int I, J; /* current positions of A ,B */
113 static int no_mat; /* number of matches */
114 static int no_mis; /* number of mismatches */
115 static int al_len; /* length of alignment */
116 /* Append "Delete k" op */
121 last = sapp[-1] -= (k);\
123 last = *sapp++ = -(k);\
125 /* Append "Insert k" op */
130 { sapp[-1] = (k); *sapp++ = last; } \
132 last = *sapp++ = (k);\
135 /* Append "Replace" op */
137 { last = *sapp++ = 0;\
143 int sim_pair_wise_lalign (Alignment *in_A, int *in_ns, int **in_l_s,Constraint_list *in_CL)
145 if ( in_ns[0]==1 && in_ns[1]==1)
146 return sim_pair_wise_lalign (in_A, in_ns, in_l_s,in_CL);
154 int sim_pair_wise_lalign (Alignment *in_A, int *in_ns, int **in_l_s,Constraint_list *in_CL)
155 /* SIM(A,B,M,N,K,V,Q,R) reports K best non-intersecting alignments of
156 the segments of A and B in order of similarity scores, where
157 V[a][b] is the score of aligning a and b, and -(Q+R*i) is the score
158 of an i-symbol indel.
161 int endi, endj, stari, starj; /* endpoint and startpoint */
162 int score; /* the max score in LIST */
163 int count; /* maximum size of list */
165 int *S; /* saving operations for diff */
166 int nc, nident; /* for display */
167 vertexptr cur; /* temporary pointer */
168 vertexptr findmax(); /* return the largest score node */
170 int t1, t2, g1, g2, r1, r2;
172 /*cedric was here 11/2/99*/
173 int CEDRIC_MAX_N_ALN=999;
174 int CEDRIC_THRESHOLD=50;
184 Aln=copy_aln (in_A, NULL);
193 M=strlen (Aln->seq_al[l_s[0][0]]);
194 N=strlen (Aln->seq_al[l_s[1][0]]);
197 pos=aln2pos_simple (Aln,-1, ns, l_s);
199 seqc0=(int*)sim_vcalloc (maxl+1,sizeof (int));
200 A=(int*)sim_vcalloc (maxl+1,sizeof (int));
201 for ( a=0; a<maxl; a++){seqc0[a]=A[a]=a;}
204 seqc1=(int*)sim_vcalloc (maxl+1,sizeof (int));
205 B=(int*)sim_vcalloc (maxl+1,sizeof (int));
206 for ( a=0; a<maxl; a++){seqc1[a]=B[a]=a;}
209 nseq=(l_s[0][0]!=l_s[1][0])?2:1;
212 Q=MAX(CL->gop, -CL->gop)*SCORE_K;
213 R=MAX(CL->gep, -CL->gep)*SCORE_K;
217 if ( K==CEDRIC_MAX_N_ALN)K--;
225 /* allocate space for all vectors */
227 CC = ( int * ) sim_vcalloc(N+1, sizeof(int));
228 DD = ( int * ) sim_vcalloc(N+1, sizeof(int));
229 RR = ( int * ) sim_vcalloc(N+1, sizeof(int));
230 SS = ( int * ) sim_vcalloc(N+1, sizeof(int));
231 EE = ( int * ) sim_vcalloc(N+1, sizeof(int));
232 FF = ( int * ) sim_vcalloc(N+1, sizeof(int));
234 HH = ( int * ) sim_vcalloc(M + 1, sizeof(int));
235 WW = ( int * ) sim_vcalloc(M + 1, sizeof(int));
236 II = ( int * ) sim_vcalloc(M + 1, sizeof(int));
237 JJ = ( int * ) sim_vcalloc(M + 1, sizeof(int));
238 XX = ( int * ) sim_vcalloc(M + 1, sizeof(int));
239 YY = ( int * ) sim_vcalloc(M + 1, sizeof(int));
240 S = ( int * ) sim_vcalloc(min(M,N)*5/4+1, sizeof (int));
241 row = ( pairptr * ) sim_vcalloc( (M + 1), sizeof(pairptr));
244 /* set up list for each row */
245 if (nseq == 2) for ( i = 1; i <= M; i++ ) row[i]= PAIRNULL;
247 z = ( pairptr )sim_vcalloc (M,(int)sizeof(pair));
248 for ( i = 1; i <= M; i++,z++) {
260 LIST = ( vertexptr * ) sim_vcalloc( K, sizeof(vertexptr));
261 for ( i = 0; i < K ; i++ )
262 LIST[i] = ( vertexptr )sim_vcalloc( 1, sizeof(vertex));
266 big_pass(A,B,M,N,K,nseq);
270 /* Report the K best alignments one by one. After each alignment is
271 output, recompute part of the matrix. First determine the size
272 of the area to be recomputed, then do the recomputation */
275 for ( count = K - 1; count >= 0; count-- )
276 { if ( numnode == 0 )
280 /*fatal("The number of alignments computed is too large");*/
285 cur = findmax(); /* Return a pointer to a node with max score*/
286 score = cur->SIM_SCORE;
287 if ( K==CEDRIC_MAX_N_ALN && score<CEDRIC_THRESHOLD)break;
288 stari = ++cur->SIM_STARI;
289 starj = ++cur->SIM_STARJ;
290 endi = cur->SIM_ENDI;
291 endj = cur->SIM_ENDJ;
296 rl = endi - stari + 1;
297 cl = endj - starj + 1;
305 diff_sim(&A[stari]-1, &B[starj]-1,rl,cl,q,q);
312 calcons(A+1,M,B+1,N,S,&nc,&nident, Aln,ns, l_s, CL);
313 percent = (double)nident*100.0/(double)nc;
317 /*Min0: index of the last residue before the first in a 1..N+1 numerotation*/
321 if (!DA->A)DA->A=copy_aln(Aln, DA->A);
322 DA->A=realloc_alignment (DA->A,nc+1);
328 for ( c=0; c< 2; c++)
330 for ( a=0; a< ns[c]; a++)
335 DA->order[l_s[c][a]][1]+=1-is_gap(Aln->seq_al[l_s[c][a]][d]);
341 for ( t1=min0,t2=min1,a=0; a<nc; a++)
346 g1=(r1==SIM_GAP || r1>M)?0:1;
347 g2=(r2==SIM_GAP || r2>N)?0:1;
350 for (b=0; b<ns[0]; b++)DA->seq_al[l_s[0][b]][a]=(g1)?Aln->seq_al[l_s[0][b]][A[t1-1]]:'-';
351 for (b=0; b<ns[1]; b++)DA->seq_al[l_s[1][b]][a]=(g2)?Aln->seq_al[l_s[1][b]][B[t2-1]]:'-';
353 for (b=0; b<ns[0]; b++){DA->seq_al[l_s[0][b]][a]='\0';}
354 for (b=0; b<ns[1]; b++){DA->seq_al[l_s[1][b]][a]='\0';}
356 DA->nseq=ns[0]+ns[1];
367 small_pass(A,B,count,nseq);
381 int sim_reset_static_variable ()
383 CC=DD=RR=SS=EE=FF=HH=WW=II=JJ=XX=YY=sapp=NULL;
384 min0=min1=max0=max1=mins=q=r=qr=tt=numnode=m1=n1=nn=rl=cl=lmin=flag=zero=last=I=J=no_mat=no_mis=al_len=0;
385 most=low=NULL;/*Very important: cause a bug if not reset*/
386 LIST=NULL; /*Very important: cause a bug if not reset*/
389 /* A big pass to compute K best classes */
392 int big_pass(int *A,int *B,int M,int N,int K, int nseq)
393 { register int i, j; /* row and column indices */
394 register int c; /* best score at current point */
395 register int f; /* best score ending with insertion */
396 register int d; /* best score ending with deletion */
397 register int p; /* best score at (i-1, j-1) */
398 register int ci, cj; /* end-point associated with c */
399 register int di, dj; /* end-point associated with d */
400 register int fi, fj; /* end-point associated with f */
401 register int pi, pj; /* end-point associated with p */
403 int addnode(); /* function for inserting a node */
406 /* Compute the matrix and save the top K best scores in LIST
407 CC : the scores of the current row
408 RR and EE : the starting point that leads to score CC
409 DD : the scores of the current row, ending with deletion
410 SS and FF : the starting point that leads to score DD */
411 /* Initialize the 0 th row */
412 for ( j = 1; j <= N ; j++ )
420 for ( i = 1; i <= M; i++)
421 { c = 0; /* Initialize column 0 */
435 for ( j = (nseq == 2 ? 1 : (i+1)) ; j <= N ; j++ )
438 ORDER(f, fi, fj, c, ci, cj)
445 ORDER(d, di, dj, c, ci, cj)
448 DIAG(i, j, c, p+TC_SCORE(A[i-1],B[j-1])) /* diagonal */
451 { c = 0; ci = i; cj = j; }
453 { ci = pi; cj = pj; }
454 ORDER(c, ci, cj, d, di, dj)
455 ORDER(c, ci, cj, f, fi, fj)
465 if ( c > lmin ) /* add the score into list */
466 lmin = addnode(c, ci, cj, i, j, K, lmin);
472 /* Determine the left and top boundaries of the recomputed area */
474 int locate(int *A,int *B,int nseq)
475 { register int i, j; /* row and column indices */
476 register int c; /* best score at current point */
477 register int f; /* best score ending with insertion */
478 register int d; /* best score ending with deletion */
479 register int p; /* best score at (i-1, j-1) */
480 register int ci, cj; /* end-point associated with c */
481 register int di=0, dj=0; /* end-point associated with d */
482 register int fi, fj; /* end-point associated with f */
483 register int pi, pj; /* end-point associated with p */
484 int cflag, rflag; /* for recomputation */
485 int addnode(); /* function for inserting a node */
486 int limit; /* the bound on j */
490 CC : the scores on the current row
491 RR and EE : the endpoints that lead to CC
492 DD : the deletion scores
493 SS and FF : the endpoints that lead to DD
496 HH : the scores on the current columns
497 II and JJ : the endpoints that lead to HH
498 WW : the deletion scores
499 XX and YY : the endpoints that lead to WW
501 for ( j = nn; j >= n1 ; j-- )
506 if ( nseq == 2 || j > mm )
507 RR[j] = SS[j] = mm + 1;
512 for ( i = mm; i >= m1; i-- )
517 cj = fj = pj = nn + 1;
519 if ( nseq == 2 || n1 > i )
523 for ( j = nn; j >= limit ; j-- )
526 ORDER(f, fi, fj, c, ci, cj)
533 ORDER(d, di, dj, c, ci, cj)
535 DIAG(i, j, c, p+TC_SCORE(A[i-1],B[j-1])) /* diagonal */
538 { c = 0; ci = i; cj = j; }
540 { ci = pi; cj = pj; }
541 ORDER(c, ci, cj, d, di, dj)
542 ORDER(c, ci, cj, f, fi, fj)
555 if ( nseq == 2 || i < n1 )
565 for ( rl = m1, cl = n1; ; )
566 { for ( rflag = cflag = 1; ( rflag && m1 > 1 ) || ( cflag && n1 > 1 ) ; )
567 { if ( rflag && m1 > 1 ) /* Compute one row */
574 cj = fj = pj = nn + 1;
576 for ( j = nn; j >= n1 ; j-- )
579 ORDER(f, fi, fj, c, ci, cj)
586 ORDER(d, di, dj, c, ci, cj)
588 DIAG(m1, j, c, TC_SCORE(A[m1-1],B[j-1])) /* diagonal */
591 { c = 0; ci = m1; cj = j; }
593 { ci = pi; cj = pj; }
594 ORDER(c, ci, cj, d, di, dj)
595 ORDER(c, ci, cj, f, fi, fj)
607 if ( ! rflag && ( (ci > rl && cj > cl) || (di > rl && dj > cl)
608 || (fi > rl && fj > cl) ) )
617 if ( ! cflag && ( (ci > rl && cj > cl) || (di > rl && dj > cl)
618 || (fi > rl && fj > cl )) )
622 if ( nseq == 1 && n1 == (m1 + 1) && ! rflag )
624 if ( cflag && n1 > 1 ) /* Compute one column */
630 if ( nseq == 2 || mm < n1 )
632 ci = fi = pi = mm + 1;
643 for ( i = limit; i >= m1 ; i-- )
646 ORDER(f, fi, fj, c, ci, cj)
653 ORDER(d, di, dj, c, ci, cj)
655 DIAG(i, n1, c, p+TC_SCORE(A[i-1], B[n1-1]))
660 { c = 0; ci = i; cj = n1; }
662 { ci = pi; cj = pj; }
663 ORDER(c, ci, cj, d, di, dj)
664 ORDER(c, ci, cj, f, fi, fj)
676 if ( ! cflag && ( (ci > rl && cj > cl) || (di > rl && dj > cl)
677 || (fi > rl && fj > cl )) )
686 if ( ! rflag && ( (ci > rl && cj > cl) || (di > rl && dj > cl)
687 || (fi > rl && fj > cl) ) )
691 if ( (m1 == 1 && n1 == 1) || no_cross() )
699 /* recompute the area on forward pass */
700 int small_pass(int *A,int *B,int count,int nseq)
701 { register int i, j; /* row and column indices */
702 register int c; /* best score at current point */
703 register int f; /* best score ending with insertion */
704 register int d; /* best score ending with deletion */
705 register int p; /* best score at (i-1, j-1) */
706 register int ci, cj; /* end-point associated with c */
707 register int di, dj; /* end-point associated with d */
708 register int fi, fj; /* end-point associated with f */
709 register int pi, pj; /* end-point associated with p */
710 int addnode(); /* function for inserting a node */
711 int limit; /* lower bound on j */
713 for ( j = n1 + 1; j <= nn ; j++ )
721 for ( i = m1 + 1; i <= mm; i++)
722 { c = 0; /* Initialize column 0 */
726 if ( nseq == 2 || i <= n1 )
739 for ( j = limit ; j <= nn ; j++ )
742 ORDER(f, fi, fj, c, ci, cj)
749 ORDER(d, di, dj, c, ci, cj)
751 DIAG(i, j, c, p+TC_SCORE(A[i-1], B[j-1])) /* diagonal */
755 { c = 0; ci = i; cj = j; }
757 { ci = pi; cj = pj; }
758 ORDER(c, ci, cj, d, di, dj)
759 ORDER(c, ci, cj, f, fi, fj)
769 if ( c > lmin ) /* add the score into list */
770 lmin = addnode(c, ci, cj, i, j, count, lmin);
776 /* Add a new node into list. */
778 int addnode(c, ci, cj, i, j, K, cost) int c, ci, cj, i, j, K, cost;
779 { int found; /* 1 if the node is in LIST */
783 if ( most != 0 && most->SIM_STARI == ci && most->SIM_STARJ == cj )
786 for ( d = 0; d < numnode ; d++ )
788 if ( most->SIM_STARI == ci && most->SIM_STARJ == cj )
794 { if ( most->SIM_SCORE < c )
795 { most->SIM_SCORE = c;
799 if ( most->SIM_TOP > i ) most->SIM_TOP = i;
800 if ( most->SIM_BOT < i ) most->SIM_BOT = i;
801 if ( most->SIM_LEFT > j ) most->SIM_LEFT = j;
802 if ( most->SIM_RIGHT < j ) most->SIM_RIGHT = j;
805 { if ( numnode == K ) /* list full */
808 most = LIST[numnode++];
810 most->SIM_STARI = ci;
811 most->SIM_STARJ = cj;
814 most->SIM_TOP = most->SIM_BOT = i;
815 most->SIM_LEFT = most->SIM_RIGHT = j;
818 { if ( low == most || ! low )
819 { for ( low = LIST[0], d = 1; d < numnode ; d++ )
820 if ( LIST[d]->SIM_SCORE < low->SIM_SCORE )
823 return ( low->SIM_SCORE ) ;
829 /* Find and remove the largest score in list */
835 for ( j = 0, i = 1; i < numnode ; i++ )
836 if ( LIST[i]->SIM_SCORE > LIST[j]->SIM_SCORE )
839 if ( j != --numnode )
840 { LIST[j] = LIST[numnode];
844 if ( low == cur ) low = LIST[0];
848 /* return 1 if no node in LIST share vertices with the area */
854 for ( i = 0; i < numnode; i++ )
856 if ( cur->SIM_STARI <= mm && cur->SIM_STARJ <= nn && cur->SIM_BOT >= m1-1 &&
857 cur->SIM_RIGHT >= n1-1 && ( cur->SIM_STARI < rl || cur->SIM_STARJ < cl ))
858 { if ( cur->SIM_STARI < rl ) rl = cur->SIM_STARI;
859 if ( cur->SIM_STARJ < cl ) cl = cur->SIM_STARJ;
870 /* diff(A,B,M,N,tb,te) returns the score of an optimum conversion between
871 A[1..M] and B[1..N] that begins(ends) with a delete if tb(te) is zero
872 and appends such a conversion to the current script. */
874 int diff_sim( int *A,int *B,int M,int N,int tb,int te)
876 { int midi, midj, type; /* Midpoint, type, and cost */
881 register int c, e, d, s;
885 /* Boundary cases: M <= 1 or N == 0 */
896 if (tb > te) tb = te;
897 midc = - (tb + r + gap(N) );
900 for (j = 1; j <= N; j++)
901 { for ( tt = 1, z = row[I+1]; z != PAIRNULL; z = z->NEXT )
905 { c = TC_SCORE (A[0],B[j-1]) - ( gap(j-1) + gap(N-j) );
917 { if (midj > 1) INS(midj-1)
919 if ( A[1] == B[midj] )
923 /* mark (A[I],B[J]) as used: put J into list row[I] */
927 z = ( pairptr )sim_vcalloc(1,sizeof(pair));
931 if (midj < N) INS(N-midj)
936 /* Divide: Find optimum midpoint (midi,midj) of cost midc */
938 midi = M/2; /* Forward phase: */
939 CC[0] = 0; /* Compute C(M/2,k) & D(M/2,k) for all k */
941 for (j = 1; j <= N; j++)
946 for (i = 1; i <= midi; i++)
951 for (j = 1; j <= N; j++)
952 { if ((c = c - qr) > (e = e - r)) e = c;
953 if ((c = CC[j] - qr) > (d = DD[j] - r)) d = c;
954 DIAG(i+I, j+J, c, s+TC_SCORE(A[i-1], B[j-1]))
966 RR[N] = 0; /* Reverse phase: */
967 t = -q; /* Compute R(M/2,k) & S(M/2,k) for all k */
968 for (j = N-1; j >= 0; j--)
973 for (i = M-1; i >= midi; i--)
978 for (j = N-1; j >= 0; j--)
979 { if ((c = c - qr) > (e = e - r)) e = c;
980 if ((c = RR[j] - qr) > (d = SS[j] - r)) d = c;
981 DIAG(i+1+I, j+1+J, c, s+TC_SCORE (A[i],B[j])) /*not -1 on purpose*/
992 midc = CC[0]+RR[0]; /* Find optimal midpoint */
995 for (j = 0; j <= N; j++)
996 if ((c = CC[j] + RR[j]) >= midc)
997 if (c > midc || (CC[j] != DD[j] && RR[j] == SS[j]))
1001 for (j = N; j >= 0; j--)
1002 if ((c = DD[j] + SS[j] + q) > midc)
1009 /* Conquer: recursively around midpoint */
1012 { diff_sim(A,B,midi,midj,tb,q);
1013 diff_sim(A+midi,B+midj,M-midi,N-midj,q,te);
1016 { diff_sim(A,B,midi-1,midj,tb,zero);
1018 diff_sim(A+midi+1,B+midj,M-midi-1,N-midj,zero,te);
1026 int calcons(int *aa0,int n0,int *aa1,int n1,int *res,int *nc,int *nident, Alignment *A, int *ns, int **l_s, Constraint_list *CL)
1029 int op, nid, lenc, nd;
1032 int a, b, id_col, tot_col, r0, r1;
1039 lenc = nid = op = 0;
1043 while (i0 < max0 || i1 < max1) {
1044 if (op == 0 && *rp == 0) {
1050 for (id_col=tot_col=0,a=0; a< ns[0]; a++)
1051 for ( b=0; b< ns[1]; b++)
1053 r0=Aln->seq_al[l_s[0][a]][*sp0-1];
1054 r1=Aln->seq_al[l_s[1][a]][*sp1-1];
1056 if ( !is_gap(r0) && r1==r0)id_col++;
1057 if ( !is_gap(r0) && !is_gap(r1))tot_col++;
1059 nid+=(tot_col)?(id_col/tot_col):0;
1064 if (op==0) op = *rp++;
1084 return mins+lenc+nd;
1087 /*Memory management */
1094 typedef struct Mem Mem;
1099 void *sim_vcalloc ( size_t nobj, size_t size)
1104 p=vcalloc (nobj, size);
1107 new_mem=vcalloc (1, sizeof (Mem));
1108 if ( last_mem==NULL)first_mem=last_mem=new_mem;
1111 last_mem->next=new_mem;
1131 first_mem=last_mem=NULL;
1132 sim_reset_static_variable();
1135 /******************************COPYRIGHT NOTICE*******************************/
1136 /*© Centro de Regulacio Genomica */
1138 /*Cedric Notredame */
1139 /*Fri Feb 18 08:27:45 CET 2011 - Revision 596. */
1140 /*All rights reserved.*/
1141 /*This file is part of T-COFFEE.*/
1143 /* T-COFFEE is free software; you can redistribute it and/or modify*/
1144 /* it under the terms of the GNU General Public License as published by*/
1145 /* the Free Software Foundation; either version 2 of the License, or*/
1146 /* (at your option) any later version.*/
1148 /* T-COFFEE is distributed in the hope that it will be useful,*/
1149 /* but WITHOUT ANY WARRANTY; without even the implied warranty of*/
1150 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the*/
1151 /* GNU General Public License for more details.*/
1153 /* You should have received a copy of the GNU General Public License*/
1154 /* along with Foobar; if not, write to the Free Software*/
1155 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
1156 /*............................................... |*/
1157 /* If you need some more information*/
1158 /* cedric.notredame@europe.com*/
1159 /*............................................... |*/
1163 /******************************COPYRIGHT NOTICE*******************************/