情報基礎A 「Cプログラミング」総合演習

このページでは、DNAの塩基配列データをCのプログラムで扱うための「支援プログラム」について、使い方や仕様を説明する。

「支援プログラム」の仕様

データの表現

ヌクレオチドの塩基は、記号としてではなく、数値で表現するようプログラムされている。その対応は

塩基 対応する数値 記号
T (またはU) 1 NUC_T
C 2 NUC_C
A 3 NUC_A
G 4 NUC_G

NUC_Tは、そこに1と書くのと同じである。他の塩基についても同様。(3.141592...と書くかわりにM_PIと書 くことができたのと同じ原理)。

アミノ酸も同様に、数値として扱うようプログラムされている。対応する数値は、ga-helper.cを見れば一目瞭然なので、ここでは省略する。

GenBank形式のデータの読み出し

int n ;
int data[5000] ;

・・・
n = readGBK("データファイル名",data) ;

あらかじめ、データを格納するのに十分な大きさの整数型配列を用意しておく(上では5000塩基対分)。 readGBK関数を実行すると、読み込まれた塩基対の数が返される(上の例では変数nにセットされる)。 塩基の系列は、配列変数(data)の先頭から、T,C,A,Gに対応した数値(1,2,3,4)に変換され、順に格納されている。 先頭の塩基は data[0]、末尾のデータは data[n-1]ということになる。

この関数を実行すると、読み込みファイル名と、読み込まれた塩基対の数が、画面に出力される。

塩基配列の画面への出力

printNuc(塩基対の数, データを入れた配列名) ;

塩基を表す数値の並びを、T,A,C,Gの記号の列として、画面にプリントする。

  data[0]=NUC_A ;
  data[1]=NUC_C ;
  data[2]=NUC_G ;
  data[3]=NUC_T ;
  data[4]=NUC_A ;
  data[5]=NUC_C ;
  printNuc(6,data) ;

上記のプログラム(の部分)を実行すると、画面には

ACGTAC

と表示される。この場合、6塩基なので6を渡している点に注目。なお、配列の末尾では改行される。

塩基のトリプレットからアミノ酸コードへの変換

 a = aminoAcid(n1,n2,n3) ;

タンパクをコードする3つの塩基(トリプレット)とアミノ酸の対応関係を求めるための関数。 塩基を表す数値を三つ与えると(n1,n2,n3)、それに対応するアミノ酸を表すコード(数値)を返す。 プログラム中では、20種類のアミノ酸に対応づけて、1から20までの整数を割り当てている。 ただし、アミノ酸をコードしていない組(TGA,TAA,TAG:終了コード)には -1 を割り当てている。

塩基のトリプレット対応するアミノ酸の記号をプリント

 printAminoAcid(n1,n2,n3) ;

塩基を表す数値を三つ与えると(n1,n2,n3)、それに対応するアミノ酸を表す記号(1文字)をプリントする。 例えば、printAminoAcid(1,1,1);は、”F"をプリント。 文字をプリントした後、改行はされない。

塩基のトリプレットの塩基配列をプリント

 printTriplet(n1,n2,n3) ;

塩基を表す数値を三つ与えると(n1,n2,n3)、それに対応する塩基を表す記号(3文字)をプリントする。 例えば、printTriplet(1,1,1);は、”TTT"をプリント。 文字をプリントした後、改行はされない。

プログラムリスト(ga-helper.c)

/* Written for Joho Kiso A                 */
/* Yoshinori Hayakawa, 2011                */
/* !!! DO NOT EDIT THE FOLLOWING LINES !!! */
#include <stdlib.h>
#include <strings.h>
#define BUFSIZE 1024
#define YES 1
#define NO 0
/* defs for nucleotide */
#define NUC_T 1
#define NUC_U 1
#define NUC_C 2
#define NUC_A 3
#define NUC_G 4
/* defs for amino acid */
#define AA_A 1
#define AA_C 2
#define AA_D 3
#define AA_E 4
#define AA_F 5
#define AA_G 6
#define AA_H 7
#define AA_I 8
#define AA_K 9
#define AA_L 10
#define AA_M 11
#define AA_N 12
#define AA_P 13
#define AA_Q 14
#define AA_R 15
#define AA_S 16
#define AA_T 17
#define AA_V 18
#define AA_W 19
#define AA_Y 20
#define AA_X (-1) /* terminate code */


int readGBK(char *filename, int *nucdata)
{
  FILE *fp ;
  char line[BUFSIZE],buf1[BUFSIZE],buf2[BUFSIZE] ;
  int n,started=NO ;
  fp = fopen(filename,"r") ;
  if (fp==NULL) {
    fprintf(stderr,"cannot open file: %s\n",filename) ;
    return 0 ;
  }
  fprintf(stderr,"reading: %s\n",filename) ;
  while (1) {
    if (fgets(line, BUFSIZE-1, fp)==NULL) break ;
    sscanf(line,"%s%[^\n]",buf1,buf2) ;
    if ( !strcmp(buf1,"ORIGIN") ) {
      started = YES ; n=0 ;
    }
    else if  ( !strcmp(buf1,"//")) {
      started = NO ;
    } 
    else {
      if (started) {
	int i ;
	for (i=0; i<strlen(buf2); i=i+1) {
	  switch (buf2[i]) {
	  case 'a': case 'A': nucdata[n]=NUC_A ; n=n+1 ; break ;
	  case 'u': case 'U':
	  case 't': case 'T': nucdata[n]=NUC_T ; n=n+1 ; break ;
	  case 'c': case 'C': nucdata[n]=NUC_C ; n=n+1 ; break ;
	  case 'g': case 'G': nucdata[n]=NUC_G ; n=n+1 ; break ;
	  default: ;
	  }
	}
      }
    }
  }
  fclose(fp) ;
  fprintf(stderr,"%d bp\n",n) ;
  return n ;
}

int aminoAcid(int x,int y, int z)
{
  int tab[]={
    AA_F, AA_F, AA_L, AA_L, AA_S, AA_S, AA_S, AA_S, AA_Y, AA_Y, AA_X, AA_X, AA_C, AA_C, AA_X, AA_W,
    AA_L, AA_L, AA_L, AA_L, AA_P, AA_P, AA_P, AA_P, AA_H, AA_H, AA_Q, AA_Q, AA_R, AA_R, AA_R, AA_R,
    AA_I, AA_I, AA_I, AA_M, AA_T, AA_T, AA_T, AA_T, AA_N, AA_N, AA_K, AA_K, AA_S, AA_S, AA_R, AA_R,
    AA_V, AA_V, AA_V, AA_V, AA_A, AA_A, AA_A, AA_A, AA_D, AA_D, AA_E, AA_E, AA_G, AA_G, AA_G, AA_G} ;
  int k = (x-1)*16 + (y-1)*4 + (z-1) ;
  if (k>=0 && k<64) return tab[k] ;
  else return 0 ;
}

void printAminoAcid(int x,int y, int z)
{
  char c, k = aminoAcid(x,y,z) ;
  switch (k) {
  case AA_A: c='A' ; break ;
  case AA_C: c='C' ; break ;
  case AA_D: c='D' ; break ;
  case AA_E: c='E' ; break ;
  case AA_F: c='F' ; break ;
  case AA_G: c='G' ; break ;
  case AA_H: c='H' ; break ;
  case AA_I: c='I' ; break ;
  case AA_K: c='K' ; break ;
  case AA_L: c='L' ; break ;
  case AA_M: c='M' ; break ;
  case AA_N: c='N' ; break ;
  case AA_P: c='P' ; break ;
  case AA_Q: c='Q' ; break ;
  case AA_R: c='R' ; break ;
  case AA_S: c='S' ; break ;
  case AA_T: c='T' ; break ;
  case AA_V: c='V' ; break ;
  case AA_W: c='W' ; break ;
  case AA_Y: c='Y' ; break ;
  case AA_X: c='x' ; break ;
  default: c='?' ;
  }
  printf("%c",c) ;
}

void printNuc(int n, int *nucdata)
{
  int i,c ;
  for (i=0 ; i<n ; i=i+1) {
    c = nucdata[i] ;
    switch (c) {
    case NUC_A: printf("A") ; break ;
    case NUC_T: printf("T") ; break ;
    case NUC_C: printf("C") ; break ;
    case NUC_G: printf("G") ; break ;
    default:;
    }
  }
  printf("\n") ;
}

void printTriplet(int x, int y, int z)
{
  int i,trip[3]={x,y,z} ;
  for (i=0 ; i<3 ; i=i+1) {
    switch (trip[i]) {
    case NUC_A: printf("A") ; break ;
    case NUC_T: printf("T") ; break ;
    case NUC_C: printf("C") ; break ;
    case NUC_G: printf("G") ; break ;
    default:;
    }
  }
}