/************************************************************************* * Ultima Modificacao: 26/04/2005 - Renatha Oliva Capua * * Last edited on 2005-05-26 18:16:48 by stolfi * * Last edited on 2005-08-03 22:48:15 by rcapua * * * * Universidade Federal Fluminense * * Mestrado em Computacao * * Aluna: Renatha Oliva Capua * * Orientadores: Helena Cristina da Gama Leitao * * Jorge Stolfi * * * * freq_tuplas.c - Programa recebe como entrada arquivos com sequencias * * de nucleotideos de DNA e seu respectivos rotulos e calculando a * * frequencias das tuplas em sequencias de exons e introns. O programa * * le por vez dois arquivos, um com os nucleotideos e outro com os rotulos* *************************************************************************/ #define PROG_NAME "freq_tuplas" #define PROG_USAGE \ PROG_NAME " \\\n" \ " TAM_TUPLA \\\n" \ " ARQ_NOME_SEQUENCIAS \\\n" \ " ARQ_SAIDA\\\n" \ " ARQ_NOME_SEQUENCIAS: ARQ_BASES_ORGANISMO_1 ARQ_ROTULO_ORGANISMO_1 \\\n" \ " ARQ_BASES_ORGANISMO_2 ARQ_ROTULO_ORGANISMO_2 ... \\\n" \ #include "freq_tuplas.h" #include int main(int argc, char **argv){ char arq_bases[256], arq_eventos[256]; FILE *pt_entrada; /* Arquivo com os nomes dos arquivos de bases e rotulos */ FILE *pt_bases; /* Arquivo com as bases de DNA */ FILE *pt_eventos; /* Arquivo com os rotulos das bases*/ tfreq *vfreq; /* Vetor para as frequencias das m-tuplas(tuplas) nas bases de treinamento */ tevento *vevento; /* Lista com os rotulos dos eventos validos */ float tempoi_CPU, tempof_CPU; /* Variaveis para pegar o tempo de CPU */ /* para começar a contar o tempo de execução */ times(&tempoi); tempoCPU(tempoi, &tempoi_CPU); /* para testar a quantidade de argumentos passados na chamada do programa */ if (argc != 4){ fprintf(stderr, "argc = %d\n", argc); fprintf(stderr, "use: %s\n", PROG_USAGE); return(-1); } int m = atoi(argv[1]); /* Tamanho das tuplas. */ int tam_vfreq = (int)pow(4,m); /* Tamanho do vetor de frequencias = 4^m */ /*Gera um vetor com todos os eventos validos */ gerar_vevento(&vevento, m); /*para criar uma estrutura para armazenar as frequencias das tuplas */ if (!(alocar_vfreq(&vfreq, tam_vfreq, m))) { fprintf(stderr, "ERRO ao alocar o vetor vfreq \n"); exit(-1); } fprintf(stderr, "\nCalculando frequencias... \n"); abrir_arq(argv[2], &pt_entrada, "r"); /*abre o arquivo com os nomes dos arquivos com as sequencias*/ /*Le os arquivos e calcula as frequencias*/ fscanf(pt_entrada,"%s", arq_bases); while (!feof(pt_entrada)){ fscanf(pt_entrada, "%s", arq_eventos); /* Abre os arquivos */ abrir_arq(arq_bases, &pt_bases, "r"); /* Arquivo com as bases de DNA*/ abrir_arq(arq_eventos, &pt_eventos, "r"); /* Arquivo com os eventos para as bases*/ fprintf(stderr, "Lendo arquivo %s e %s\n", arq_bases, arq_eventos); /* Soma as frequencias do arquivo lido */ calcula_freq(&vfreq, &pt_bases, &pt_eventos, m); /* Fecha os arquivos */ fclose(pt_bases); fclose(pt_eventos); fscanf(pt_entrada,"%s", arq_bases); }//fim do while gravar_saida(vfreq, tam_vfreq, vevento, argv[3], m); /* Desalocar a estrutura com as frequencias das tuplas*/ desalocar_vfreq(&vfreq, tam_vfreq); fclose(pt_entrada); fprintf(stderr, "...Operacao Concluida com sucesso!\n"); /*para finalizar o tempo de execucao*/ times(&tempof); tempoCPU(tempof, &tempof_CPU); fprintf(stderr, "tempo total de CPU: %.3f\n\n", ((tempof_CPU - tempoi_CPU)/60)); return(0); } //fim do main /**************************************************************************** * Procedimento para criar o vetor que vai guardar as frequencias de m-tuplas* * tam_vfreq -> tamanho maximo do vetor, m-> tamanho da tupla * ****************************************************************************/ int alocar_vfreq(tfreq **vfreq, int tam_vfreq, int m){ int cnt, cnt_prob; tfreq *vfreq_aux; // vfreq_aux = *vfreq; /* Aloca espaço para os eventos */ vfreq_aux = (tfreq *) malloc(tam_vfreq * sizeof(tfreq)); /* Testa se alocação foi bem sucedida */ if (vfreq_aux == NULL){ fprintf(stderr, "Erro na alocacao de memoria,vfreq nao pode ser criado!\n"); return(0); }//fim do if /* Inicializa variaveis e aloca espaço para os rotulos das tuplas e suas frequencias */ for(cnt = 0; cnt < tam_vfreq; cnt++){ vfreq_aux[cnt].evento = (char *) malloc((m + 1) * sizeof(char)); /* rotulo do evento */ strcpy(vfreq_aux[cnt].evento, "\0"); vfreq_aux[cnt].prob = (tprob *) malloc (tam_vfreq * sizeof(tprob)); /* tuplas e suas probabilidades */ for (cnt_prob = 0; cnt_prob < tam_vfreq; cnt_prob++){ vfreq_aux[cnt].prob[cnt_prob].tupla = (char *) malloc((m + 1) * sizeof(char)); /* tupla */ strcpy(vfreq_aux[cnt].prob[cnt_prob].tupla, "\0"); vfreq_aux[cnt].prob[cnt_prob].valor = 0; } }//fim do for i< vfreq_tam *vfreq = vfreq_aux; return(1); }//fim do alocar_vfreq /************************************************************************* * Procedimento que retorna a tupla referente ao indice em vfreq * *************************************************************************/ char *retorna_tupla(int indice, int m){ int num = 0, resto = 0; int cnt = 0; char *tupla; tupla = (char *)malloc ((m+1) * sizeof(char)); strcpy(tupla,"\0"); num = indice; for(cnt = 0; cnt <= m - 1; cnt++){ resto = num % 4; switch(resto){ case 0: str_ncat_ini(tupla, 'A', m); break; /*concatena a letra na ultima posicao da tupla*/ case 1: str_ncat_ini(tupla, 'T', m); break; /*concatena a letra na ultima posicao da tupla*/ case 2: str_ncat_ini(tupla, 'C', m); break; /*concatena a letra na ultima posicao da tupla*/ case 3: str_ncat_ini(tupla, 'G', m); break; /*concatena a letra na ultima posicao da tupla*/ }//fim do switch num = num/4 ; }//fim do while return(tupla); }//fim do retorna_tupla /************************************************************************* * Procedimento que retorna o evento referente ao indice em vfreq * *************************************************************************/ char *retorna_evento(int indice, int m){ int num = 0, resto = 0; int cnt = 0; char *evento; evento = (char *) malloc ((m+1) * sizeof(char)); strcpy(evento,"\0"); num = indice; for(cnt = 0; cnt <= m - 1; cnt++){ resto = num % 4; switch(resto){ case 0: str_ncat_ini(evento, 'I', m); break; /*concatena a letra na ultima posicao da tupla*/ case 1: str_ncat_ini(evento, 'E', m); break; /*concatena a letra na ultima posicao da tupla*/ case 2: str_ncat_ini(evento, 'F', m); break; /*concatena a letra na ultima posicao da tupla*/ case 3: str_ncat_ini(evento, 'G', m); break; /*concatena a letra na ultima posicao da tupla*/ }//fim do switch num = num/4 ; }//fim do while return(evento); }//fim do retorna_evento /************************************************************************* * Procedimento que retorna o indice da posicao de tupla em vfreq * *************************************************************************/ int retorna_indice_tupla(char *elemento, int m){ int indice = 0, pos = m - 1; while (*elemento != '\0'){ switch(*elemento){ case 'A': indice = indice + (((int)pow(4,pos)) * 0); break; case 'T': indice = indice + (((int)pow(4,pos)) * 1); break; case 'C': indice = indice + (((int)pow(4,pos)) * 2); break; case 'G': indice = indice + (((int)pow(4,pos)) * 3); break; default: printf("ERRO!!! elemento: %c da tupla nao encontrado",*elemento); fflush(stdout); exit(1); }//fim do switch elemento++; pos--; }//fim do while return(indice); }//fim do indice_tupla /************************************************************************* * Procedimento que retorna o indice da posicao do evento em vfreq * *************************************************************************/ int retorna_indice_evento(char *elemento, int m){ int indice = 0, pos = m - 1; while (*elemento != '\0'){ switch(*elemento){ case 'I': indice = indice + (((int)pow(4,pos)) * 0); break; case 'E': indice = indice + (((int)pow(4,pos)) * 1); break; case 'F': indice = indice + (((int)pow(4,pos)) * 2); break; case 'G': indice = indice + (((int)pow(4,pos)) * 3); break; default: printf("ERRO!!! elemento:%c do evento nao encontrado\n",*elemento); fflush(stdout); exit(1); }//fim do switch elemento++; pos--; }//fim do for return(indice); }//fim do indice_evento /************************************************************************* * Procedimento que incrementa em vfreq a frequencia da tupla passada como* * parametro. * * vfreq -> vetor com as frequencias das tuplas * * m-> tamanho da tupla * *************************************************************************/ void guardar_freq(tfreq **vfreq, char *tupla, char *evento, int m){ int pos_tupla = 0; /* Posição que a tupla deve ser inserida em vfreq*/ int pos_evento = 0; /* Posição que o evento deve ser inserido em vfreq*/ tfreq *vfreq_aux; vfreq_aux = *vfreq; /* Retorna as posições do vetor onde a tupla e o rotulo do evento devem ser inseridos */ pos_tupla = retorna_indice_tupla(tupla, m); pos_evento = retorna_indice_evento(evento, m); /* Pesquisa para ver se evento está cadastrado. */ if ((strcmp(vfreq_aux[pos_evento].evento,"\0")) != 0){ /* evento ja' cadastrado */ if (strcmp(vfreq_aux[pos_evento].prob[pos_tupla].tupla, "\0") == 0) /* tupla cadastrada */ strcpy(vfreq_aux[pos_evento].prob[pos_tupla].tupla, tupla); }else{/* evento nao cadastrada */ strcpy(vfreq_aux[pos_evento].evento, evento); strcpy(vfreq_aux[pos_evento].prob[pos_tupla].tupla, tupla); }//fim do if tupla vfreq_aux[pos_evento].prob[pos_tupla].valor = vfreq_aux[pos_evento].prob[pos_tupla].valor + 1; *vfreq = vfreq_aux; }//fim do guardar_freq /************************************************************************* * Procedimento que percorre as sequencias de nucleotideos deslocando a * * janela base a base e pegando as tuplas de tamanho m no arquivo pt_bases* * e seu respectivo rotulo do evento no arquivo pt_eventos. * * * * vfreq -> vetor que guarda as frequencias das tuplas * * pt_bases -> arquivo com as bases, pt_eventos -> arquivo com os eventos * * m -> tamanho da tupla * *************************************************************************/ void calcula_freq(tfreq **vfreq, FILE **pt_bases, FILE **pt_eventos, int m){ char *tupla, *evento; FILE *pt_bases_aux, *pt_eventos_aux; char letra_tupla = ' '; char letra_evento = ' '; tupla = (char*)malloc((m + 1) * sizeof(char)); evento = (char*)malloc((m + 1) * sizeof(char)); strcpy(tupla,"\0"); strcpy(evento,"\0"); pt_bases_aux = *pt_bases; pt_eventos_aux = *pt_eventos; /* Lê uma base e o rotulo do seu evento */ //fscanf(pt_bases_aux, "%c", &letra_tupla); //fscanf(pt_eventos_aux, "%c", &letra_evento); fscanf(pt_bases_aux, "%c", &letra_tupla); consumir_cabecalho(&pt_bases_aux, &letra_tupla); fscanf(pt_eventos_aux, "%c", &letra_evento); consumir_cabecalho(&pt_eventos_aux, &letra_evento); //fprintf(stderr, "letra_tupla: %c, letra_evento: %c\n", letra_tupla,letra_evento); while((!feof(pt_bases_aux))&&(!feof(pt_eventos_aux))){ if (letra_tupla == '\n'){ fscanf(pt_bases_aux, "%c", &letra_tupla); }else if (letra_evento == '\n'){ fscanf(pt_eventos_aux, "%c", &letra_evento); }else{ if( ((letra_tupla < 'A')||(letra_tupla > 'Z'))&& ((letra_tupla < 'a') ||((letra_tupla) > 'z'))&& (letra_tupla != '*') && (letra_tupla != '?') ){ fprintf(stderr, "Erro! base %c e' invalido!\n", letra_tupla); exit(1); } if( (letra_evento != 'I') && (letra_evento != 'E') && (letra_evento != 'F') && (letra_evento != 'G') && (letra_evento != '*') && (letra_evento != '?') ){ fprintf(stderr, "Erro! rotulo %c e' invalido!\n", letra_evento); exit(1); } str_ncat(tupla, letra_tupla, m); /*concatena a letra na ultima posicao da tupla*/ str_ncat(evento, letra_evento, m); assert(strlen(tupla) == strlen(evento)); /* Incrementa a frequencia da tupla em vfreq */ if ( (strlen(tupla) == m)&& (strchr(tupla,'*')==NULL) && (strchr(tupla,'?')==NULL) && (caracter_valido(tupla)== 0) && (strchr(evento,'*')==NULL) && (strchr(evento,'?')==NULL) ) guardar_freq(vfreq, tupla, evento, m); letra_tupla = ' '; letra_evento = ' '; fscanf(pt_bases_aux, "%c", &letra_tupla); fscanf(pt_eventos_aux, "%c", &letra_evento); } }//fim do while *pt_bases = pt_bases_aux; *pt_eventos = pt_eventos_aux; free(tupla); free(evento); }//fim do calcula_freq /************************************************************************* * Se o evento correspondente ao indice passado como parâmetro for um * * evento valido, ou seja, se o evento pertencer a lista de eventos * * válidos, seu rotulo é retornado, caso contrario é retornado "\0" * *************************************************************************/ char *evento_valido(tevento *vevento, int indice, int m){ char *evento; tevento *prim; evento = (char *) malloc (m * sizeof(char)); strcpy(evento, retorna_evento(indice, m)); prim = vevento; while (prim != NULL){ if (strcmp(prim->evento, evento) == 0) { return (evento); } else { prim = prim->prox;} }//fim do while return ("\0"); }//fim de evento_valido /************************************************************************* * Procedimento para gravar os dados da fila de frequencias em um arquivo.* * vevento -> vetor com os eventos validos m->tamanho da tupla * *************************************************************************/ void gravar_saida(tfreq *vfreq, int tam_vfreq, tevento *vevento, char *nome_saida, int m){ int cnt = 0; int cnt_prob = 0; FILE *pt_saida; char *evento; abrir_arq(nome_saida, &pt_saida, "w+"); /*abre o arquivo de saida*/ fprintf(pt_saida,">Arquivo com as frequencias de ocorrencia das k-tuplas em sequencias de DNA\n"); evento = (char *) malloc (m * sizeof(char)); for(cnt = 0; cnt < tam_vfreq; cnt++){ if (strcmp(vfreq[cnt].evento, "\0") != 0){ long int vtot = 0; /* Soma de todas as frequencias de um evento*/ /* Soma o valor da frequencia de todas as tuplas para um determinado evento */ for(cnt_prob = 0; cnt_prob < tam_vfreq; cnt_prob++){ if (strcmp(vfreq[cnt].prob[cnt_prob].tupla, "\0") != 0){ vtot += vfreq[cnt].prob[cnt_prob].valor; }//fim do if evento } for(cnt_prob = 0; cnt_prob < tam_vfreq; cnt_prob++){ if (strcmp(vfreq[cnt].prob[cnt_prob].tupla, "\0") != 0){ double freq = ((double)vfreq[cnt].prob[cnt_prob].valor + 1)/(vtot + tam_vfreq); fprintf(pt_saida,"%s", vfreq[cnt].evento); fprintf(pt_saida," %s", vfreq[cnt].prob[cnt_prob].tupla); fprintf(pt_saida," %10li", vfreq[cnt].prob[cnt_prob].valor); //----------------------------------------- //fprintf(pt_saida," vtot: %10li", vtot); //fprintf(pt_saida," tam_vfreq: %d", tam_vfreq); //------------------------------------------- fprintf(pt_saida," %12.10f\n",freq); }else{ double freq = ((double)vfreq[cnt].prob[cnt_prob].valor + 1)/(vtot + tam_vfreq); fprintf(pt_saida,"%s", vfreq[cnt].evento); fprintf(pt_saida," %s", retorna_tupla(cnt_prob, m)); fprintf(pt_saida," %10li", vfreq[cnt].prob[cnt_prob].valor); //----------------------------------------- //fprintf(pt_saida," vtot: %10li", vtot); //fprintf(pt_saida," tam_vfreq: %d", tam_vfreq); //------------------------------------------- fprintf(pt_saida," %12.10f\n", freq); }//fim do if evento }//fim do for }else{ /* Caso o evento não tenha aparecido nenhuma vez */ strcpy(evento, evento_valido(vevento, cnt, m)); if (strcmp(evento, "\0") != 0){ /* Se o evento for igual a \0 ele é um evento não considerado */ for(cnt_prob = 0; cnt_prob < tam_vfreq; cnt_prob++){ double freq = ((double)vfreq[cnt].prob[cnt_prob].valor + 1) / (tam_vfreq); fprintf(pt_saida,"%s", evento); fprintf(pt_saida," %s", retorna_tupla(cnt_prob, m)); fprintf(pt_saida," %10li", vfreq[cnt].prob[cnt_prob].valor); fprintf(pt_saida," %12.10f\n", freq); }//fim do for }//fim do if evento_valido }//fim do if }//fim do for fclose(pt_saida); }//fim do gravar_sol /************************************************************************* * Procedimento que gera uma lista com os eventos considerados validos * * vevento-> vetor com os eventos, m -> tamanho da sequencia de eventos * *************************************************************************/ void gerar_vevento(tevento **vevento, int m){ int cnt = 0; int ph = 0; int pos = 0; char *evento, *evento_ci, *evento_ic; char *pedaco; tevento *prim = NULL; tevento *ult = NULL; tevento *novo; evento = (char *) malloc (m * sizeof(char)); evento_ci = (char *) malloc (m * sizeof(char)); evento_ic = (char *) malloc (m * sizeof(char)); pedaco = (char *) malloc (2 * sizeof(char)); strcpy(evento,"\0"); strcpy(pedaco,"\0"); /* Gera os eventos com I puro */ for(cnt = 0; cnt < m; cnt++){ str_ncat(evento, 'I', m); } novo = (tevento *) malloc (sizeof(tevento)); novo->evento = (char*) malloc (m * sizeof(char)); novo->prox = NULL; strcpy(novo->evento, evento); prim = novo; ult = novo; /* Gera eventos com EFG e I */ strcpy(evento,"\0"); for(ph = 0; ph < 3; ph++){ /* Gera eventos com EFG puro */ for(cnt = 0; cnt < m; cnt++){ pos = ((ph + cnt) % 3); str_incpy("EFG", pedaco, pos, 1); str_cat(evento, *pedaco); strcpy(pedaco, "\0"); }//fim do for novo = (tevento *) malloc (sizeof(tevento)); novo->evento = (char*) malloc (m * sizeof(char)); strcpy(novo->evento,evento); novo->prox = NULL; ult->prox = novo; ult = novo; /* Gera eventos com I e EFG */ strcpy(evento_ci, evento); strcpy(evento_ic, evento); for(cnt = 0; cnt < (m - 1); cnt++){ /* I depois */ str_ncat(evento_ci,'I', m); novo = (tevento *) malloc (sizeof(tevento)); novo->evento = (char*) malloc (m * sizeof(char)); strcpy(novo->evento,evento_ci); novo->prox = NULL; ult->prox = novo; ult = novo; /* I antes */ str_ncat_ini(evento_ic,'I', m); novo = (tevento *) malloc (sizeof(tevento)); novo->evento = (char*) malloc (m * sizeof(char)); strcpy(novo->evento,evento_ic); novo->prox = NULL; ult->prox = novo; ult = novo; }//fim do for strcpy(evento, "\0"); strcpy(evento_ci, "\0"); strcpy(evento_ic, "\0"); }//fim do for *vevento = prim; free(evento); free(evento_ci); free(evento_ic); }//fim do evento_valido /************************************************************************* * Procedimento desalocar a fila criada. * *************************************************************************/ void desalocar_vfreq(tfreq **vfreq, int tam_vfreq){ int cnt, cnt_prob; tfreq *vfreq_aux; vfreq_aux = *vfreq; for (cnt=0; cnt < tam_vfreq;cnt++){ for (cnt_prob=0; cnt_prob < tam_vfreq; cnt_prob++) free(vfreq_aux[cnt].prob[cnt_prob].tupla); free(vfreq_aux[cnt].prob); free(vfreq_aux[cnt].evento); }//fim do for *vfreq = vfreq_aux; free(vfreq_aux); }//fim do desalocar_fila