/************************************************************************* * Ultima Modificacao: 27/04/2005 - Renatha Oliva Capua * * Last edited on 2005-05-26 17:07:01 by stolfi * * Last edited on 2005-06-11 20:14:12 by rcapua * * * * Universidade Federal Fluminense * * Mestrado em Computacao * * Aluna: Renatha Oliva Capua * * Orientadores: Helena Cristina da Gama Leitao * * Jorge Stolfi * * * * tratar_bd.c - Programa que le as bases de dados EID de (Saxonov et * * al, 2000) sedidas por Alexei Fedorov e calcula as frequencias das * * triplas em sequencias de exons e introns de organismos eucariotos. * *************************************************************************/ #include "tratar_bd.h" /************************************************************************* * Procedimento que grava em um arquivo a fila de elementos com a * * classificacao da sequencia. * *************************************************************************/ void gravar_arq(tno **prim, char *nome_arq, FILE **pt, int *cnt){ FILE *pt_aux; tno *no_aux; pt_aux = *pt; if (pt_aux == NULL){ abrir_arq(nome_arq, &pt_aux, "w+"); fprintf(pt_aux, ">arquivo com o rotulo para as bases extraidas do arquivo:%s\n",nome_arq); } no_aux = *prim; while(no_aux != NULL){ if (*cnt == 80){ fprintf(pt_aux,"\n"); *cnt = 0; } fprintf(pt_aux, "%c", no_aux->elemento); no_aux = no_aux->prox; *cnt = *cnt + 1; }//fim do while *pt = pt_aux; }//fim do gravar_arq_classif /************************************************************************* * Procedimento que grava em um arquivo a fila de elementos com a * * classificacao da sequencia. * *************************************************************************/ void desalocar_lista(tno **prim){ tno *no_aux; no_aux = *prim; while (no_aux != NULL){ *prim = no_aux->prox; free(no_aux); no_aux = *prim; } }//fim do desalocar_classif /************************************************************************* * Procedimento deve liberar a memoria se o tamanho da lista chegar a * * MAX_BASES. * *************************************************************************/ void liberar_memoria(tno **prim, tno **ult, FILE **pt, char *nome_arq, int *tam_lista, int *col){ if (*tam_lista == MAX_BASES){ gravar_arq(prim, nome_arq, pt, col); desalocar_lista(prim); *prim = NULL; *ult = NULL; *tam_lista = 0; }//fim do if }//fim do liberar_memoria /************************************************************************* * Procedimento que guarda o elemento(a tupla ou o rotulo) passado como * * parametro e inclui na lista * *************************************************************************/ void guardar_elemento(char elemento, tno **prim, tno **ult){ tno *prim_aux, *ult_aux, *no; prim_aux = *prim; ult_aux = *ult; no = (tno*) malloc (sizeof(tno)); no->elemento = elemento; no->prox = NULL; if (prim_aux == NULL){ prim_aux = no; ult_aux = no; }else{ ult_aux->prox = no; ult_aux = no; } *prim = prim_aux; *ult = ult_aux; }//fim do guardar_elemento /************************************************************************* * Procedimento que retira as informacoes relevantes do cabecalho do * * arquivo, tais como: gene_id, cds_start e cds_end. * *************************************************************************/ void extrair_cabecalho(FILE **pt_seq, int *splice_invalido, int *cds_start, int *cds_end, int *cds_len, char *gene_id){ char inf[35000], cds_start_aux[15], cds_end_aux[15], cds_len_aux[25]; char *pt; int cnt; FILE *pt_seq_aux; pt_seq_aux = *pt_seq; strcpy(cds_start_aux ,"\0"); strcpy(cds_end_aux,"\0"); strcpy(cds_len_aux,"\0"); strcpy(gene_id,"\0"); strcpy(inf, "\0"); *splice_invalido = 0; fgets(inf, sizeof(inf), pt_seq_aux); /*guarda o cabecalho inteiro(ate' \n) em inf*/ /*para armazenar o gene_id - número único de identificacao do gene*/ pt = strstr(inf,"gene="); /*procura o label gene= em inf*/ if(*pt == 'g'){ /*testa se pt retornou mesmo o ponteiro para gene*/ for(cnt = 0; cnt < 6; cnt++) /*move o ponteiro ate o final do label(gene=)*/ pt++; while(*pt != '\"'){ /*enquanto nao for o final do numero indicado por (") */ str_cat(gene_id,*pt); if(*pt == '\n') /*se achar o \n significa que nao achou o gene_id */ break; pt++; }//fim do while }//fim do if /* Splice com EEEE indica que o intron entre cds's possui menos de 4 bases podendo ser algum erro tipográfico*/ pt = strstr(inf,"EEEE"); /* Procura o label "EEEE" em inf */ if (pt != NULL) *splice_invalido = 1; /*para armazenar o valor da cds_start*/ pt = strstr(inf,"CDS_start="); /*procura o label CDS_start em inf*/ if (*pt == 'C'){ /*tenta testar se pt retornou mesmo o ponteiro para CDS_START*/ for (cnt = 0; cnt < 10; cnt++) /*move o ponteiro ate o final do label CDS_start=*/ pt++; while (*pt != ','){ /*enquanto nao for o final do numero*/ if (*pt == '\n'){ /*se nao achar o CDS_start*/ printf("ERRO!!sequencia de bases nao possui o valor do CDS_start"); fflush(stdout); exit(1); } str_cat(cds_start_aux,*pt); pt++; } *cds_start = atoi(cds_start_aux); /*transforma em numero*/ }//fim do if /* Para armazenar o valor da cds_end */ pt = strstr(inf,"CDS_end="); /*procura o label CDS_start em buffer*/ if (*pt == 'C'){ for (cnt=0;cnt<8;cnt++) /*move o ponteiro ate o final do label CDS_start=*/ pt++; while (*pt!= ','){ /*enquanto nao for o final do numero*/ if (*pt == '\n'){ /*se nao achar o CDS_start*/ printf("ERRO!!sequencia de bases nao possui o valor do CDS_end"); fflush(stdout); exit(1); } str_cat(cds_end_aux,*pt); pt++; }//fim while *cds_end = atoi(cds_end_aux); }//fim do if strstr /* Para armazenar o tamanho da cds */ pt = strstr(inf,"CDS_len="); /*procura o label CDS_start em inf*/ if (*pt == 'C'){ /*tenta testar se pt retornou mesmo o ponteiro para CDS_START*/ for (cnt = 0; cnt < 8; cnt++) /*move o ponteiro ate o final do label CDS_start=*/ pt++; while ((*pt != ' ')&&(*pt != '\n')){ str_cat(cds_len_aux,*pt); pt++; }//fim do while *cds_len = atoi(cds_len_aux); /*transforma em numero*/ }//fim do if *pt_seq = pt_seq_aux; }//fim do extrair cabecalho /************************************************************************* * Procedimento que percorre as sequencias de nucleotideos deslocando base* * a base e pegando as bases e seu respectivo rotulo. * *************************************************************************/ void extrair_dados(FILE **pt_entrada, char *nome_base, char *nome_rotulo){ /* Variaveis para o ler as bases do arquivo */ char letra_base ='\0'; /* caracter lido do arquivo de entrada com as bases */ char letra_rotulo ='\0'; /* caracter lido do arquivo de entrada com os rotulos*/ char gene_id[15]; /* Identificador do gene no Genbank */ int cds_start = 0; /* posicao do inicio da cds */ int cds_end = 0; /* posicao final da cds*/ int cds_len = 0; /* Tamanho da cds - valor retirado do cabeçalho */ int pos_cds = 0; /* Contador que indica a posição da base lida na cds */ int tam_exon = 0; /* Tamanho do exon que está sendo lido */ int ignora_gene = 0; /* Determina se o gene deve ser ignorado(1) ou computado(0)*/ int is_exon_utr = 0; /* exon de região UTR, o valor da variavel é 1*/ int splice_invalido = 0; /* determina se splice é invalido - possui EEE */ /* Número de colunas na linha corrente. */ int col_base = 0; int col_rotulo = 0; /* Contadores globais de simbolos na saída - Usados para contar quantos simbolos há na memoria */ int tot_base = 0; int tot_rotulo = 0; /* Variáveis para armazenar as bases e os rotulos */ FILE *pt_entrada_aux, *pt_rotulo, *pt_base; tno *prim_rotulo,*ult_rotulo, *prim_base, *ult_base; prim_rotulo = NULL; ult_rotulo = NULL; pt_rotulo = NULL; prim_base = NULL; ult_base = NULL; pt_base = NULL; pt_entrada_aux = *pt_entrada; fscanf(pt_entrada_aux, "%c", &letra_base); /*le uma letra do arquivo*/ while(!feof(pt_entrada_aux)){ if (letra_base == '\n'){ }else if (letra_base == '>'){ /* Encontrou o cabecalho com informacoes sobre a seqüência de DNA */ ignora_gene = 0; /* (*) indica que vai começar um novo gene, exceto no inicio do arquivo, quando o tam_exon foi iniciado com o valor 0 */ if (tam_exon != 0){ letra_base = '*'; guardar_elemento(letra_base, &prim_base, &ult_base); letra_rotulo = '*'; guardar_elemento(letra_rotulo, &prim_rotulo, &ult_rotulo); tot_base++; tot_rotulo++; }//fim do if pos_cds = 1; cds_start = 0; cds_end = 0; tam_exon = 0; /*tamanho do exon neste gene*/ extrair_cabecalho(&pt_entrada_aux, &splice_invalido, &cds_start, &cds_end, &cds_len, gene_id); /* O gene é ignorado se no splice encontrar o label "EEE" - suspeita de erro tipografico no gene */ if (splice_invalido){ ignora_gene = 1; splice_invalido = 0; } //fim do if /* Tamanho da cds deve ser multiplo de 3*/ if ((cds_len % 3)!= 0){ ignora_gene = 1; } cds_len = 0; }else if(ignora_gene == 1){ }else if((letra_base >= 'A') && (letra_base <= 'Z')){ /*se for exon*/ /* Testa se a base do exon esta dentro da regiao codificadora(cds)*/ if ((pos_cds >= cds_start) && (pos_cds <= cds_end)){ is_exon_utr = 0; /* Calcula o rotulo para a base*/ switch(tam_exon % 3){ case 0: letra_rotulo='E'; break; case 1: letra_rotulo='F'; break; case 2: letra_rotulo='G'; break; default: letra_rotulo='?'; // Impossível. } guardar_elemento(letra_base, &prim_base, &ult_base); guardar_elemento(letra_rotulo, &prim_rotulo, &ult_rotulo); tot_base++; tot_rotulo++; tam_exon++; }else if (is_exon_utr == 0){ /* É um exon da região UTR*/ is_exon_utr = 1; letra_base = '*'; guardar_elemento(letra_base, &prim_base, &ult_base); letra_rotulo = '*'; guardar_elemento(letra_rotulo, &prim_rotulo, &ult_rotulo); tot_base++; tot_rotulo++; }//fim do if pos_cds++; }else if ((letra_base >= 'a') && ((letra_base) <= 'z')){ /*se for intron*/ is_exon_utr = 0; guardar_elemento(letra_base, &prim_base, &ult_base); letra_rotulo = 'I'; guardar_elemento(letra_rotulo, &prim_rotulo, &ult_rotulo); tot_base++; tot_rotulo++; pos_cds++; }else if(letra_base == '.'){ /* Indica que há um intron não identificado na seqüência */ letra_base = '*'; guardar_elemento(letra_base, &prim_base, &ult_base); letra_rotulo = '*'; guardar_elemento(letra_rotulo, &prim_rotulo, &ult_rotulo); tot_base++; tot_rotulo++; }else { printf("Erro!caracter %c e' invalido!",letra_base); printf("gene=%s,cds_start=%d,cds_end=%d", gene_id, cds_start,cds_end); fflush(stdout); exit(1); } letra_base='\0'; letra_rotulo='\0'; liberar_memoria(&prim_base, &ult_base, &pt_base, nome_base, &tot_base, &col_base); liberar_memoria(&prim_rotulo, &ult_rotulo, &pt_rotulo, nome_rotulo, &tot_rotulo, &col_rotulo); fscanf(pt_entrada_aux, "%c", &letra_base); }//fim do while gravar_arq(&prim_base, nome_base, &pt_base, &col_base); desalocar_lista(&prim_base); gravar_arq(&prim_rotulo, nome_rotulo, &pt_rotulo, &col_rotulo); desalocar_lista(&prim_rotulo); *pt_entrada = pt_entrada_aux; fclose(*pt_entrada); if (pt_rotulo != NULL) fclose(pt_rotulo); if (pt_base != NULL) fclose(pt_base); }//fim do tratar_dados int main(int argc, char **argv){ char arq_entra[256]; char arq_base[256]; char arq_rotulo[256]; FILE *pt_entrada,*pt_entra; float tempoi_CPU, tempof_CPU; /*variaveis para pegar o tempo de CPU*/ /* para comecar a contar o tempo de execucao */ times(&tempoi); tempoCPU(tempoi, &tempoi_CPU); if (argc != 2){ printf("use: tratar_base .txt \n arq_entrada com uma lista dos nomes de arquivos contendo o DNA dos organismos \n"); return(1); }//fim do if abrir_arq(argv[1], &pt_entrada, "r"); /*abre o arquivo com os nomes dos arquivos com as sequencias*/ printf("\nExtraindo bases do arquivo fonte..."); fflush(stdout); fscanf(pt_entrada,"%s", arq_entra); while (!feof(pt_entrada)){ fscanf(pt_entrada,"%s", arq_base); fscanf(pt_entrada,"%s", arq_rotulo); abrir_arq(arq_entra, &pt_entra, "r");/*abre o arquivo com o DNA do organismo*/ printf("\nArquivo:%s",arq_entra); fflush(stdout); extrair_dados(&pt_entra, arq_base, arq_rotulo); fscanf(pt_entrada,"%s", arq_entra); }//fim do while fclose(pt_entrada); printf("\n ...Operacao Concluida com sucesso!"); /*para finalizar o tempo de execucao*/ times(&tempof); tempoCPU(tempof, &tempof_CPU); printf("\ntempo total de CPU: %.3f\n\n", ((tempof_CPU - tempoi_CPU)/60)); return(0); } //fim do main