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