/* program: 二つのアミノ酸配列のアラインメントとアラインメント・スコアの計算 file: scoreout.c date: 2003/7/7 by O.W */ #include #include #include #define MAXLENG 1500 /* 配列長最大値 */ #define ASIZE 23 /* アミノ酸の種類(種類は 22 個,その他の分類が 1 個)*/ #define INFTY -70000 /* 無限値(ありえないスコア)*/ #define GOPEN -10 /* ギャップを開くときのペナルティ */ #define GEXT -1 /* ギャップを続けるときのペナルティ */ /* スコア表 BLOSUM-62 */ int TBL[ASIZE+1][ASIZE+1] = { { -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 }, { -9, 4,-1,-2,-2, 0,-1,-1, 0,-2,-1,-1,-1,-1,-2,-1, 1, 0,-3,-2, 0,-2,-1, 0 }, { -9,-1, 5, 0,-2,-3, 1, 0,-2, 0,-3,-2, 2,-1,-3,-2,-1,-1,-3,-2,-3,-1, 0,-1 }, { -9,-2, 0, 6, 1,-3, 0, 0, 0, 1,-3,-3, 0,-2,-3,-2, 1, 0,-4,-2,-3, 3, 0,-1 }, { -9,-2,-2, 1, 6,-3, 0, 2,-1,-1,-3,-4,-1,-3,-3,-1, 0,-1,-4,-3,-3, 4, 1,-1 }, { -9, 0,-3,-3,-3, 9,-3,-4,-3,-3,-1,-1,-3,-1,-2,-3,-1,-1,-2,-2,-1,-3,-3,-2 }, { -9,-1, 1, 0, 0,-3, 5, 2,-2, 0,-3,-2, 1, 0,-3,-1, 0,-1,-2,-1,-2, 0, 3,-1 }, { -9,-1, 0, 0, 2,-4, 2, 5,-2, 0,-3,-3, 1,-2,-3,-1, 0,-1,-3,-2,-2, 1, 4,-1 }, { -9, 0,-2, 0,-1,-3,-2,-2, 6,-2,-4,-4,-2,-3,-3,-2, 0,-2,-2,-3,-3,-1,-2,-1 }, { -9,-2, 0, 1,-1,-3, 0, 0,-2, 8,-3,-3,-1,-2,-1,-2,-1,-2,-2, 2,-3, 0, 0,-1 }, { -9,-1,-3,-3,-3,-1,-3,-3,-4,-3, 4, 2,-3, 1, 0,-3,-2,-1,-3,-1, 3,-3,-3,-1 }, { -9,-1,-2,-3,-4,-1,-2,-3,-4,-3, 2, 4,-2, 2, 0,-3,-2,-1,-2,-1, 1,-4,-3,-1 }, { -9,-1, 2, 0,-1,-3, 1, 1,-2,-1,-3,-2, 5,-1,-3,-1, 0,-1,-3,-2,-2, 0, 1,-1 }, { -9,-1,-1,-2,-3,-1, 0,-2,-3,-2, 1, 2,-1, 5, 0,-2,-1,-1,-1,-1, 1,-3,-1,-1 }, { -9,-2,-3,-3,-3,-2,-3,-3,-3,-1, 0, 0,-3, 0, 6,-4,-2,-2, 1, 3,-1,-3,-3,-1 }, { -9,-1,-2,-2,-1,-3,-1,-1,-2,-2,-3,-3,-1,-2,-4, 7,-1,-1,-4,-3,-2,-2,-1,-2 }, { -9, 1,-1, 1, 0,-1, 0, 0, 0,-1,-2,-2, 0,-1,-2,-1, 4, 1,-3,-2,-2, 0, 0, 0 }, { -9, 0,-1, 0,-1,-1,-1,-1,-2,-2,-1,-1,-1,-1,-2,-1, 1, 5,-2,-2, 0,-1,-1, 0 }, { -9,-3,-3,-4,-4,-2,-2,-3,-2,-2,-3,-2,-3,-1, 1,-4,-3,-2,11, 2,-3,-4,-3,-2 }, { -9,-2,-2,-2,-3,-2,-1,-2,-3, 2,-1,-1,-2,-1, 3,-3,-2,-2, 2, 7,-1,-3,-2,-1 }, { -9, 0,-3,-3,-3,-1,-2,-2,-3,-3, 3, 1,-2, 1,-1,-2,-2, 0,-3,-1, 4,-3,-2,-1 }, { -9,-2,-1, 3, 4,-3, 0, 1,-1, 0,-3,-4, 0,-3,-3,-2, 0,-1,-4,-3,-3, 4, 1,-1 }, { -9,-1, 0, 0, 1,-3, 3, 4,-2, 0,-3,-3, 1,-1,-3,-1, 0,-1,-3,-2,-2, 1, 4,-1 }, { -9, 0,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2, 0, 0,-2,-1,-1,-1,-1,-1 } }; /* 補足: 1. BLAST http://www.ncbi.nlm.nih.gov/blast/html/sub_matrix.html より 2. アルファベット(アミノ酸記号)とインデックスの対応は以下の表の通り */ /* アルファベット表(X は「その他」用)*/ int C2N[26] = { /* char --> index */ 1,21, 5, 4, 7,14, 8, 9,10, 0,12,11,13, 3, 0,15, 6, 2,16,17, 0,20,18,23,19,22 /* A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z */ }; int N2C[24] = { /* index --> char */ '*', 'A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I', 'L', 'K', 'M', 'F', 'P', 'S', 'T', 'W', 'Y', 'V', 'B', 'Z', 'X' }; /* 大域変数 */ int SEQ1[MAXLENG+1], SEQ2[MAXLENG+1]; /* アミノ酸配列 */ int STB[MAXLENG+1][MAXLENG+1][3]; /* スコア計算のための表 */ void maketb(int, int); void out(int, int); int max(int x, int y) { return x > y ? x : y; } int max3(int x, int y, int z) { return max(max(x, y), z); } int min(int x, int y) { return x < y ? x : y; } int main(int argc, char *argv[]) { int leng; int m, n, i; FILE *fp; char instr[MAXLENG]; /* データ列の読み込み */ fp = fopen("proteins-smallexample.txt", "r"); if(!fp){ printf("File open error!\n"); exit(1); } fgets(instr, MAXLENG + 1, fp); leng = strlen(instr); for(i = 0; i < leng; i++) { if(instr[i] == '%') break; SEQ1[i+1] = C2N[instr[i] - 'A']; } m = i; fgets(instr, MAXLENG + 1, fp); leng = strlen(instr); for(i = 0; i < leng; i++) { if(instr[i] == '%') break; SEQ2[i+1] = C2N[instr[i] - 'A']; } n = i; fclose(fp); /* score, seq. id. の計算 */ maketb(m, n); out(m, n); return 0; } void maketb(int m, int n) { int i, j; /* 探索打ち切り */ /* 解説:一方の列が終わったらペナルティ 0 で打ち切ってよい */ for(i = 1; i <= m; i++) STB[i][n][0] = TBL[SEQ1[i]][SEQ2[n]]; for(j = 1; j <= n; j++) STB[m][j][0] = TBL[SEQ1[m]][SEQ2[j]]; /* 探索打ち切り */ /* 解説:ギャップ途中で一方の列が終わることは許されない */ for(i = 1; i <= m; i++) STB[i][n][1] = TBL[SEQ1[i]][SEQ2[n]]; for(j = 1; j <= n; j++) STB[m][j][2] = TBL[SEQ1[m]][SEQ2[j]]; /* STB の計算 */ for(i = m - 1; i >= 1; i--) { int ch = SEQ1[i]; for(j = n - 1; j >= 1; j--) { STB[i][j][0] = max3(STB[i+1][j+1][0] + TBL[ch][SEQ2[j]], STB[ i ][j+1][1] + GOPEN, STB[i+1][ j ][2] + GOPEN); STB[i][j][1] = max(STB[i+1][j+1][0] + TBL[ch][SEQ2[j]], STB[ i ][j+1][1] + GEXT); STB[i][j][2] = max(STB[i+1][j+1][0] + TBL[ch][SEQ2[j]], STB[i+1][ j ][2] + GEXT); } } /* デバッグ用 for(i = 1; i <= m; i++){ for(j = 1; j <= n; j++) printf("%d, ", STB[i][j][0]); printf("\n"); } for(i = 1; i <= m; i++){ for(j = 1; j <= n; j++) printf("%d, ", STB[i][j][1]); printf("\n"); } for(i = 1; i <= m; i++){ for(j = 1; j <= n; j++) printf("%d, ", STB[i][j][2]); printf("\n"); } printf("\n");printf("\n"); exit(1); */ return; } int putout(int g, int i, int j, int k, int s, int s1, int s2, int s3, char xout[], char yout[]) { if (s == s1) { xout[k] = N2C[SEQ1[i]]; yout[k] = N2C[SEQ2[j]]; return 0; } if (s == s2) { xout[k] = '-'; yout[k] = N2C[SEQ2[j]]; return 1; } if (s == s3) { xout[k] = N2C[SEQ1[i]]; yout[k] = '-'; return 2; } printf("ERROR AT OUT: %d/ %d, %d; %d, %d, %d, %d\n", g, i, j, s, s1, s2, s3); exit(-1); } void out(int m, int n) { int i, j, g, k; int ii, jj; int s, s1, s2; int maxs, maxi, maxj, maxk; char xout[MAXLENG+1], yout[MAXLENG+1]; /* 最適スタート地点を探す */ s1 = INFTY; for(j = 1; j <= n; j++) { s = STB[1][j][0]; if(s > s1) { s1 = s; maxj = j; } } s2 = INFTY; for(i = 1; i <= m; i++) { s = STB[1][j][0]; if(s > s2) { s2 = s; maxi = i; } } if(s1 > s2) { maxs = s1; maxi = 1; maxk = maxj; } else { maxs = s2; maxj = 1; maxk = maxi; } /* 出力する文字列の作成(先頭部分)*/ i = j = 1; for(k = 1; k < maxk; k++) { if(maxi == 1) { xout[k] = ' '; yout[k] = N2C[SEQ2[j]]; j++; } else { xout[k] = N2C[SEQ1[i]]; yout[k] = ' '; i++; } } /* 出力する文字列の作成(本体)*/ i = maxi; j = maxj; k = maxk - 1; g = 0; while (i <= m && j <= n) { int ch = SEQ1[i]; k++; switch (g) { case 0: g = putout(g, i, j, k, STB[ i ][ j ][g], STB[i+1][j+1][0] + TBL[ch][SEQ2[j]], STB[ i ][j+1][1] + GOPEN, STB[i+1][ j ][2] + GOPEN, xout, yout); break; case 1: g = putout(g, i, j, k, STB[ i ][ j ][g], STB[i+1][j+1][0] + TBL[ch][SEQ2[j]], STB[ i ][j+1][1] + GEXT, INFTY, xout, yout); break; case 2: g = putout(g, i, j, k, STB[ i ][ j ][g], STB[i+1][j+1][0] + TBL[ch][SEQ2[j]], INFTY, STB[i+1][ j ][2] + GEXT, xout, yout); } switch (g) { case 0: i++; j++; break; case 1: j++; break; case 2: i++; } } /* 結果の出力 */ printf("score = %d, seq. id. = %d\n", maxs, maxs * 100 / min(m, n)); printf("SEQ1 (%4d): ", m); for(ii = 1; ii <= k; ii++) printf("%c", xout[ii]); for(;i <= m; i++) printf("%c", N2C[SEQ1[i]]); printf("\n"); printf("SEQ2 (%4d): ", n); for(jj = 1; jj <= k; jj++) printf("%c", yout[jj]); for(;j <= n; j++) printf("%c", N2C[SEQ2[j]]); printf("\n"); return; }