original in es Carlos Andrés Pérez
en to es Carlos Andrés Pérez
en to de Viktor Horvath
Carlos Andrés Pérez ist Spezialist f�r Molekularsimulation und Doktorand der Biotechnologie. Technischer Berater der Grupo de Investigación en Educación Virtual (GIEV) [Forschungsgruppe f�r e-Learning]. Adresse: Universidad Santiago de Cali, Calle 5ª carrera 62 Campus Pampalinda, Cali – Colombia.
Dieser Artikel will einige der Vorteile zeigen, die Perl-Programmierung unter Unix f�r die Auswertung biologischer DNS-, RNS- und Proteinsequenz-Datenbanken bietet, in Vergleichsprozessen oder Analyse. Das Humangenomprojekt und die DNS-Klontechniken haben den Fortschritt der Wissenschaft auf diesem Gebiet beschleunigt. Die t�glich generierten Daten �bersteigen h�ufig die Kapazit�ten, sie unter dem Gesichtspunkt der Evolution zu verarbeiten.
Die schnelle Vermehrung der biologischen Informationen zu verschiedenen Genomen (Summen der Gene eines Organismus) treibt die Bioinformatik als eine fundamentale Disziplin f�r die Handhabung und Analyse dieser Daten an.
Die Bioinformatik entstand, als Wissenschaftler Gensequenzen digital zu speichern und mittels Programmen zu vergleichen begannen. Lange war Bioinformatik auf die Sequenzanalyse beschr�nkt. Die Wichtigkeit, die Molek�lstruktur festzustellen, sorgte jedoch daf�r, da� Computer zu einem wichtigen Werkzeug f�r Untersuchungen in theoretischer Biochemie wurden. T�glich gibt es mehr Informationen und mehr Datensammlungen zur dreidimensionalen Molek�lstruktur. Gene werden nicht mehr einzeln, sondern im Ganzen oder in einem gr��eren Teil untersucht. Es ist jetzt einfacher zu verstehen, wie sie sich untereinander und in bezug auf die Proteine verhalten und wie sie sich in Stoffwechselwegen organisieren. Jedes Mal werden wir uns mehr dar�ber bewu�t, wie wichtig es ist, die Daten zu organisieren.
Jede der beschriebenen Aktivit�ten hat mindestens zwei Gesichtspunkte, unter denen sie interessant ist. Einerseits ist es das biologische Interesse, die Beziehungen zwischen organischen Molek�len zu kennen, und andererseits ger�t der Zusammenbau zu einem interessanten Problem des Softwaredesign. Biologische Informationen m�ssen kombiniert und integriert werden, um eine globale und effektive Sicht der zugrundeliegenden biologischen Prozesse zu erhalten. Wir haben selber die Notwendigkeit bemerkt, f�r eine wirksame L�sung die verschiedenen Felder der Informatik zusammenzuf�hren: Datenbankverwaltung, auch Datenintegration, effiziente Algorithmen, leistungsf�hige Hardware - Parallelrechner, Multiprozessorsysteme etc.
Larry Wall begann die Entwicklung von Perl 1986. Perl ist eine interpretierte Programmiersprache, ideal zur Handhabung von Text, Dateien und Prozessen. Perl erlaubt die schnelle Entwicklung kleiner Programme. Man k�nnte sagen, da� Perl eine optimierte Mischung einer Hochsprache (z.B. C) und einer Skriptsprache (z.B. bash) ist.
Perl-Programme k�nnen unter verschiedenen Betriebssystemen oder Plattformen laufen. Es ist jedoch unter den UNIX-Systemen entstanden und hat sich dort verbreitet. Perl hat seinen anf�nglichen Bereich endg�ltig verlassen, seit es als Sprache f�r Web-Applikationen eingesetzt wird. Vor Perl waren awk, thirst und grep die Werkzeuge zur Dateianalyse und der Extraktion von Informationen.
Perl vereinigte die F�higkeiten dieser UNIX-Werkzeuge in einem einzigen Programm, wobei jedes mit mehr Funktionalit�t erweitert und modernisiert wurde.
Perl ist eine freie Programmiersprache, und es l�uft auf jedem Betriebssystem, das in biologischen Forschungslaboren g�ngig ist. Unter UNIX und Mac OS X ist es schon vorinstalliert, ansonsten mu� man es installieren. Es gen�gt, die passende Version von dieser Seite zu laden: http://www.cpan.org
Unter Linux wird Perl mit der Datei als Argument aufgerufen, die die auszuf�hrenden Befehle enth�lt. Eine andere, h�ufig verwendete Methode gestattet es, direkt diese Datei aufzurufen. Daf�r m�ssen wir zweierlei machen: (a) einen besonderen Kommentar als erste Zeile in das Programm schreiben:
#!/usr/bin/env perl
print "Hi\n";
und (b) die Datei unter Unix ausf�hrbar machen:
% chmod +x greetings.pl
Dann k�nnen wir die Programmdatei einfach unter ihrem Namen aufrufen.
Wenn wir eine Datenbank von Molekularsequenzen in Textformat haben, k�nnen wir mit Perl eine Sequenz-Suchmaschine schreiben. Dieses Beispiel zeigt, wie man nach einer Proteinsequenz in einer Datenbank im Format SWISS-PROT (db_human_swissprot) durch Angabe ihrer ID sucht.
#!/usr/bin/perl
# Suche nach einer Aminos�ure-Sequenz in einer Datenbank # im Format SWISS-PROT, mit einem gegebenen ID-Code. # Frage nach dem ID-Code und speichere ihn # von der Eingabe (stdin) in eine Variable
print "Enter the ID to search: "; $id_query=<STDIN>; chomp $id_query;
# Wir �ffnen die Datenbank-Datei. # Wenn das unm�glich ist, endet das Programm
open (db, "human_kinases_swissprot.txt") || die "problem opening the file human_kinases_swissprot.txt\n";
# Suche Zeile f�r Zeile in der Datenbank
while (<db>) { chomp $_;
# Pr�fe, ob wir in einem ID-Feld sind
if ($_ =~ /^ID/) {
# Wenn ja, sammeln wir die Information # und trennen die Zeile bei den Leerzeichen
($a1,$id_db) = split (/\s+/,$_);
# Wenn das ID-Feld nicht das gesuchte ist, # gehen wir zum n�chsten
next if ($id_db ne $id_query);
# Wenn wir darauf sto�en, setzen wir eine Marke
$signal_good=1;
# Dann pr�fen wir, ob es sich um das Sequenz-Feld handelt # und ob die Marke 1 ist (gesuchte Sequenz) # Wenn ja, �ndern wir die Marke auf 2, um die Sequenz zu sammeln
} elsif (($_ =~ /^SQ/) && ($signal_good==1)) { $signal_good=2;
# Wenn die Marke schlie�lich 2 ist, zeigen wir jede Zeile # der Sequenz an, au�er wenn die Zeile mit // beginnt # In dem Fall verlassen wir die while-Schleife
} elsif ($signal_good == 2) { last if ($_ =~ /^\/\//); print "$_\n"; } }
# Wenn wir die while-Schleife verlassen haben, pr�fen wir die Marke. # Ist der Test negativ, hei�t das, da� wir die gesuchte Sequenz # nicht gefunden haben und wir einen Fehler ausgeben.
if (!$signal_good) { print "ERROR: "."Sequence not found\n"; }
# Als letztes schlie�en wir die noch offene Datei
close (db); exit;
#!/usr/bin/perl # Suchmaschine f�r Aminos�ure-Muster # Frage den Nutzer nach den zu suchenden Mustern
print "Please, introduce the pattern to search in query.seq: "; $patron = <STDIN>; chomp $patron;
# Wir �ffnen die Datenbank-Datei. # Wenn das unm�glich ist, endet das Programm
open (query, "query_seq.txt") || die "problem opening the file query_seq.txt\n";
# Suche Zeile f�r Zeile nach der SWISS-PROT-Sequenz
while (<query>) { chomp $_;
# Wenn wir beim SQ-Feld ankommen, Marke auf 1 setzen
if ($_ =~ /^SQ/) { $signal_seq = 1;
# Wenn wir am Ende der Sequenz ankommen, verlasse die Schleife. # Dieser Ausdruck mu� vor dem Test, ob die Marke 1 ist, stehen, # denn diese Zeile geh�rt nicht zur Aminos�ure-Sequenz.
} elsif ($_ =~ /^\/\//) { last;
# Teste, ob die Marke 1 ist. Wenn ja, l�sche die Leerzeichen # in der Sequenzzeile und vereinige jede Zeile in einer neuen Variable. # Zum Zusammenf�gen k�nnen wir auch folgendes machen: # $secuencia_total.=$_;
} elsif ($signal_seq == 1) { $_ =~ s/ //g; $secuencia_total=$secuencia_total.$_; } }
# Jetzt vergleiche die komplett zusammengef�gte Sequenz # mit dem gesuchten Muster
if ($secuencia_total =~ /$patron/) { print "The sequence query.seq contains the pattern $patron\n"; } else { print "The sequence query.seq doesn't contain the pattern $patron\n"; }
# Als letztes schlie�en wir die noch offene Datei
close (query); exit;
Falls wir die genaue Fundstelle des Musters erfahren wollen, m�ssen wir eine bestimmte Variable $& benutzen. Sie beh�lt das gefundene Muster nach der Auswertung eines regul�ren Ausdrucks (man m��te sie direkt nach die Zeile if ($$secuencia_total>= ~/$$patron>/) { schreiben. Das k�nnen wir mit den Variablen $ ` und $ ´ verbinden, die alles links und rechts vom gefundenen Muster speichern. Hier die Modifikation des vorigen Programms mit diesen neuen Variablen, um die genaue Position des Musters anzugeben. Hinweis: Auch die Funktion length kann n�tzlich sein, die die L�nge einer Zeichenkette liefert.
# Wir m�ssen nur das "if" da �ndern, wo das Muster gefunden wurde. # Jetzt vergleiche die komplett zusammengef�gte Sequenz # mit dem gesuchten Muster und pr�fe dessen Position in der Sequenz
if ($secuencia_total =~ /$patron/) { $posicion=length($`)+1; print "The sequence query_seq.txt contains the pattern $patron in the following position $posicion\n"; } else { print "The sequence query_seq.txt doesn't contain the pattern $patron\n"; }
Die H�ufigkeiten der einzelnen Aminos�uren in einem Protein ist unterschiedlich, je nach seiner Funktion oder bevorzugten Umgebung. Daher sehen wir in diesem Beispiel, wie man die H�ufigkeiten der Aminos�uren in einer gegebenen Aminos�uren-Sequenz berechnet.
#!/usr/bin/perl # Berechnet die H�ufigkeiten der Aminos�uren in einer Proteinsequenz # Erh�lt den Dateinamen von der Kommandozeile (Format SWISS-PROT) # Kann auch mit "print" von <stdin> erfragt werden
if (!$ARGV[0]) {print "The execution line shall be: program.pl file_swissprot\n";} $fichero = $ARGV[0];
# Initialisiere die Variable $errores
my $errores=0;
# �ffne die Datei zum Lesen
open (FICHA, "$fichero") || die "problem opening the file $fichero\n";
# Zuerst �berpr�fen wir die Sequenz wie im zweiten Beispiel
while (<FICHA>) { chomp $_; if ($_ =~ /^SQ/) { $signal_good = 1; } elsif ($signal_good == 1) { last if ($_ =~ /^\/\//); $_ =~ s/\s//g; $secuencia.=$_; } } close (FICHA);
# Jetzt verwenden wir eine Schleife, die jede Position einer Aminos�ure # in der Sequenz testet (in einer eigenen Funktion, die sp�ter in anderen # Programmen benutzt werden kann)
comprueba_aa ($secuencia);
# Gib die Ergebnisse auf dem Schirm aus # Zuerst die 20 Aminos�uren und dann das Array mit ihren H�ufigkeiten # In diesem Fall kann "sort" nicht in "foreach" benutzt werden, # denn das Array enth�lt die H�ufigkeiten als Zahlen.
print"A\tC\tD\tE\tF\tG\tH\tI\tK\tL\tM\tN\tP\tQ\tR\tS\tT\tV\tW\tY\n"; foreach $each_aa (@aa) { print "$each_aa\t"; }
# Dann gibt das Programm m�gliche Fehler zur�ck und terminiert
print "\nerrores = $errores\n"; exit;
# Funktionen: # Diese berechnet die H�ufigkeit # einer jeden Aminos�ure einer Proteinsequenz
sub comprueba_aa {
# Sequenz nehmen
my ($secuencia)=@_;
# und jede Aminos�ure ansehen, a l�uft von 0 bis zur Sequenzl�nge
for ($posicion=0 ; $posicion<length $secuencia ; $posicion++ ) {
# Aminos�ure nehmen
$aa = substr($secuencia, $posicion, 1);
# und in einer Bedingung pr�fen, welche es ist # Bei �bereinstimmung wird die entsprechende H�ufigkeit um 1 erh�ht # in einem Array, das f�r jede Aminos�ure eine Variable bereith�lt, # alphabetisch geordnet.
if ( $aa eq 'A' ) { $aa[0]++; } elsif ( $aa eq 'C' ) { $aa[1]++; } elsif ( $aa eq 'D' ) { $aa[2]++; } elsif ( $aa eq 'E' ) { $aa[3]++; } elsif ( $aa eq 'F' ) { $aa[4]++; } elsif ( $aa eq 'G' ) { $aa[5]++; } elsif ( $aa eq 'H' ) { $aa[6]++; } elsif ( $aa eq 'I' ) { $aa[7]++; } elsif ( $aa eq 'K' ) { $aa[8]++; } elsif ( $aa eq 'L' ) { $aa[9]++; } elsif ( $aa eq 'M' ) { $aa[10]++; } elsif ( $aa eq 'N' ) { $aa[11]++; } elsif ( $aa eq 'P' ) { $aa[12]++; } elsif ( $aa eq 'Q' ) { $aa[13]++; } elsif ( $aa eq 'R' ) { $aa[14]++; } elsif ( $aa eq 'S' ) { $aa[15]++; } elsif ( $aa eq 'T' ) { $aa[16]++; } elsif ( $aa eq 'V' ) { $aa[17]++; } elsif ( $aa eq 'W' ) { $aa[18]++; } elsif ( $aa eq 'Y' ) { $aa[19]++;
# Wenn die Aminos�ure nicht gefunden wurde, # wird die Fehlerzahl inkrementiert
} else { print "ERROR: Aminoacid not found: $aa\n"; $errores++; } }
# Schlie�lich das Array mit den H�ufigkeiten zur�ckgeben
return @aa; }
Jetzt werden wir den Schritt betrachten, der nach dem Informationsflu� und der Transkription in einer Zelle geschieht. Das ist die Translation, durch die eine RNS-Sequenz, die von einem aus DNS bestehenden Gen kommt, zu einem Baustein eines Proteins oder einer Aminos�ure-Sequenz wird. Daf�r m�ssen wir den genetischen Code kennen, der ein RNS/DNS-Tripel einer Aminos�ure zuordnet. Die Sequenz extrahieren wir aus der EMBL-formatierten Datei eines Gens von Escherichia coli, und bald werden wir die �bersetzung mit der in der Datei existierenden �berpr�fen. F�r dieses Beispiel m�ssen wir ein „Associate Array“ (Hashtabelle) einf�hren. Im Programm wird nur der Kodierbereich gebraucht, der sich im Feld „FT CDS“ befindet.
#!/usr/bin/perl # �bersetzt eine DNS-Sequenz von einer EMBL-Datei # zur korrespondierenden Aminos�ure # Erh�lt den Dateinamen von der Kommandozeile (Format SWISS-PROT) # Kann auch mit "print" von <stdin> erfragt werden
if (!$ARGV[0]) {print "The program line shall be: program.pl ficha_embl\n";} $fichero = $ARGV[0];
# �ffne die Datei zum Lesen
open (FICHA, "$fichero") || die "problem opening the file $fichero\n";
# Zuerst �berpr�fen wir die Sequenz wie im zweiten Beispiel
while (<FICHA>) { chomp $_; if ($_ =~ /^FT CDS/) { $_ =~ tr/../ /; ($a1,$a2,$a3,$a4) = split (" ",$_); } elsif ($_ =~ /^SQ/) { $signal_good = 1; } elsif ($signal_good == 1) { last if ($_ =~ /^\/\//);
# Zahlen und Leerzeichen l�schen
$_ =~ tr/0-9/ /; $_ =~ s/\s//g; $secuencia.=$_; } } close (FICHA);
# Hier definieren wir ein "Associate Array", das # Aminos�uren und Nukleotide zuordnet (ebenfalls in # einer eigenen Funktion f�r den Fall, da� derselbe Code # in einem anderen Programm benutzt wird)
my(%codigo_genetico) = ( 'TCA' => 'S',# Serin 'TCC' => 'S',# Serin 'TCG' => 'S',# Serin 'TCT' => 'S',# Serin 'TTC' => 'F',# Phenylalanin 'TTT' => 'F',# Phenylalanin 'TTA' => 'L',# Leucin 'TTG' => 'L',# Leucin 'TAC' => 'Y',# Tyrosin 'TAT' => 'Y',# Tyrosin 'TAA' => '*',# stop 'TAG' => '*',# stop 'TGC' => 'C',# Cystein 'TGT' => 'C',# Cystein 'TGA' => '*',# stop 'TGG' => 'W',# Tryptophan 'CTA' => 'L',# Leucin 'CTC' => 'L',# Leucin 'CTG' => 'L',# Leucin 'CTT' => 'L',# Leucin 'CCA' => 'P',# Prolin 'CCC' => 'P',# Prolin 'CCG' => 'P',# Prolin 'CCT' => 'P',# Prolin 'CAC' => 'H',# Histidin 'CAT' => 'H',# Histidin 'CAA' => 'Q',# Glutamin 'CAG' => 'Q',# Glutamin 'CGA' => 'R',# Arginin 'CGC' => 'R',# Arginin 'CGG' => 'R',# Arginin 'CGT' => 'R',# Arginin 'ATA' => 'I',# Isoleucin 'ATC' => 'I',# Isoleucin 'ATT' => 'I',# Isoleucin 'ATG' => 'M',# Methionin 'ACA' => 'T',# Threonin 'ACC' => 'T',# Threonin 'ACG' => 'T',# Threonin 'ACT' => 'T',# Threonin 'AAC' => 'N',# Asparagin 'AAT' => 'N',# Asparagin 'AAA' => 'K',# Lysin 'AAG' => 'K',# Lysin 'AGC' => 'S',# Serin 'AGT' => 'S',# Serin 'AGA' => 'R',# Arginin 'AGG' => 'R',# Arginin 'GTA' => 'V',# Valin 'GTC' => 'V',# Valin 'GTG' => 'V',# Valin 'GTT' => 'V',# Valin 'GCA' => 'A',# Alanin 'GCC' => 'A',# Alanin 'GCG' => 'A',# Alanin 'GCT' => 'A',# Alanin 'GAC' => 'D',# Asparagins�ure 'GAT' => 'D',# Asparagins�ure 'GAA' => 'E',# Glutamins�ure 'GAG' => 'E',# Glutamins�ure 'GGA' => 'G',# Glycin 'GGC' => 'G',# Glycin 'GGG' => 'G',# Glycin 'GGT' => 'G',# Glycin );
# �bersetze jedes Codon in die entsprechende Aminos�ure # und f�ge sie der Proteinsequenz hinzu
print $a3; for($i=$a3 - 1; $i < $a4 - 3 ; $i += 3) { $codon = substr($secuencia,$i,3);
# Schreibe das Codon gro� (statt klein wie im EMBL-Format)
$codon =~ tr/a-z/A-Z/; $protein.= codon2aa($codon); } print "This proteinic sequence of the gen:\n$secuencia\nis the following:\n$protein\n\n"; exit;