Module LV348 Version enseignant TD 3 page 1/7 TD 3 Recherche de similarités dans une banque de séquences Revu dernièrement par Mathilde Carpentier, Cyril Gallut et Joël Pothier Version du 30 mars 2012 Tous les exercices sont à faire en python. L objectif de ce TP est d écrire un programme de type FASTA. Cette méthode permet de trouver, dans une banque de séquences, les séquences ressemblant à une séquence dite requête. 1 Les données Nous travaillerons aussi avec la banque de séquences protéiques téléchargeable à l adresse : http://abiens.snv.jussieu.fr/bi/e.coli.swissprot.fst Vous pouvez télécharger une séquence requête à l adresse : http://abiens.snv.jussieu.fr/bi/b.subtilis. dna_polymerase.fst. Vous pouvez également télécharger des séquences requêtes sur le site : http://srs.ebi.ac.uk/ 2 Pseudo-Fasta L objectif est d écrire un programme qui permet de compter le nombre de mots d une taille donnée (ou graines) communs entre la séquence requête et les séquence de la banque. Ce programme retournera la séquence de la banque partageant le plus de graines avec la requête. 2.1 Lecture des fichiers Écrivez (si cela n a pas déjà été fait) une fonction python nommée readfastalmul permettant de lire un fichier fasta contenant plusieurs séquences et qui retourne la liste des tuples (nom, sequence), le nom étant la ligne de description sans le ">". 2.2 Construction du dictionnaire des graines Écrivez une fonction nommée makedict qui à partir d une séquence et d une taille de graine, construit et retourne le dictionnaire contenant pour chaque graine présente dans la séquence les positions auxquelles elle apparaît. Exemple : Soit la séquence ATGATG et des graines de taille 3. Le dictionnaire retourné doit être (sachant que les indices commencent à 0) : {ATG:[0,3], TGA:[1] GAT:[2]}. 2.3 Comptage des graines communes Écrivez une fonction qui à partir d un dictionnaire de graines généré par la fonction ci-dessus et à partir d une séquence retourne le nombre de graines communes entre les 2. 2.4 Pseudo-Fasta Utilisez les fonctions précédentes pour écrire la fonction pseudofasta qui retourne la séquence de la banque partageant le plus de graines avec la requête.
Module LV348 Version enseignant TD 3 page 2/7 3 FASTA simple En réalité, la méthode FASTA prend aussi en compte les positions où sont trouvées les graines dans les séquences. Elle recherche d abord le décalage (ie. la meilleure diagonale) des deux séquences (requête/banque) pour le quel le plus grand nombre de graines est trouvé. Par exemple si on compare la séquence requête précédente ATGATG avec la séquence de la banque TATGA le meilleur décalage est de -1, c est-à-dire : -ATGATG TATGA Il y a alors 2 graines de longueur 3 communes : ATG et TGA. Le score de similitude entre ces 2 séquences sera alors le nombre de résidus identiques entre les deux séquences lorsqu elles sont décalées. Ecrivez un programme permettant de trouver les séquences d une banque les plus similaires à une séquence requête selon cette méthode. Solution : Toutes les fonctions python sont dans le repertoire code. 1 #!/usr/bin/python 2 # -*- coding: latin1 -*- 3 4 # chargement de la bibliothèque sys 5 import sys 6 # chargement de la bibliothèque random 7 from random import * 8 9 #Question 2.1 10 # Lecture d un fichier de plusieurs séquences au format fasta 11 def readfastamul(nomfi): 12 # Lecture du contenu du fichier 13 f=open(nomfi,"r") 14 lines=f.readlines() 15 f.close() 16 # Analyse du contenu du fichier 17 seq="" 18 nom="" 19 lesseq=[] 20 for l in lines: 21 if l[0] == > : 22 if seq!= "": 23 tmp=(nom,seq) 24 lesseq.append(tmp) 25 nom=l[1:-1] 26 seq="" 27 else: 28 # Ne pas oublier d enlever le retour chariot à la fin 29 # des lignes 30 seq=seq+l[:-1] 31 if seq!= "": 32 tmp=(nom,seq) 33 lesseq.append(tmp) 34 return lesseq
Module LV348 Version enseignant TD 3 page 3/7 35 36 # Question 2.2 Pour une taille l de mot donnée et une séquence, 37 # retourne le dictionnaire contenant pour chaque mot de taille l 38 # une liste des positions auxquelles il apparaît dans la séquence 39 # 40 def makedict(seq,l): 41 resdico={} 42 for i in xrange(0,len(seq)-l+1): 43 if resdico.has_key(seq[i:i+l]): 44 resdico[seq[i:i+l]].append(i) 45 else: 46 resdico[seq[i:i+l]]=[i] 47 return resdico 48 49 #Question 2.3 50 # Fonction retournant le nombre de graines communes 51 # entre le dictionnaire crée à partir de la séquence requête et une 52 # séquence donnée. 53 def comptegrainescommunes(seq, dico): 54 l=len(dico.keys()[0]) # récuppère la longueur de la graine. 55 nbgraines=0 56 for i in xrange(0,len(seq)-l+1): # Pour chaque mot de longueur l 57 # on incremente du nombre d occurence de ce mot 58 # dans la sequence requete (i.e. longeur de la liste des 59 # positions du mot) 60 if dico.has_key(seq[i:i+l]): 61 nbgraines=nbgraines+len(dico[seq[i:i+l]]) 62 return nbgraines 63 64 #Question 2.4 65 # Fonction retournant la séquence de la banque ayant le plus nombre de graines 66 # communes avec la séquence requête (sous forme de dictionnaire). 67 def pseudofasta(listeseq, query, lggraines): 68 listeseqscores=[] 69 dico=makedict(query, lggraines) 70 for seq in listeseq[0:]: 71 score=comptegrainescommunes(seq[1],dico)#/len(listeseq[0][1]) 72 #print score,seq[0] 73 listeseqscores.append((seq,score)) 74 75 # Tri par ordre décroissant sur le deuxième élément du tuple (le score) 76 listeseqscores.sort(key=lambda SeqScore:SeqScore[1], reverse=true) 77 # Conserve les dix meilleurs 78 TenBestScores=listeSeqScores[0:10] 79 return TenBestScores 80 81 ################################################### 82 83 #Question 3.1 84 #Fonction retournant le meilleur décalage 85 def decalage(dico, lgseqdico, seq): 86 lgseq=len(seq) 87 lgraine=len(dico.keys()[0]) 88 tdec={} 89 for i in xrange(-lgseq+1,lgseqdico): 90 tdec[i]=0
Module LV348 Version enseignant TD 3 page 4/7 91 #print tdec 92 #print tvaldec 93 for i in xrange(0,lgseq-lgraine+1): 94 if dico.has_key(seq[i:i+lgraine]): 95 #print "Graine ",seq[i:i+lgraine], " trouvee" 96 for j in dico[seq[i:i+lgraine]]: 97 tdec[j-i]=tdec[j-i]+1 98 return trouveimax(tdec) 99 100 def trouveimax(tab): 101 imax=tab.keys()[0] 102 for i in tab.keys()[1:]: 103 if tab[imax]<tab[i]: 104 imax=i 105 return imax 106 107 108 109 #Version de mathilde avec un tableau 110 #Q represente la requete et B la proteine de la banque 111 #Comme les decalages calcules avec la formule iq-ib 112 #sont dans l intervalle [-lgb+1,lgq-1] et 113 #qu on veut des indices entre [0,?] 114 #Il faut qu on ajoute lgb-1 iq-ib. 115 #Ansi, on aura un indice dans [0,lgB+lgQ-2] 116 #Donc i=iq-ib+lgb-1 et pour retouver le decalage 117 # dec = i-lgb+1 118 def decalage2(dico, lgq, seq): 119 lgb=len(seq) 120 lgraine=len(dico.keys()[0]) 121 tdec=[] 122 imax=0 123 for ib in xrange(0,lgq+lgb-1): 124 tdec.append(0) 125 for ib in xrange(0,lgb-lgraine+1): 126 if dico.has_key(seq[ib:ib+lgraine]): 127 #print "Graine ",seq[i:i+lgraine], " trouvee" 128 for iq in dico[seq[ib:ib+lgraine]]: 129 tdec[iq-ib+lgb-1]=tdec[iq-ib+lgb-1]+1 130 if tdec[iq-ib+lgb-1]>tdec[imax]: 131 imax=iq-ib+lgb-1 132 return imax-lgb+1 133 134 135 #Version de Joel ou le décalage est inverse: Banque-Query et non Query -Banque 136 #Fonction retournant le meilleur decalage 137 # qdico: dictionnaire de la query 138 # lgq: longueur de la sequence query 139 # bseq: seq de la banque 140 def decalagejoel(qdico, lgq, bseq): 141 lgb=len(bseq) 142 lgraine=len(qdico.keys()[0]) 143 tdec=[] 144 # Le decalage minimal de la seq query (lgq) par rapport 145 # a la seq banque (lgb) minimal est -lgq+k 146 # exemple avec k==2
Module LV348 Version enseignant TD 3 page 5/7 147 # query: 0 1 2 3 4... lgq-3 lgq-2 lgq-1 148 # bank: <----- -lgq+k ---------> 0 1 2 3 4... lgb-1 149 # 150 # Le decalage maximal de la query / banque est de lgb-k+1 151 # exemple avec k==2 152 # query: <------ lgb-k ----> 0 1 2 3 4... lgq-3 lgq-2 lgq-1 153 # bank: 0 1 2 3 4... lgb-2 lgb-1 154 # donc l etalage de la liste des decalages doit etre: 155 # -lgq+k,..., 0,...,+lgb-k 156 # donc d une longueur ABS(-lgq+k) + 1 + lgb-k, soit lgq-k+1+lgb-k, 157 # soit encore lgq+lgb-2k+1 158 # Note: il faudra retrouver le vrai decalage en prenant l indice dans le tableau 159 # des decalages - lgq + k 160 # Exemple1: un vrai decalage de -lgq+k est a l indice 0 (ici decalage minimal) 161 # Exemple2: un vrai decalage de lgb-k est a l indice lgq+lgb-2k (ici 162 # decalage maximal) 163 # Inversement, on trouve l indice == decalage + lgq - k 164 for i in xrange(lgq+lgb-2*lgraine+1): 165 tdec.append(0) 166 #print tdec 167 indicemax = 0 168 decamax=0 169 for posb in xrange(0,lgb-lgraine+1): 170 if qdico.has_key(bseq[i:i+lgraine]): 171 #print "Graine ",bseq[i:i+lgraine], " trouvee" 172 for posq in dico[seq[i:i+lgraine]]: 173 indice = posb-posq + lgq - lgraine 174 tdec[indice]=tdec[indice]+1 175 # on note le max en meme temps 176 if tdec[indice] > tdec[indicemax]: 177 indicemax = indice 178 decamax = posb-posq 179 return decamax 180 181 182 #Question 3.2 183 # Fonction comptant le nombre d aa identiques 184 # Si les 2 protéines sont alignées selon le décalage donné 185 def CompteId(seq1,seq2,dec): 186 if dec <= 0: 187 iseq1=0 188 else: 189 iseq1=dec 190 iseq2=iseq1-dec 191 len1=len(seq1) 192 len2=len(seq2) 193 nbid=0 194 while iseq1 <len1 and iseq2 < len2: 195 if seq1[iseq1]==seq2[iseq2]: 196 nbid+=1 197 iseq1+=1 198 iseq2+=1 199 return nbid 200
Module LV348 Version enseignant TD 3 page 6/7 201 #Question 3.3 202 # Fonction retournant la séquence de la liste de séquences 203 # ayant le plus de graines commune avec la séquence requête 204 # (sous forme de dictionnaire) 205 def FastaSimple(listeSeq, query, lggraines): 206 dico=makedict(query, lggraines) 207 lgquery=len(query) 208 dec=decalage(dico, lgquery, listeseq[0][1]) 209 bestscore=compteid(listeseq[0][1],query, dec) 210 bestseq=listeseq[0] 211 for i in listeseq[1:]: 212 dec=decalage(dico, lgquery, i[1]) 213 score=compteid(i[1],query, dec) 214 #print score,i[0] 215 if score > bestscore: 216 bestscore=score 217 bestseq=i 218 return(bestseq,bestscore) 219 220 # ############################################################################### 221 ################################ main ################################ 222 223 224 # Si la ligne de commande ne contient pas le bon nombre de paramètres le 225 # programme s arrête en afichant le mode d emplois 226 if ( len(sys.argv)!= 4 ): 227 print "Usage :" 228 print "./SolutionsTD3_Fasta.py banque seqreq taille" 229 print "\tbanque : fichier fasta contenant la banque" 230 print "\tseqreq : fichier fasta contenant la séquence reqête" 231 print "\tseqreq : taille de la graine (entier)" 232 sys.exit() 233 234 #Question 2.1 235 print "Lecture de la banque" 236 messeq=readfastamul(sys.argv[1]) 237 print "Lecture de la requete" 238 query=readfastamul(sys.argv[2]) 239 taillegraine = int(sys.argv[3]) 240 241 242 #Question 2.2 243 #print makedict("atgatg",3) 244 print "Construction du dictionnaire de la séquence requête" 245 dicoquery=makedict(query[0][1],taillegraine) 246 247 #PSEUDO FASTA 248 #Question 2.3 249 #print "Nombre de graines de taille 3 communes entre ATGATG et TATGA" 250 #print comptegrainescommunes("tatga", makedict("atgatg",3)) 251 252 253 #question 2.4
Module LV348 Version enseignant TD 3 page 7/7 254 print "PseudoFasta" 255 #messeq.append(query[0]) 256 TenbestHits=pseudoFasta(mesSeq, query[0][1],taillegraine) 257 print "Meilleur hit avec pseudofasta",tenbesthits[0][0][0],"nb graines ", TenbestHits[0][1] 258 259 for i in xrange(0,10): 260 print "Nb graines =",TenbestHits[i][1]," : ",TenbestHits[i][0][0] 261 262 print 263 264 #FASTA SIMPLE 265 #question 3.1 266 #print "meilleur decalage pour les sequences ATGATG et TATGA :" 267 #print "Selon fonction decalage ", decalage(makedict("atgatg",3), 6, "TATGA") 268 #print "Selon fonction decalage2", decalage2(makedict("atgatg",3), 6, "TATGA") 269 #print "Selon fonction decalagejoel", decalagejoel(makedict("atgatg",3), 6, " TATGA") 270 #bestdec=decalage(dicoquery, len(query[0][1]), besthit[0][1]) 271 272 #question 3.2 273 #print "Nb id pour les sequences ATGATG et TATGA :" 274 #print CompteId("ATGATG", "TATGA", decalage(makedict("atgatg",3), 6, "TATGA")) 275 276 #question 3.3 277 besthit=fastasimple(messeq, query[0][1],taillegraine) 278 print "Meilleur hit avec FastaSimple",bestHit[0][0],"nb identites ",besthit[1] code/solutionstd3_fasta.py