Projekt - the Rostlab!

Werbung
Technische Universität München
Institut für Informatik
Lehrstuhl für Bioinformatik
Einführung in die Programmierung für Bioinformatiker
Prof. B. Rost, L. Richter
WS 2014/15
Aufgabenblatt 9
22.12.2014
Programmierprojekt
Aufgabe:
9.1 (Ü) Aufgabe:
Das folgende Projekt soll über die Weihnachtsferien in Java implementiert werden. Nutzen Sie dazu
nach Möglichkeit die Mittel der Standardbibliothek.
Die Datei uniprot-escherichia.fasta enthält 4433 Proteinsequenzen aus Escherichia coli. Ziel
ist es unter anderem, häufig auftretende Teilsequenzen herauszufinden. Die Schritte auf dem Weg
dorthin kommen in der Bioinformatik in der einen oder anderen Abwandlung immer wieder vor
und Sie können Teile davon weiterverwenden. Das Projekt benutzt Klassen, die in den bisherigen Übungen oder Vorlesungen noch nicht behandelt wurden. Dafür werden die entsprechenden
Code-Zeilen angegeben. Sie sollten aber selbstständig dazu auch in der Java-API nachlesen, was
diese Klassen machen bzw. wie manche Methoden zu benutzen sind. Überlegen Sie auch, welche
elementaren Schritte Sie in Hilfsfunktionen ausgliedern kı̈nnen.
9.2 (Ü) Einlesen der Sequenzen:
Die Textdatei mit den Sequenzen im fasta-Format wird zeilenweise eingelesen. Erzeugen Sie dazu
eine Klasse FastaReader, die die Methode Fasta getNextSequence(), bereitstellt. Die Methode
gibt ein Fast-Objekt zurück, dass jeweils den Fasta-Header, die Sequenz und die Sequenzlänge
enthält. Da Ein-/Ausgabe erst nach der Winterpause in der Vorlesung behandelt wird hier die
notwendigen Zeilen:
Zwischen der Package-Definition und ihrer Klasse muss die folgenden Importanweisung eingefügt
werden:
import java.io.*;
Das BufferedReader-Objekt zum Einlesen erzeugen Sie so:
BufferedReader input = new BufferedReader(new FileReader(srcPath));
Mit Hilfe des Aufrufes String inputLine = input.readLine() können Sie jeweils eine neue Zeile aus der Datei einlesen. Ist das Dateiende erreicht, gibt die Funktion null zurück. Berücksichtigen
Sie die Angaben in der API zu den jeweiligen Ausnahmen.
Das fasta-Format besagt, dass jeder Eintrag aus zwei Teilen besteht, einer einzigen Headerzeile
(mit > als erstem Zeichen) und den restlichen Zeilen, welche die Sequenz enthalten. Überlegen
1
Sie sich zunächst einen Algorithmus, der sicherstellt, dass jeweils der Header zusammen mit seiner
kompletten Sequenz weitergegeben werden. Betrachten Sie dazu die Grenzfälle wie Dateianfang
und Dateiende. Erzeugen Sie auch eine entsprechende Fasta-Klasse mit den oben beschriebenen
Eigenschaften.
9.3 (Ü) Parsen (Zerlegen) des Header:
Schreiben Sie eine Klasse HeaderParser, die die statische Methode HashMap<String,String>
parseHeader(String fastHeader) bereit stellt.
Die HashMap stellt eine ADT dar, in der einfach Schlüssel/Wert Paare gespeichert werden können.
Ein fasta-Header kann so aussehen:
>sp|P45465|YRAN ECOLI UPF0102 protein YraN OS=Escherichia coli (strain K12) GN=yraN
PE=3 SV=1
Extrahieren Sie dazu die Uniprot-ID (P45465), den EntryName (YRAN ECOLI) und den Organismus (OS=Escherichia coli (strain K12)). Die genaue Spezifikation des Headers können Sie unter
http://www.uniprot.org/help/fasta-headers nachlesen. Überlegen Sie sich, wie Sie sinnvoll
den String in die Bestandteile, die Sie interessieren zerlegen können (z.B. an besonderen Zeichen
oder Leerzeichen). Geben Sie die Felder und ihre Werte dann in der HashMap zurück.
Zur Erzeugung der HashMap brauchen Sie:
Zwischen der Package-Definition und ihrer Klasse muss die folgende Importanweisung eingefügt
werden:
import java.util.*;
Das HashMap-Objekt erzeugen Sie so:
HashMap<String, String> mappings = new HashMap<String, String>();
Bonus:
Wer schon damit gearbeitet hat, kann auch versuchen, die Headerzeile mit Hilfe regulärer Ausdrücke
und der Klassen Pattern und Matcher aus dem Paket java.util.regex zu zerlegen.
9.4 (Ü) Suchen häufiger Substrings:
Schreiben Sie eine Klasse, verschiedene Methoden zur Suche nach Teilsequenzen anbietet:
• eine Methode Collection<String> getCommon(int threshold, int length), die die
längsten (ab Länge length und länger) häufigsten Substrings (Teilsequenzen) heraussucht.
Eine Teilsequenz ist häufig, wenn Sie in threshold% der Sequenzen vorkommt. Es gibt verschiedene Verfahren dieses Problem zu lösen, aber aufgrund der kombinatorischen Explosion
sind nicht alle wirklich umsetzbar. Das hier vorgeschlagene Verfahren beruht auf einer schichtweisen Suche (levelwise search). Ausgehend von einem Alphabet mit 20 Buchstaben (den 20
Aminosäuren) werden schrittweise immer längere Kandidatenstrings erzeugt. Dabei kann ein
Kandidat der Form aX oder Xa nur dann häufig sein, wenn auch schon sein Vorgänger X
häufig war. Es gilt also in jedem Durchgang darum, Listen mit Kandidaten und Häufigkeiten
anzulegen. Eine Möglichkeit wären dafür etwa Listen wie HashMap<String, Integer>, aber
auch andere Lösungen sind denkbar. Es kann sinnvoll sein, zunächst mit einem reduzierten
2
Datensatz und einem sehr hohen Schwellenwert zu arbeiten und die Methode auszutesten.
Zu niedrige Schwellwerte können durchaus zu einem Absturz wegen zu wenig Arbeitsspeicher führen. Der genaue Rückgabetyp kann frei gewählt werden, solange das Objekt das
Collection Interface unterstützt.
• eine Methode int countOccurrence(String searchString), die angibt, wie oft der Suchstring in der Sequenzdatenbank enthalten ist. Dabei muss nur ein Vorkommen pro Sequenz
gezählt werden.
• Bonus: Erweitern Sie die o.g. Aufgabe in einer weiteren Methode, die auch Mehrfachtreffer
berücksichtigt.
3
Herunterladen