/* yama - Yet Another Multiple Aligner */ /* Version Creation Date: 10/30/92 */ /* Revision Histories: March 93 : lav format April 93 : linked with lib.c May 93 : left/right end gaps April 94 : rewritten in Standard C */ #include #include #define max(x,y) ((x) >= (y) ? (x) : (y)) #define min(x,y) ((x) <= (y) ? (x) : (y)) #define DEFAULT_LL 50 /* output line length */ #define SIGMA 128 #define SUB(a,b) PD(i,j,(a),(b)) = PD(i,j,(b),(a)) = \ PD(j,i,(a),(b)) = PD(j,i,(b),(a)) #define SUBI(a,b) PD(i,j,(a),(b)) = PD(j,i,(b),(a)) #define SUBJ(a,b) PD(j,i,(a),(b)) = PD(i,j,(b),(a)) #define DAG(a) PD(i,j,(a),(a)) = PD(j,i,(a),(a)) #define DT(x) PT[i][j]x = PT[j][i]x #define DTI(x) PT[i][j]x #define DTJ(x) PT[j][i]x #define NUMBER 10 /* Maximum number of sequences */ #define SYMA 'A' #define SYMC 'C' #define SYMG 'G' #define SYMT 'T' #define DASH '-' #define LSTAR '*' #define RSTAR '@' #define MININT -9999999 #define TRUE 1 #define FALSE 0 /* #define USAGE "Usage: yama [-e ] [-c ] [-t] [L=??] " */ #define USAGE "Usage: yama [-c ] [-t] [L=??] " /* score file format : seq1 seq2 60 2 8 -10 seq2 seq3 50 2 10 -10 default 60 2 10 -10 seq2 3 2 4 3 default 0 0 0 0 Default : to output LAV-format text -t : normal text output L : text length input sequence order format: "((seq1[20,50] seq2[30,45]) seq3[20,50])" */ /* int PD(NUMBER+1,NUMBER+1,SIGMA,SIGMA); */ /* symbol distance */ int *PD_storage; /* symbol distance */ int K; /* number of sequences */ int LL; /* line length */ #define PD_SIZE(K) (sizeof(int) * SIGMA * SIGMA * ((K)+1) * ((K)+1)) #define PD_ALLOC(K) do{PD_storage = (int*)ckalloc(PD_SIZE(K));}while(0) #define PD(a,b,c,d) PD_storage[(d) + SIGMA*((c) + SIGMA*((b) + (K+1)*(a)))] #define PD2(a,b) (PD_storage + SIGMA*SIGMA*((b) + (K+1)*(a))) int PT[NUMBER+1][NUMBER+1][2][2][4][4]; /* Altschul gap counts */ char *S [NUMBER+1]; /* sequences */ int L [NUMBER+1]; /* lengths of sequences */ int From[NUMBER+1]; /* Starting position */ int To[NUMBER+1]; /* End position */ int SD[NUMBER+1][NUMBER+1]; /* sequence distance */ char *Sname[NUMBER+1]; /* sequence name */ char Ename[30]; /* int gflag = 0; */ char tflag = 1; char cflag = 0; char eflag = 0; static int sl; static int *sapp; /* Current script append ptr */ static int last; /* Last script op appended */ /* Append "Delete k" op */ #define DEL(k) \ { sl += k; \ if (last < 0) \ last = sapp[-1] -= (k); \ else \ last = *sapp++ = -(k); \ } /* Append "Insert k" op */ #define INS(k) \ { sl += k; \ if (last > 0) \ last = sapp[-1] += (k); \ else \ last = *sapp++ = (k); \ } #define REP { ++sl; last = *sapp++ = 0; } /* Append "Replace" op */ /* - -> * for some cases */ #define ET(ii,jj) ((ii == DASH)? jj : ii) /* compute the value for gap table T */ /* 0 : DASH; 1 : letter; 2 : LSTAR ; 3 : RSTAR */ #define GV(ii) ((ii==DASH)? 0 : ((ii==LSTAR)? 2 : ((ii==RSTAR)? 3 : 1))) #define ETGV(kk,ii,jj) { \ kk = ET(ii,jj); \ kk = GV(kk); \ } int *C1, *C2; int *HH, *VV, *DD; int *RH, *RV, *RD; char **E1, **E2; /* End gaps indicator */ char **HE1, **VE2; /* End gaps indicator */ typedef struct tnode *Tptr; typedef struct tnode { Tptr left; Tptr right; int L; /* leftmost sequence */ int R; /* rightmost sequence */ char **AL; /* return alignment */ int N; /* alignment length */ } Tnode; char order[256]; void main(), data(), StoAL(), ALStoAL(), MALStoMAL(), MDisplay(), LDisplay(), order_print(), print_score(); Tptr build_tree(); int traverse_tree(); void main(int argc, char *argv[]) { int e, m, v; char cname[30]; char **AL; int *ALS; int SL; char *ckalloc(); int i,j; int c; Tptr tp; /* gflag = 0; */ LL = DEFAULT_LL; if (argc <= 1) fatal(USAGE); for ( ++argv; --argc; argv++ ) if ( (*argv)[0] == '-' ) { /* if ( (*argv)[1] == 'g' ) { if ( (*argv)[2] == '2' ) gflag = 2; else gflag = 1; } else if ( (*argv)[1] == 't' ) tflag = 0; */ if ( (*argv)[1] == 't' ) tflag = 0; else if ( (*argv)[1] == 'c' ) { /* score file is provided */ ++argv; --argc; sscanf(*argv,"%s",cname); cflag = 1; score_name(cname); } else if ( (*argv)[1] == 'e' ) { /* end points are provided */ ++argv; --argc; sscanf(*argv,"%s",Ename); eflag = 1; } else fatal(USAGE); } else if ((*argv)[0] == 'L' && (*argv)[1] == '=') LL = atoi(*argv + 2); else { strcpy(order,*argv); tp = build_tree(order); } /* for (i=1; i<=K; ++i) printf("Seq %d: Length: %d %s\n",i,L[i],S[i]+1); */ PD_ALLOC(K); if (tflag) { printf("#:lav\n\n"); printf("d {\n \"YAMA output with parameters:\n"); } order_print(order); /* if (cflag) printf(" score file: %s\n",cname); else printf(" default score file used\n"); */ data(); /* get input scoring scheme */ c = traverse_tree(tp); if (tflag) { printf(" \"\n"); printf("}\n"); LDisplay(tp->AL,K-1,tp->N,c); } else { printf("\n alignment score = %d\n\n",c); MDisplay(tp->AL,K-1,tp->N); } #ifdef CHECK printf("check_score=%d\n",align_score(tp->AL,K-1,tp->N)); #endif free(tp->AL[0]); free(tp->AL); exit(0); } /* order_print - print out the sequence order */ void order_print(char *order) { char *op, buf[80], flag; int LL = 60, IL = 54, i; int line_no=0; flag = TRUE; while (flag) { while (*order == ' ') ++order; i = 0; op = order; if (++line_no > 1) LL = IL; while ((*op++ != '\0') && (i++ < LL)); op--; if (*op == '\0') flag = FALSE; if (i > 0) { while (*op != ']' && *op !=')' && *op != '\0' && i-- > 0) op--; if (i <= 0) { flag = FALSE; if (line_no == 1) printf(" order=%s\n",order); else printf(" %s\n",order); printf("Last line is too long!\n"); } else { strncpy(buf,order,i); buf[i] = '\0'; if (line_no == 1) printf(" order=%s\n",buf); else printf(" %s\n",buf); } } order = ++op; } } /* build_tree - return the root of the aligning tree */ Tptr build_tree(char *order) { Tptr Stack[NUMBER], p; int i,j,k; int sp; char temp[20]; char *ckalloc(); char *tname[NUMBER+1]; /* sequence name */ int tfrom[NUMBER], tto[NUMBER], tK; char *get_seqname(); FILE *fp, *ckopen(); int strsame(); char fname[40]; if (eflag) { /* read end points */ fp = ckopen(Ename,"r"); lav_read_init(fp); tK = 0; while ((tname[tK] = get_seqname(&tfrom[tK], &tto[tK],0))) if (++tK > NUMBER) fatal("The maximum number of sequences is %d",NUMBER); fclose(fp); } sp = 0; K = 0; i = 0; while (order[i] != '\0') { switch (order[i]) { case ')': if (sp < 2) fatal("wrong input format!"); p = (Tptr)ckalloc(sizeof(Tnode)); p->right = Stack[--sp]; p->left = Stack[--sp]; p->L = (p->left)->L; p->R = (p->right)->R; Stack[sp++] = p; case '(': case ']': case ' ': case '\t': ++i; break; default: if (++K > NUMBER) fatal("The maximum number of sequences is %d",NUMBER); j = strcspn(order+i,"( )\0\t"); strncpy(fname,order+i,j); /* printf("fname\n",K,fname[K]); */ i += j; L[K] = get_seq(fname,&S[K],&Sname[K],&From[K],&To[K]); S[K]--; /* printf("K=%d, Sname=%s, From=%d, To=%d\n",K,Sname[K],From[K],To[K]); fflush(stdout); */ p = (Tptr)ckalloc(sizeof(Tnode)); p->left = p->right = NULL; p->L = p->R = K; Stack[sp++] = p; break; } } if (sp != 1) fatal("wrong format!"); return Stack[0]; } /* traverse_tree - traverse the aligning tree */ int traverse_tree(Tptr tp) { int *ALS; int SL, i, l, r, n; int c; Tptr p,q; char *ckalloc(); p = tp->left; q = tp->right; if (p->L == p->R) { /* one to many */ p->AL = (char **) ckalloc((L[p->L]+1)*sizeof(char *)); p->AL[0] = (char *) ckalloc(L[p->L]+1); for (i=1; i<=L[p->L]; ++i) p->AL[i] = (p->AL[i-1])+1; StoAL(S[p->L],L[p->L],p->AL); p->N = L[p->L]; } else traverse_tree(p); if (q->L == q->R) { /* many to one */ q->AL = (char **) ckalloc((L[q->L]+1)*sizeof(char *)); q->AL[0] = (char *) ckalloc(L[q->L]+1); for (i=1; i<=L[q->L]; ++i) q->AL[i] = (q->AL[i-1])+1; StoAL(S[q->L],L[q->L],q->AL); q->N = L[q->L]; } else traverse_tree(q); /* printf("(%d %d)",tp->L,tp->R); */ ALS = (int *)ckalloc((p->N + q->N +1)*sizeof(int)); /* Mscore(p->AL,p->R - p->L, p->N, q->AL, q->R - q->L, q->N,p->L,q->L); */ c = MALIGN(p->AL,p->R - p->L, p->N, q->AL, q->R - q->L, q->N, ALS, &SL,p->L,q->L); n = tp->R - tp->L + 1; tp->AL = (char **)ckalloc((SL+1)*sizeof(char *)); tp->AL[0] = (char *)ckalloc(n*(SL+1)); for (i=1; i<=SL; ++i) tp->AL[i] = tp->AL[i-1] + n; MALStoMAL(p->AL,p->R - p->L, p->N, q->AL, q->R - q->L, q->N, ALS, SL, tp->AL); tp->N = SL; free(ALS); free(p->AL[0]); free(p->AL); free(q->AL[0]); free(q->AL); return c; } #define COST \ { DAG(DASH) = 0; \ DAG(SYMA) = m; \ DAG(SYMC) = m; \ DAG(SYMG) = m; \ DAG(SYMT) = m; \ SUB(DASH,SYMA) = -GE; \ SUB(DASH,SYMC) = -GE; \ SUB(DASH,SYMG) = -GE; \ SUB(DASH,SYMT) = -GE; \ SUB(SYMA,SYMC) = v; \ SUB(SYMA,SYMG) = v; \ SUB(SYMA,SYMT) = v; \ SUB(SYMC,SYMG) = v; \ SUB(SYMC,SYMT) = v; \ SUB(SYMG,SYMT) = v; \ \ DT([0][0][0][0]) = 0; /* -- : -- */ \ DT([0][0][0][1]) = G; /* -- : -x */ \ DT([0][0][1][0]) = G; /* -x : -- */ \ DT([0][0][1][1]) = 0; /* -x : -x */ \ DT([0][1][0][0]) = 0; /* -- : x- */ \ DT([0][1][0][1]) = 0; /* -- : xx */ \ DT([0][1][1][0]) = G; /* -x : x- */ \ DT([0][1][1][1]) = 0; /* -x : xx */ \ DT([1][0][0][0]) = 0; /* x- : -- */ \ DT([1][0][0][1]) = G; /* x- : -x */ \ DT([1][0][1][0]) = 0; /* xx : -- */ \ DT([1][0][1][1]) = 0; /* xx : -x */ \ DT([1][1][0][0]) = 0; /* x- : x- */ \ DT([1][1][0][1]) = G; /* x- : xx */ \ DT([1][1][1][0]) = G; /* xx : x- */ \ DT([1][1][1][1]) = 0; /* xx : xx */ \ \ \ /* Left end gaps */ \ DAG(LSTAR) = 0; \ SUBI(LSTAR,SYMA) = -LGGEI; \ SUBI(LSTAR,SYMC) = -LGGEI; \ SUBI(LSTAR,SYMG) = -LGGEI; \ SUBI(LSTAR,SYMT) = -LGGEI; \ SUBJ(LSTAR,SYMA) = -LGGEJ; \ SUBJ(LSTAR,SYMC) = -LGGEJ; \ SUBJ(LSTAR,SYMG) = -LGGEJ; \ SUBJ(LSTAR,SYMT) = -LGGEJ; \ SUB(LSTAR,DASH) = 0; \ \ DT([0][0][0][2]) = 0; /* -- : -* */ \ DTI([0][0][1][2]) = LGGJ; /* -x : -* */ \ DTJ([0][0][1][2]) = LGGI; /* -x : -* */ \ DT([0][0][2][0]) = 0; /* -* : -- */ \ DTI([0][0][2][1]) = LGGI; /* -* : -x */ \ DTJ([0][0][2][1]) = LGGJ; /* -* : -x */ \ DT([0][0][2][2]) = 0; /* -* : -* */ \ DT([0][1][0][2]) = 0; /* -- : x* */ \ DTI([0][1][1][2]) = LGGJ; /* -x : x* */ \ DTJ([0][1][1][2]) = LGGI; /* -x : x* */ \ DT([0][1][2][0]) = 0; /* -* : x- */ \ DT([0][1][2][1]) = 0; /* -* : xx */ \ DT([0][1][2][2]) = 0; /* -* : x* */ \ DT([1][0][0][2]) = 0; /* x- : -* */ \ DT([1][0][1][2]) = 0; /* xx : -* */ \ DT([1][0][2][0]) = 0; /* x* : -- */ \ DTI([1][0][2][1]) = LGGI; /* x* : -x */ \ DTJ([1][0][2][1]) = LGGJ; /* x* : -x */ \ DT([1][0][2][2]) = 0; /* x* : -* */ \ DT([1][1][0][2]) = 0; /* x- : x* */ \ DTI([1][1][1][2]) = LGGJ; /* xx : x* */ \ DTJ([1][1][1][2]) = LGGI; /* xx : x* */ \ DT([1][1][2][0]) = 0; /* x* : x- */ \ DTI([1][1][2][1]) = LGGI; /* x* : xx */ \ DTJ([1][1][2][1]) = LGGJ; /* x* : xx */ \ DT([1][1][2][2]) = 0; /* x* : x* */ \ \ /* Right end gaps */ \ DAG(RSTAR) = 0; \ SUBI(RSTAR,SYMA) = -RGGEI; \ SUBI(RSTAR,SYMC) = -RGGEI; \ SUBI(RSTAR,SYMG) = -RGGEI; \ SUBI(RSTAR,SYMT) = -RGGEI; \ SUBJ(RSTAR,SYMA) = -RGGEJ; \ SUBJ(RSTAR,SYMC) = -RGGEJ; \ SUBJ(RSTAR,SYMG) = -RGGEJ; \ SUBJ(RSTAR,SYMT) = -RGGEJ; \ SUB(RSTAR,DASH) = 0; \ \ DT([0][0][0][3]) = 0; /* -- : -* */ \ DTI([0][0][1][3]) = RGGJ; /* -x : -* */ \ DTJ([0][0][1][3]) = RGGI; /* -x : -* */ \ DT([0][0][3][0]) = 0; /* -* : -- */ \ DTI([0][0][3][1]) = RGGI; /* -* : -x */ \ DTJ([0][0][3][1]) = RGGJ; /* -* : -x */ \ DT([0][0][3][3]) = 0; /* -* : -* */ \ DT([0][1][0][3]) = 0; /* -- : x* */ \ DTI([0][1][1][3]) = RGGJ; /* -x : x* */ \ DTJ([0][1][1][3]) = RGGI; /* -x : x* */ \ DT([0][1][3][0]) = 0; /* -* : x- */ \ DT([0][1][3][1]) = 0; /* -* : xx */ \ DT([0][1][3][3]) = 0; /* -* : x* */ \ DT([1][0][0][3]) = 0; /* x- : -* */ \ DT([1][0][1][3]) = 0; /* xx : -* */ \ DT([1][0][3][0]) = 0; /* x* : -- */ \ DTI([1][0][3][1]) = RGGI; /* x* : -x */ \ DTJ([1][0][3][1]) = RGGJ; /* x* : -x */ \ DT([1][0][3][3]) = 0; /* x* : -* */ \ DT([1][1][0][3]) = 0; /* x- : x* */ \ DTI([1][1][1][3]) = RGGJ; /* xx : x* */ \ DTJ([1][1][1][3]) = RGGI; /* xx : x* */ \ DT([1][1][3][0]) = 0; /* x* : x- */ \ DTI([1][1][3][1]) = RGGI; /* x* : xx */ \ DTJ([1][1][3][1]) = RGGJ; /* x* : xx */ \ DT([1][1][3][3]) = 0; /* x* : x* */ \ \ SUB(LSTAR,RSTAR) = 0; \ DT([0][0][2][3]) = 0; /* -* : -@ */ \ DT([0][0][3][2]) = 0; \ DT([0][1][2][3]) = 0; \ DT([0][1][3][2]) = 0; \ DT([1][0][2][3]) = 0; \ DT([1][0][3][2]) = 0; \ DT([1][1][2][3]) = 0; \ DT([1][1][3][2]) = 0; \ } /* data : read input scoring scheme */ void data () { auto int i, j; auto int m, v; auto int G, GE; /* gap cost */ auto int LGGI, LGGJ, LGGEI, LGGEJ; /* end gap cost */ auto int RGGI, RGGJ, RGGEI, RGGEJ; /* end gap cost */ auto char first_time; /* printf("\n G GE match mismatch\n"); */ for (i=1; i 0) { AL[++k][0] = DASH; AL[k][1] = S2[++j]; op--; } else { AL[++k][0] = S1[++i]; AL[k][1] = DASH; op++; } } } } /* MALStoMAL - generate a multiple alignment according to the script */ void MALStoMAL(char **AL1, int M1, int N1, char **AL2, int M2, int N2, int ALS[], int SL, char **AL) { int i,j,k,op; char *alk, *alt; int I,J; int MM; MM = M1+M2+1; for (I=0; I<=MM; ++I) AL[0][I] = DASH; i = j = k = op = 0; while (i < N1 || j < N2) { if (op == 0 && *ALS == 0) { op = *ALS++; ++i; ++j; ++k; alk = AL[k]; alt = AL1[i]; for (I=0; I<=M1; ++I) alk[I]=alt[I]; alt = AL2[j]; for (I=0; I<=M2; ++I) alk[M1+1+I]=alt[I]; } else { if (op == 0) op = *ALS++; if (op > 0) { ++j; ++k; alk = AL[k]; for (I=0; I<=M1; ++I) alk[I]=DASH; alt = AL2[j]; for (I=0; I<=M2; ++I) alk[M1+1+I]=alt[I]; op--; } else { ++i; ++k; alk = AL[k]; alt = AL1[i]; for (I=0; I<=M1; ++I) alk[I]=alt[I]; for (I=0; I<=M2; ++I) alk[M1+1+I]=DASH; op++; } } } } /* MDisplay - display a multiple alignment */ void MDisplay(char **AL, int M, int N) { int i,j,k; int POS[NUMBER]; for (k=0; k<=M; ++k) POS[k] = From[k+1]; for (i=1; i<=N; i=i+LL) { printf(" "); for (j=i+1; j<=N+1 && j=1 && AL1[j][i]==DASH) { HE1[j][i] = E1[j][i] = RSTAR; --j; } HE1[j][i] = RSTAR; } for (j=0; j<=N2; ++j) { e2 = E2[j]; ve2 = VE2[j]; for (i=0; i<=M2; ++i) ve2[i] = e2[i] = DASH; } for (i=0; i<=M2; ++i) { j = 0; while (j<=N2 && AL2[j][i]==DASH) { VE2[j][i] = E2[j][i] = LSTAR; ++j; } j = N2; while (j>=1 && AL2[j][i]==DASH) { VE2[j][i] = E2[j][i] = RSTAR; --j; } VE2[j][i] = RSTAR; } /* Compute projection cost within AL1 and AL2 */ C1[0] = 0; pal = AL1[0]; for (i=1; i<=N1; ++i) { t = 0; e1 = E1[i]; cal = AL1[i]; for (I=0; I i1) DEL(i2-i1) return; } if (i2-i1 <= 0) { INS(j2-j1) return; } /* rounded up; for the sake of the two-row case */ midi = (i1+i2+1)/2; /* Forward computation */ /* Initialize the first row */ HH[j1] = hh; VV[j1] = vv; DD[j1] = dd; cal1 = AL1[i1]; pal2 = AL2[j1]; he1 = HE1[i1]; for (j=j1+1; j<=j2; ++j) { cal2 = AL2[j]; e2 = E2[j]; hg = HH[j-1]; vg = VV[j-1]; dg = DD[j-1]; c = C2[j]; for (I=0; I<=M2; ++I) { cj = ET(cal2[I],e2[I]); for (J=0; J<=M1; ++J) c += PD(L1+J,L2+I,he1[J],cj); } for (I=0; I<=M1; ++I) { ci = cal1[I]; ei = GV(he1[I]); for (J=0; J<=M2; ++J) { cj = GV(cal2[J]); pj = pal2[J]; hg -= PT[L1+I][L2+J][0][pj!=DASH][ei][cj]; vg -= PT[L1+I][L2+J][ci!=DASH][0][ei][cj]; dg -= PT[L1+I][L2+J][ci!=DASH][pj!=DASH][ei][cj]; } } /* for (I=0; I=j1; --j) { pal2 = AL2[j]; c = C2[j+1]; e2 = E2[j+1]; for (I=0; I<=M2; ++I) { cj = ET(cal2[I],e2[I]); for (J=0; J<=M1; ++J) c += PD(L2+I,L1+J,cj,he1[J]); } d = v = h += c; /* for (I=0; I=midi; --i) { pal1 = AL1[i]; cal2 = AL2[j2]; /* Initialize the last column */ c = C1[i+1]; e1 = E1[i+1]; ve2 = VE2[j2]; for (I=0; I<=M1; ++I) { ci = ET(cal1[I],e1[I]); for (J=0; J<=M2; ++J) c += PD(L1+I,L2+J,ci,ve2[J]); } d = h = v = RV[j2] + c; /* for (I=0; I=j1; --j) { pal2 = AL2[j]; e2 = E2[j+1]; ve2 = VE2[j]; /* Compute RD, RH, RV affected by the diagonal edge */ c = C1[i+1] + C2[j+1]; for (I=0; I<=M1; ++I) { ci = ET(cal1[I],e1[I]); for (J=0; J<=M2; ++J) { cj = ET(cal2[J],e2[J]); c += PD(L1+I,L2+J,ci,cj); } } hg = vg = dg = RD[j+1]; RH[j+1] = h; RV[j+1] = v; RD[j+1] = d; for (I=0; I<=M1; ++I) { ETGV(ci,cal1[I],e1[I]) pi = pal1[I]; for (J=0; J<=M2; ++J) { ETGV(cj,cal2[J],e2[J]) pj = pal2[J]; hg -= PT[L1+I][L2+J][0][pj!=DASH][ci][cj]; vg -= PT[L1+I][L2+J][pi!=DASH][0][ci][cj]; dg -= PT[L1+I][L2+J][pi!=DASH][pj!=DASH][ci][cj]; } } /* for (I=0; I h) h = c+hg; if (c+vg > v) v = c+vg; if (c+dg > d) d = c+dg; /* Compute RD, RH, RV affected by the vertical edge */ c = C1[i+1]; for (I=0; I<=M1; ++I) { ci = ET(cal1[I],e1[I]);; for (J=0; J<=M2; ++J) c += PD(L1+I,L2+J,ci,ve2[J]); } hg = dg = vg = RV[j]; for (I=0; I<=M1; ++I) { ci = GV(cal1[I]); pi = pal1[I]; for (J=0; J<=M2; ++J) { ej = GV(ve2[J]); pj = pal2[J]; hg -= PT[L1+I][L2+J][0][pj!=DASH][ci][ej]; vg -= PT[L1+I][L2+J][pi!=DASH][0][ci][ej]; dg -= PT[L1+I][L2+J][pi!=DASH][pj!=DASH][ci][ej]; } } /* for (I=0; I h) h = c+hg; if (c+vg > v) v = c+vg; if (c+dg > d) d = c+dg; /* printf("i=%d, j=%d, d=%d, h=%d, v=%d\n",i,j,d,h,v); */ cal2 = pal2; } cal1 = pal1; RH[j1] = h; RV[j1] = v; RD[j1] = d; } /* printf("malign: d=%d, v=%d, h=%d\n",d,v,h); printf("score=%d\n",max3(d,v,h)); */ /* Determine optimal midpoint */ midc = max(VV[j1]+RV[j1],DD[j1]+RD[j1]); midj = j1; for (j=j1+1; j<=j2; ++j) { if ((t = max(VV[j]+RV[j],DD[j]+RD[j])) > midc) { midc = t; midj = j; } } /* printf("i1=%d, i2=%d, j1=%d, j2=%d, midscore=%d, midj=%d\n",i1,i2,j1,j2,midc,midj); */ if (i2-i1 <= 1) { /* two-row case */ if (midc == (VV[midj]+RV[midj])) { /* vertical edge */ if (midj > j1) INS(midj-j1) DEL(1) if (midj < j2) INS(j2-midj) } else { /* diagonal edge */ if (midj-1 > j1) INS(midj-1-j1) REP if (midj < j2) INS(j2-midj) } } else { /* Divide into two subproblems */ /* save overlapped variables */ h = HH[midj]; v = VV[midj]; d = DD[midj]; if (midc == (VV[midj]+RV[midj])) { /* vertical edge */ malign(i1,j1,hh,vv,dd,midi,midj,MININT,RV[midj],MININT); malign(midi,midj,MININT,v,MININT,i2,j2,rh,rv,rd); } else { /* diagonal edge */ malign(i1,j1,hh,vv,dd,midi,midj,MININT,MININT,RD[midj]); malign(midi,midj,MININT,MININT,d,i2,j2,rh,rv,rd); } } fflush(stdout); return midc; } /* Mscore - return the optimum score of two alignments alignment */ int Mscore(char **AL1, int M1, int N1, char **AL2, int M2, int N2, int L1, int L2) { int i, j, I, J; int h, v, d, t, c; int hg, vg, dg; char *cal, *pal; char *cal1, *pal1, *cal2, *pal2; char ci, cj, pi, pj, ei, ej; char *ckalloc(); char *e1, *e2; char *he1, *ve2; j = (N1+1) * sizeof(int); C1 = (int *) ckalloc(j); j = (N2+1) * sizeof(int); C2 = (int *) ckalloc(j); HH = (int *) ckalloc(j); VV = (int *) ckalloc(j); DD = (int *) ckalloc(j); E1 = (char **) ckalloc((N1+1)*sizeof(char *)); E1[0] = (char *) ckalloc((M1+1)*(N1+1)); HE1 = (char **) ckalloc((N1+1)*sizeof(char *)); HE1[0] = (char *) ckalloc((M1+1)*(N1+1)); for (i=1; i<=N1; ++i) { E1[i] = E1[i-1]+(M1+1); HE1[i] = HE1[i-1]+(M1+1); } E2 = (char **) ckalloc((N2+1)*sizeof(char *)); E2[0] = (char *) ckalloc((M2+1)*(N2+1)); VE2 = (char **) ckalloc((N2+1)*sizeof(char *)); VE2[0] = (char *) ckalloc((M2+1)*(N2+1)); for (i=1; i<=N2; ++i) { E2[i] = E2[i-1]+(M2+1); VE2[i] = VE2[i-1]+(M2+1); } /* Compute E1 and E2 */ for (j=0; j<=N1; ++j) { e1 = E1[j]; he1 = HE1[j]; for (i=0; i<=M1; ++i) he1[i] = e1[i] = DASH; } for (i=0; i<=M1; ++i) { j = 0; while (j<=N1 && AL1[j][i]==DASH) { HE1[j][i] = E1[j][i] = LSTAR; ++j; } j = N1; while (j>=1 && AL1[j][i]==DASH) { HE1[j][i] = E1[j][i] = RSTAR; --j; } HE1[j][i] = RSTAR; } for (j=0; j<=N2; ++j) { e2 = E2[j]; ve2 = VE2[j]; for (i=0; i<=M2; ++i) ve2[i] = e2[i] = DASH; } for (i=0; i<=M2; ++i) { j = 0; while (j<=N2 && AL2[j][i]==DASH) { VE2[j][i] = E2[j][i] = LSTAR; ++j; } j = N2; while (j>=1 && AL2[j][i]==DASH) { VE2[j][i] = E2[j][i] = RSTAR; --j; } VE2[j][i] = RSTAR; } /* Compute projection cost within AL1 and AL2 */ for (i=0; i<=N1; ++i) { t = 0; cal = AL1[i]; e1 = E1[i]; for (I=0; I=1 && AL[j][i]==DASH) { E1[j][i] = RSTAR; --j; } } score = 0; pal = AL[0]; for (j=1; j<=N; ++j) { e1 = E1[j]; cal = AL[j]; for (I=0; Iy) if (x>z) return x; else return z; else if (y>z) return y; else return z; }