Tema 8 · Processament de seqüències
Introducció
El processament de seqüències d'ADN i proteïnes és una tasca fonamental en bioinformàtica. Aprendrem a calcular el percentatge GC (contingut de guanina i citosina), analitzar freqüències de nucleòtids i identificar ORFs (Open Reading Frames, marcs oberts de lectura) que poden correspondre a gens.
Objectius
- Calcular el percentatge GC d'una seqüència d'ADN
- Determinar la freqüència de cada nucleòtid (A, C, G, T)
- Identificar codons d'inici (ATG) i de parada (TAA, TAG, TGA)
- Extreure ORFs i traduir-los a seqüència d'aminoàcids
Percentatge GC i freqüències
Funció per calcular el percentatge GC i les freqüències de cada base:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void analitzar_sequencia(char adn[]) {
int i, len = strlen(adn);
int a = 0, c = 0, g = 0, t = 0;
for (i = 0; i < len; i++) {
char base = toupper(adn[i]);
switch (base) {
case 'A': a++; break;
case 'C': c++; break;
case 'G': g++; break;
case 'T': t++; break;
}
}
int total_bases = a + c + g + t;
float gc = total_bases > 0 ? 100.0 * (g + c) / total_bases : 0;
printf("Total bases vàlides: %d\n", total_bases);
printf("A: %d (%.1f%%)\n", a, 100.0 * a / total_bases);
printf("C: %d (%.1f%%)\n", c, 100.0 * c / total_bases);
printf("G: %d (%.1f%%)\n", g, 100.0 * g / total_bases);
printf("T: %d (%.1f%%)\n", t, 100.0 * t / total_bases);
printf("Contingut GC: %.1f%%\n", gc);
}
int main() {
char adn[] = "AGCTTAGGCTAGCTAGC";
analitzar_sequencia(adn);
return 0;
}
toupper() converteix a majúscules per evitar errors
Identificació d'ORFs
Un ORF comença amb un codó d'inici ATG i acaba amb un codó de parada (TAA, TAG o TGA). La seqüència entre ells, de longitud múltiple de 3, es pot traduir a aminoàcids.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// Busca el següent ORF a partir d'una posició donada
// Retorna la posició final o -1 si no en troba
int trobar_orf(char adn[], int inici, char orf[], int *longitud) {
int len = strlen(adn);
int i = inici;
// Buscar codó d'inici ATG
while (i < len - 2) {
if (toupper(adn[i]) == 'A' &&
toupper(adn[i+1]) == 'T' &&
toupper(adn[i+2]) == 'G') {
break;
}
i++;
}
if (i >= len - 2) return -1; // No hi ha més ATG
int inici_orf = i;
int j = 0;
// Copiar codons fins a trobar un codó de parada
while (i < len - 2) {
char c1 = toupper(adn[i]);
char c2 = toupper(adn[i+1]);
char c3 = toupper(adn[i+2]);
// Comprovar si és codó de parada
if ((c1 == 'T' && c2 == 'A' && c3 == 'A') ||
(c1 == 'T' && c2 == 'A' && c3 == 'G') ||
(c1 == 'T' && c2 == 'G' && c3 == 'A')) {
break;
}
// Copiar el codó
orf[j++] = adn[i];
orf[j++] = adn[i+1];
orf[j++] = adn[i+2];
i += 3;
}
orf[j] = '\0';
*longitud = j / 3; // Nombre d'aminoàcids
return i; // Posició final
}
int main() {
char adn[] = "XXATGGCCTAATAG";
char orf[1000];
int long_aa, pos = 0;
while ((pos = trobar_orf(adn, pos, orf, &long_aa)) != -1) {
printf("ORF trobat: %s (%d aa)\n", orf, long_aa);
pos++; // Avançar per buscar més ORFs
}
return 0;
}
Traducció d'ADN a proteïna
Un cop tenim la seqüència d'ADN d'un ORF, podem traduir cada codó (3 bases) a un aminoàcid segons el codi genètic estàndard.
char traduir_codo(char *codo) {
// Versió simplificada: només alguns aminoàcids
if (strncmp(codo, "ATG", 3) == 0) return 'M'; // Metionina
if (strncmp(codo, "TGG", 3) == 0) return 'W'; // Triptòfan
if (strncmp(codo, "TTT", 3) == 0 || strncmp(codo, "TTC", 3) == 0) return 'F'; // Fenilalanina
if (strncmp(codo, "TTA", 3) == 0 || strncmp(codo, "TTG", 3) == 0 ||
strncmp(codo, "CTT", 3) == 0 || strncmp(codo, "CTC", 3) == 0 ||
strncmp(codo, "CTA", 3) == 0 || strncmp(codo, "CTG", 3) == 0) return 'L'; // Leucina
if (strncmp(codo, "TAA", 3) == 0 || strncmp(codo, "TAG", 3) == 0 ||
strncmp(codo, "TGA", 3) == 0) return '*'; // STOP
return 'X'; // Desconegut
}
void traduir_orf(char orf_adn[], char proteina[]) {
int i, j = 0;
for (i = 0; i < strlen(orf_adn); i += 3) {
char codo[4];
strncpy(codo, &orf_adn[i], 3);
codo[3] = '\0';
proteina[j++] = traduir_codo(codo);
}
proteina[j] = '\0';
}
Exercicis
- Escriu un programa que demani una seqüència d'ADN i mostri el percentatge GC i la freqüència de cada base.
- Identifica tots els codons ATG en una seqüència i mostra les posicions on apareixen.
- Amplia la taula de traducció per incloure almenys 10 aminoàcids diferents.
Mini Projecte – Analitzador de seqüències
Escriu un programa complet que:
- Llegeixi una seqüència d'ADN des d'un fitxer (pot contenir diverses línies).
- Calculi i mostri el percentatge GC i les freqüències de cada nucleòtid.
- Identifiqui tots els ORFs en els tres marcs de lectura (començant a posició 0, 1 i 2).
- Per a cada ORF trobat, mostri la seva longitud en aminoàcids i la seqüència proteica traduïda (encara que sigui parcial).
- Desi els resultats en un fitxer de text amb un resum ordenat per longitud d'ORF (el més llarg primer).
Pista: utilitza funcions separades per a cada tasca i estructura les dades en structs si cal.