Projet BBSG 2016 mini-pipeline de phylogénie en Java

Transcription

Projet BBSG 2016 mini-pipeline de phylogénie en Java
Projet BBSG 2016
mini-pipeline de phylogénie en Java
Introduction
Le but du projet est de construire un programme qui construit et affiche un
arbre phylogénétique à partir de séquences nucléiques ou protéiques contenues
dans un fichier au format Multi-Fasta . Nous utiliserons la librairie Parallel
Java qui génère des arbres phylogénétiques à partir de séquences nucléiques au
format Phylip-Interleaved . L’application sera découpée en deux parties indépendantes qui seront développées l’une après l’autre. Dans la première, vous
devrez transformer un fichier Multi-Fasta au format Phylip-Interleaved . Puis,
vous devrez lire le fichier Phylip-Interleaved contenant les séquences, extraire les
séquences et calculer la matrice des distance entre ces séquences.
La deuxième partie consistera à construire un arbre phylogènétique à partir
de la matrice précédemment calculée et visualiser cette arbre.
Pour les plus téméraires, des exercices supplémentaires sont proposés. Ces
exercices vont vous permettre de rendre votre application plus ”modulaire” et
plus ”complete”. De plus, Ces exercices vous permettrons de développer une
application ”complexe” du point de vue de la programmation objet.
Modalités du projet et du rendu
Pour ce projet,
— Vous devrez vous mettre en binôme.
— Vous devrez utiliser le gestionnaire de version git (Créez vous un compte
avec gitlab 1 si besoin).
— Pour chaque partie, vous devrez
— Développer une série de tests au travers une classe spéciale TestController
afin de valider (vérifier) le travail effectué. Cette série de tests vous
permettra de vérifier que l’intégralité de votre code est correct et que
vous n’avez rien cassé dans les parties précédemment achevées.
— Créer une archive .jar dans votre dépot nommé partieX-Nom1Nom2.jar
avec X le numéro de la partie.
— Nous envoyer un mail décrit ci dessous :
— L’objet de votre mail doit être de la forme
[ProjetBBSG] PartieX Nom1 Nom2
avec X le numéro de la partie rendue et Nom1, Nom2, le nom de
chaque membre du binôme,
— Le mail contiendra un lien vers votre depot git nous permettant
d’accéder à votre archive .jar. Attention, il vous faudra nous
donner un accès en lecture à l’archive (et pas forcement à l’intégralité de votre dépot). Pour nous inviter sur gitlab, mon mail
1. https://about.gitlab.com/
1
est la [email protected] et mon profil gitlab
est Antoine Naudin.
Vous devrez rendre la partie 1 du projet avant le 14/10/2016 (3 semaines).
A cette date vous recevrez une correction de cette partie. La partie 2 devra
être rendue avant le 28/10/2016 (2 semaines). La troisième partie consiste à
développer la javadoc pour votre projet et fournir un jar exécutable All in One,
documenté, devant être rendu avant le 04/11/2016 (1 semaine).
1
Extraction séquence ADN et Matrice des distances
1.1
Extraction des séquences à partir d’un fichier
Cette partie consistera à lire un fichier Multi-Fasta et créer un fichier au
format Phylip-Interleaved contenant les ”mêmes” séquences. Pour cela, il faudra
construire un parser pour les fichier Multi-Fasta (lire le fichier et en extraire les
données de façon structurée) puis générer un fichier Phylip-Interleaved avec les
séquences obtenues.
Cette opération est nécessaire pour utiliser par la suite la librairie Parallel
Java. Cette librairie nous sera très utile car elle implémente des structures de
données adaptées aux séquences nucléiques et implémente des méthodes que
nous utiliserons pour manipuler ces chaînes. La librairie Parallel Java à un
défaut, elle est incompatible avec les fichiers Multi-Fasta et ne sait lire que le
format de fichier Phylip-Interleaved 2 3 . Ci-dessous, un aperçu des deux formats
en questions.
Multi-Fasta :
>Cow Commentaire
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXX
>Carp Commentaire
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYYYYY
Phylip-Interleaved :
3 705
Cow
Carp
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
2. http://evolution.genetics.washington.edu/phylip/doc/sequence.html
3. http://www.molecularevolution.org/resources/fileformats/phylip_dna
2
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
Pour une description détaillée des formats, vous etes invités à aller voir la
documentation sur internet.
Spécificité du format Phylip-Interleaved La première ligne d’un fichier
au format Phylip-Interleaved contiendra toujours deux nombres séparés par un
espace. Le premier nombre correspond au nombre de séquences totales et le
deuxième correspond à la taille des séquences.
Différences entre Multi-Fasta et Phylip-Interleaved Les séquences contenues dans un fichier Multi-Fasta peuvent avoir des longueurs différentes. Le
format Phylip-Interleaved considère que toutes les séquences contenues dans le
fichier ont la même longueur. Il faudra en tenir compte lors de la conversion
d’un fichier Multi-Fasta au format Phylip-Interleaved .
Questions
1. Créez une classe Controller contenant un attribut séquences dont le
constructeur prend comme paramètre un nom de chemin vers un fichier
Multi-Fasta (.mfasta). Le paramètre sera de type String.
2. Créez une méthode void fastaToPhylip() dans votre classe Controller qui,
à partir de l’attribut sequences (correspondant au contenu d’un fichier
Multi-Fasta ) produira un nouveau fichier au format Phylip-Interleaved (.phy).
3. Créez dans votre classe Controller une méthode main et testez votre
code, i.e., générez un fichier au format Phylip-Interleaved à partir d’un
fichier Multi-Fasta .
1.2
Matrice des distances
Vous devrez ensuite construire la matrice des distances entre ces séquences.
Pour cela, vous devrez implémenter une fonction double distance(seq1, seq2).
Cette fonction prend deux séquences seq1 et seq2 en paramètre, et retourne
une distance (de type double) entre seq1 et seq2.
Les fichiers au format Phylip vont nous permettre d’utiliser le package
Parallel Java. Ce package propose une classe DnaSequenceList spécialement
conçue pour contenir (et représenter) des séquences nucléiques. Cette classe
implémente l’interface Iterable<DnaSequence>. Pour créer et initialiser une
3
instance de la classe DnaSequenceList , nous utiliserons la méthode
public static DnaSequenceList read(File file) 4
de la classe DnaSequenceList . Ci dessous, un passage de la documentation
expliquant cette méthode.
Read a DNA sequence list from the given input file.
The input file must be in interleaved PHYLIP format.
Une fois les séquences importées dans une instance de la classe DnaSequenceList ,
vous pourrez accéder aux différentes sequences via la méthode
public DnaSequence seq(int i)
Cette méthode retourne un objet de type DnaSequence , qui est la classe utilisée
par le package PJ pour représenter (et contenir) une séquence. Par exemple, pour
accéder à la séquence nucléique d’un objet de type DnaSequence , il vous suffit
d’appeler sa méthode toString() qui retourne la séquence sous la forme d’une
chaîne de caractères 5 .
Questions
4. Télécharger et importer le package ”Parallel Java” 6 . Nous utiliserons principalement le sous-package pj.lib.edu.rit.compbio. Attention, il se peut
que vous rencontriez quelques problèmes pour importer la package (sous
eclipse ou autre).
5. Dans votre main, créez un objet de la classe DnaSequenceList du package
PJ et initialisez-la avec un fichier au format Phylip.
6. Vérifier que votre code fonctionne comme il se doit.
Il ne nous reste plus qu’à calculer la matrice des distances à partir des séquences importées. Pour cela,
7. Créer une classe DnaDistance implémentant l’interface Distance 7 du package ”Parallel Java”.
8. Implémenter la méthode
double distance(DnaSequence seq1, DnaSequence seq2)
de la classe DnaDistance imposée par l’interface. Cette méthode retourne
une distance (type double) entre les sequences seq1 et seq2. Vous être
libre du choix de la distance et de son implémentation. La contrainte est
de coder vous même la distance et non de réutiliser une classe existante
pour la calculer.
4. https://www.cs.rit.edu/~ark/pj/doc/edu/rit/compbio/phyl/DnaSequenceList.
html#read(java.io.File)
5. https://www.cs.rit.edu/~ark/pj/doc/edu/rit/compbio/phyl/DnaSequence.html
6. https://www.cs.rit.edu/~ark/pj.shtml#download
7. https://www.cs.rit.edu/~ark/pj/doc/edu/rit/compbio/phyl/Distance.html
4
Voir le choix des
distances
9. Dans la classe Controller , ajouter une variable d’instance double [][]
distanceMatrix (tableau 2-dimensionnel de type double).
10. Dans la classe Controller , implémenter une méthode
double[][] fillDistanceMatrix(DnaSequenceList listSeq)
qui calcule et retourne la matrice des distances calculée à partir des séquences contenues dans l’objet listSeq et de votre méthode distance()
implémentée precedemment.
11. Compléter votre fonction main() pour que votre programme calcule cette
matrice.
12. Exporter votre matrice au format décrit sur la page http://evolution.
genetics.washington.edu/phylip/doc/distance.html afin de pouvoir
reconstruire l’arbre, l’exporter au format Newick, et le visualiser grâce
à des outils comme phylip drawtree ou phylip drawgram. Vous pouvez
aller consulter la documentation de PJ car il existe surement des methodes
déjà implémentées pour exporter une matrice au format voulu.
Optionnel : Cette distance devra respecter certaines propriétés 8 pour être
considérée comme une vraie distance ! Implémentez une fonction vérifiant que
votre distance les respecte. Vous inclurez ce test dans votre batterie de tests
unitaires.
2
Construction de l’arbre phylogénétique et Visualisation
A partir de la matrice de distances précédemment construite, nous allons
construire un arbre phylogénétique et le visualiser.
2.1
Construction d’un arbre phylogénétique
Pour cela, vous pourrez utiliser l’algorithme UPGMA 9 implémenté dans la
classe Upgma du package PJ. Le but n’est pas de coder UPGMA. Pour plus
d’informations, nous vous renvoyons vers la documentation officielle 10 . Nous
utiliserons la méthode suivante (de la classe Upgma) pour construire notre arbre
phylogénétique,
static DnaSequenceTree buildTree(DnaSequenceList seqList, Distance dcalc)
Build a phylogenetic tree of the given DNA sequences.
Notez que cette méthode est static. La méthode buildTree() construit donc
un arbre à partir de vos séquences (regroupées dans l’instance seqList de la
8. https://fr.wikipedia.org/wiki/Distance_(mathématiques)
9. https://en.wikipedia.org/wiki/UPGMA
10. https://www.cs.rit.edu/~ark/pj/doc/edu/rit/compbio/phyl/Upgma.html
5
classe DnaSequenceList ) et de votre classe Distance (Distance dcalc). Cette
arbre est encapsulé dans une instance de la classe DnaSequenceTree . Pour exporter cet arbre au format newick, vous pourrez utiliser la fonction toString()
de la classe DnaSequenceTree qui retourne du newick ! comme vous pouvez le
voir dans la documentation recopiée ci-dessous :
public String toString()
Returns a string version of this DNA sequence tree.
The returned string is in Newick Standard format,
including the branch lengths if any and the tip
nodes’ DNA sequence names. For further information
about Newick Standard format, ...
1. Constuire l’arbre phylogénétique à partir de vos séquences en utlisant la
methode buildTree() décrite ci dessus.
2. Exportez l’arbre phylogénétique dans un fichier au format newick.
2.2
Visualisation de l’arbre
1. Pour finir, il ne nous reste plus qu’à afficher l’arbre phylogénétique, i.e.,
produire un fichier ”image”. Dans un premier temps, vous utiliserez un
programme externe à partir d’un arbre encodé en newick (voir Introduction).
2. Si vous avez le temps, nous vous invitons a aller regarder de plus prêt la
classe Class TreeDrawing du package edu.rit.compbio.phyl. Cette
classe contient une méthode
void draw(DnaSequenceTree tree)
qui affiche une image de l’arbre tree donnée en argument.
3
Questions optionnelles
3.1
Concaténation de fichiers Fasta en un seul fichier Multi-Fasta
1. Implémentez la méthode
String concatFasta(String dirname)
qui prend en paramètre un (chemin vers un) nom de dossier dirname
contenant des séquences FASTA (.fasta). Cette méthode concatène tous
les fichiers FASTA présents dans le répertoire dirname en un seul fichier
au format multi-FASTA (.mfasta).
2. Créer classe TestController qui étends la classe Controller . Cette
classe nous servira à tester l’implémentation des méthodes de la classe
Controller .
6
3. Télécharger le dossier .. contenant
— un dossier dirname contenant des séquences fasta,
— un fichier output.mfasta contenant le résultat de la concaténation des
fichiers présents dans le répertoire input.
4. Implémentez une méthode int testConcatFasta(String dirname, String
result) dans la classe TestController. Celle-ci ira lire le contenu des fichiers fasta placés dans le répertoire dirname. Le paramètre result est
l’adresse d’un fichier Multi-Fasta correspondant au résultat attendu suite
à la concaténation des fichiers présents dans le répertoire dirname.
Cette méthode devra appeler la méthode concatFasta(dirname) de la
classe Controller et vérifier que la chaîne de caractères retournée par
l’appel est bien égale au résultat attendu présent dans le fichier result.
Si la fonction nous retourne une chaîne de caractères identique au contenu
du fichier result, la méthode retournera true et false sinon .
Par exemple, si le dossier dirname contient trois séquences string1, string2
et string3, alors la méthode retournera true si
string1 + string2 + string3 == result
.
5. Créez une méthode static void main(String args), exécutez et vérifiez que votre code fonctionne.
3.2
Importation de XML et TXT
Il vous faudra adapter votre programme (de façon intelligente :-) ) pour
pouvoir à votre souhait importer, soit des fichiers aux formats XML, TXT, ou
fasta.
1. Implémentez l’interface Parser suivante
public i n t e r f a c e P a r s e r {
public Sequence p a r s e F i l e ( ) ;
public S t r i n g r e a d F i l e ( ) ;
}
La méthode parseFile() va extraire les séquences d’ADN contenu dans
le fichier fic. La méthode readFile() va retourner le contenu du fichier
sous forme de chaîne de caractères.
2. Chaque classe qui implémentera Parser sera dédié à un seul type de fichier.
Créez une classe implémentant l’interface Parser pour le type de fichier de
votre choix. Par exemple, nous présentons ci dessous la classe XMLParser
pour le format XM L.
7
public c l a s s XmlUrlParser implements P a r s e r {
String f i c ;
public XmlUrlParser ( S t r i n g f i c ) {
this . f i c=f i c ;
}
public int p a r s e F i l e ( ) {
System . out . p r i n t l n ( " t o ␣ be ␣ implemented ! " ) ;
return 0 ;
}
public S t r i n g r e a d F i l e ( ) {
System . out . p r i n t l n ( " t o ␣ be ␣ implemented ! " ) ;
return 0 ;
}
}
3. Implémentez les méthodes de la classe précédemment construite.
4. Téléchargez un fichier contenant des séquences (attention au type) et tester
votre code.
3.3
Acquisition de données
On souhaite pouvoir télécharger des données (génomiques ?) à partir d’une
URL sur internet. Par exemple depuis EBI 11 . Pour cela, vous pourrez vous
appuyer sur la classe ci dessous nommé ”URLContent”.
public class URLContent{
public static getURLContent(String u) {
URL URL;
try {
// get URL content
URL = new URL(u);
URLConnection conn = URL.openConnection();
// open the stream and put it into BufferedReader
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}
br.close();
11. https://www.ebi.ac.uk/ena/data/view/X65924&display=fasta
8
System.out.println("Done");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
1. Ajouter un constructeur supplémentaire pour la classe Controller prenant
une ou plusieurs URL en arguments
3.4
Export GraphViz
Exporter vos arbres aux formats graphviz pour les visualiser avec l’outil
graphviz.
4
Pré-requis et Connaissances requises
Partie 1 : Import sequences
— Test unitaires (méthodologie)
Partie 2 : Construction arbre
— Utilisation package externe
— Utilisation structure de données ”complexes” (multi-niveau)
Partie 3 : Option et visualisation
— GraphViz
— Coder à la main l’export graphviz. Voir la documentation de graphviz
et le format .dot sur internet.
9