Cours d’initiation au langage Perl : les variables et fonctions


Télécharger Cours d’initiation au langage Perl : les variables et fonctions

★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Télécharger aussi :


Introduction à Perl pour la bioinformatique

M2 bioinformatique

Jérôme Farinas

Institut de Recherche en Informatique de Toulouse Université Paul Sabatier

21 octobre 2010

 

Présentation du cours

Le cours est séparé en neuf parties.

Détail des parties :

1   Introduction (30 mn - Mustapha)

2   Séquences et chaˆ?nes de caractères (2h30 - Mustapha)

3   Motifs et boucles (3h - Mustapha)

4   Sous-programmes et débogage (3h - Mustapha)

5   Exercices (3h - Mustapha)

6   Mutations et nombres aléatoires (3h - Jérôme)

7   Code génétique (3h - Jérôme)

8   Cartes de restriction et expressions régulières (3h - Jérôme)

9   Exercices et examen écrit (4h - Jérôme)

Première partie I Introduction (COURS 2008)

Plan de la partie

Références

Premiers pas en Perl

L’art de la programmation


Références

Premiers pas en Perl

L’art de la programmation

Références bibliographiques

1   « Introduction à Perl pour la bioinformatique », james Tisdall, éd.

O’Reilly

I   base de ce cours

2   « Introduction à Perl », Randal L. Swartz et Tom Christiansen, éd.

O’Reilly

I   très didactique

3   « Programmation en Perl », Larry Wall, Tom Christiansen & Jon

Orwant, éd. O’Reilly

I   pour aller plus loin avec Perl

4  

I   le site officiel

Références

Premiers pas en Perl

L’art de la programmation

Premiers pas en Perl

Une courbe d’apprentissage basse et longue

Avantage de Perl

Versions de Perl

Installation de Perl sur votre ordinateur Comment exécuter des programmes?

Editeurs de texte´

Obtenir de l’aide

Références

Premiers pas en Perl

L’art de la programmation

L’art de la programmation

Différentes approches pour la programmation

Edition-exécution-modification´

Sauvegardes

Messages d’erreur

Débogage

Un vivier de programmes

Les programmes libres (open source)

Stratégies de programmation

Le processus de la programmation


Deuxième partie II

Séquences et chaˆ?nes de caractères (COURS 2008)

Plan de la partie

Représentation de données de séquences

Un programme pour stocker une séquence ADN

Concaténation de fragments ADN

Transcription : ADN en ARN

Calcul du complément inverse d’un brin d’ADN en Perl

Protéines, fichiers et tableaux

10  Exercices

11  Synthèse

Plan

Représentation de données de séquences

Un programme pour stocker une séquence ADN

Concaténation de fragments ADN

Transcription : ADN en ARN

Calcul du complément inverse d’un brin d’ADN en Perl

Protéines, fichiers et tableaux

10  Exercices

11  Synthèse

Terminologie biologique

Les symboles utilisés en bioinformatique pour représenter les séquences d’ADN et de protéines sont les mêmes que ceux utilisés par les biologistes dans la littérature.

ADN = { 4 nucléotides différents } protéines = { 20 acides aminés } fragments de protéines = peptides nucléotide + sucre (désoxyribose pour ADN, ribose pour ARN) = nucléosides

nucléosides = { adénosine, guanosine, cytidine, thymidine, uridine } nucléotide + phosphate = nucléotides

nucléotides = { acide adélinique, guanilique, cytidilique, thymidilique, uridylique }

acide nucléique = suite de nucléotides reliées entre eux par une liaison phosphodiester peptide = court polymère d’acides aminés protéine = unité biologique fonctionnelle faite de un ou plusieurs polypeptides


Bases nucléotidiques

                                               Code    Base nucléotidiques

A            Adémine C         Cytosine

                                                  G        Guanine

T            Thymine U          Uracile

                                                  M         A ou C (amino)

                                                  R          A ou G (purine)

                                                  W          A ou T (liaison faible)

S            C ou G (liaison forte) Y   C ou T (pyrimidine)

                                                  K          G ou T (céto)

                                                  V          A ou C ou G

                                                  H          A ou C ou T

                                                  D           A ou G ou T

                                                  B           C ou G ou T

                                                  N           A ou G ou C ou T

I

Code à une lettre

Acide aminé

Code à trois lettres

L

Leucine

Leu

A

Alanine

Ala

B

Acide aspartique ou Asparagine

Asx

C

Cystéine

Cys

D

Acide aspartique

Asp

E

Acide glutamique

Glu

F

Phénylalanine

Phe

G

Glycine

Gly

H

Histidine

His

I

Idoleucine

Ile

K

Lysine

Lys

M

Méthionine

Met

N

Asparagine

Asn

P

Proline

Pro

II

Q

Glutamine

Gln

R

Arginine

Arg

S

Sérine

Ser

T

Thréonine

Thr

V

Valine

Val

W

Tryptophane

Trp

X

Inconnu

Xxx

Y

Tyrosine

Tyr

Z

Acide glatamique ou Glutamine

Glx

III

La terminologie utilisée en informatique diffère légèrement de celle utilisée en biologie en ce qui concerne les deux précédents tableaux.

Alphabet = ensemble finis de symboles

Chaˆ?ne de caractères = suite de symboles

Langage = ensemble (fini ou infni) de chaˆ?nes de caractères (ici, séquences nucléiques ou protéiques)


Plan

Représentation de données de séquences

Un programme pour stocker une séquence ADN

Concaténation de fragments ADN

Transcription : ADN en ARN

Calcul du complément inverse d’un brin d’ADN en Perl

Protéines, fichiers et tableaux

10  Exercices

11  Synthèse

Un programme pour stocker une séquence ADN I

Un programme pour stocker une séquence ADN II

Remarques sur ce programme :

Contrôle du flux (ordre dans lequel les instructions sont exécutées)

Commentaires

Ligne d’invocation

Instructions

Variables

Chaˆ?ne de caractères

Affectation

Affichage

Fin du programme

Plan

Représentation de données de séquences

Un programme pour stocker une séquence ADN

Concaténation de fragments ADN

Transcription : ADN en ARN

Calcul du complément inverse d’un brin d’ADN en Perl

Protéines, fichiers et tableaux

10  Exercices

11  Synthèse

Concaténation de fragments ADN I

#!/usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Concaténer deux fragments d’ADN et les afficher #

# Stockons les fragments d’ADN dans deux variables ADN1 et ADN2

$ADN1 = ’ACGGGAGGACGGGAAAATTACTACGGCATTAGC’;

$ADN2 = ’ATAGTGCCGTGAGAGTGATGTAGTA’;

# Affichons les fragments d’origine (valeurs des variables ADN1 et ADN2) print "Voici les fragments d’ADN d’origine :\n\n"; print $ADN1, "\n"; print $ADN2, "\n\n";

# Concaténons les fragments d’ADN dans une troisième variable appelée

# ADN3 en utilisant l’interpolation des cha^?nes et affichons sa valeur

$ADN3 = "$ADN1$ADN2";

Concaténation de fragments ADN II

print "Voici la concaténation des deux fragments (version 1) :\n\n"; print "$ADN3\n\n";

# Concaténons les fragments d’ADN dans une troisième variable appelée

# ADN3 et en utilisant l’opérateur . de concaténation affichons-la

$ADN3 = $ADN1 . $ADN2; print "Voici la concaténation des deux fragments (version 2) :\n\n"; print "$ADN3\n\n";

# Affichons la concaténation sans stockage intermédiaire print "Voici la concaténation des deux fragments (version 3) :\n\n"; print $ADN1, $ADN2, "\n\n";

# Fin explicite exit;

Résultat

Plan

Représentation de données de séquences

Un programme pour stocker une séquence ADN

Concaténation de fragments ADN

Transcription : ADN en ARN

Calcul du complément inverse d’un brin d’ADN en Perl

Protéines, fichiers et tableaux

10  Exercices

11  Synthèse

Transcription : ADN en ARN I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Transcrire de l’ADN en ARN

#

# Stockons le fragment d’ADN

$ADN = ’ACGGGAGGACGGGAAAATTACTACGGCATTAGC’;

# Affichons le fragment d’ADN print "Voici le fragment d’ADN d’origine :\n\n"; print "$ADN\n\n";

# Transcrivons l’ADN en ARN en substituant tous les T par des U

$ARN = $ADN;

$ARN =~ s/T/U/g;

# Affichons le fragment d’ARN print "Voici le résultat de la transcription de l’ADN en ARN :\n\n";

Transcription : ADN en ARN II

print "$ARN\n";

# Fin explicite exit;

Résultat

Plan

Représentation de données de séquences

Un programme pour stocker une séquence ADN

Concaténation de fragments ADN

Transcription : ADN en ARN

Calcul du complément inverse d’un brin d’ADN en Perl

Protéines, fichiers et tableaux

10  Exercices

11  Synthèse


I

#!/usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Calculer le reverse complément d’un brin d’ADN #

# Stockons le fragment d’ADN

$ADN = ’ACGGGAGGACGGGAAAATTACTACGGCATTAGC’;

# Affichons le fragment d’ADN print "Voici le fragment d’ADN d’origine :\n\n"; print "$ADN\n\n";

# Calculons le complément inverse

# ATTENTION : cette tentative va échouer

#

# Premièrement, copions l’ADN dans une nouvelle variable $revcom

# (raccourci pour REVerse COMplément)

II

# Remarquez que les noms de variables peuvent utiliser des minuscules

# comme "revcom" mais également des majuscules comme "ADN". En fait, # les minuscules sont plus courantes. En revanche, les caractères accentués

# sont interdits.

#

# Il importe peu que nous retournions la cha^?ne avant de la complémenter # ou que nous la complémentions avant de la retourner.

# Si bien que lorsque nous faisons la copie, nous la retournons en meme

# temps

#

$revcom = reverse $ADN;

#

# Substituons à présent chaque base par sa base complémentaire

# A->T, T->A, G->C, C->G

#

$revcom =~ s/A/T/g;

$revcom =~ s/T/A/g;

$revcom =~ s/G/C/g;

III

$revcom =~ s/C/G/g;

# Affichons le complément inverse obtenu print "Voici le complément inverse :\n\n"; print "$revcom\n";

#

# Oh-oh, ¸ca ne marche pas correctement

# Notre complément inverse devrait avoir un peu de toutes les bases

# de notre séquence d’ADN d’origine et pas seulement des A et des G #

# Voyez-vous pourquoi?

#

# Le problème provient des deux premières substitutions qui changent

# tous les A en T, puis tous les T en A, il ne reste plus que des A

# à la place des A et des T initiaux

# La m^eme chose se produit pour les C et les G

# print "\nL’algorithme est mauvais, le complément inverse incorrect!\n"; print "Essayons encore \n\n";

IV

# Stockons une nouvelle copie du fragment d’ADN (vous comprenez pourquoi

# nous avons conservé l’original)

$revcom = reverse $ADN;

# Voir les explications pour une présentation de la fonction tr///

$revcom =~ tr/ACGTacgt/TGCAtgca/;

# Affichons le complément inverse du fragment d’ADN print "Voici le complément inverse :\n\n"; print "$revcom\n"; print "\nCette fois ¸ca marche!\n\n";

exit;


Résultat

Plan

Représentation de données de séquences

Un programme pour stocker une séquence ADN

Concaténation de fragments ADN

Transcription : ADN en ARN

Calcul du complément inverse d’un brin d’ADN en Perl

Protéines, fichiers et tableaux

10  Exercices

11  Synthèse

Lire la séquence d’une protéine contenue dans un fichier I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Lire la séquence d’une protéine contenue dans un

# fichier #

# Le nom du fichier contenant la séquence de la protéine $nom_fichier_proteine = ’’;

# Nous devons tout d’abord ouvrir le fichier et lui associer un # descripteur de fichier qui permet par la suite d’accéder facilement au # fichier.

# Nous avons utilisé FIC_PROTEINE pour plus de lisibilité open(FIC_PROTEINE, $nom_fichier_proteine);

# Nous pouvons à présent lire la séquence de la protéine depuis


II

# le fichier en utilisant les caractères < et > pour lire les # informations depuis le descripteur de fichiers. Nous stockons les données

# dans notre variable proteine.

$proteine = <FIC_PROTEINE>;

# Nous avons nos données, nous pouvons fermer le fichier close FIC_PROTEINE;

# Affichons la valeur de la variable proteine print "Voici la protéine :\n"; print $proteine;

exit;

Résultat

I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Lire la séquence d’une protéine contenue dans un

# fichier. Deuxième essai #

# Le nom du fichier contenant la séquence de la protéine $nom_fichier_proteine = ’’;

# Nous devons tout d’abord ouvrir le fichier et lui associer un # descripteur de fichier qui permet par la suite d’accéder facilement au # fichier.

# Nous avons utilisé FIC_PROTEINE pour plus de lisibilité. open(FIC_PROTEINE, $nom_fichier_proteine);

# Nous pouvons à présent lire la séquence de la protéine depuis


II

# le fichier en utilisant les caractères < et > pour lire les # informations depuis le descripteur de fichiers.

# Puisque le fichier contient trois lignes et que la lecture retourne

# une seule ligne, nous allons devoir lire et afficher une ligne

# trois fois de suite

# Première ligne

$proteine = <FIC_PROTEINE>;

# Affichons la première ligne du fichier contenant la protéine print "\nVoici la première ligne du fichier-protéine :\n\n"; print $proteine;

# Deuxième ligne

$proteine = <FIC_PROTEINE>;

# Affichons la deuxième ligne du fichier contenant la protéine

III

print "\nVoici la deuxième ligne du fichier-protéine :\n\n"; print $proteine;

# Troisième ligne

$proteine = <FIC_PROTEINE>;

# Affichons la troisième ligne du fichier contenant la protéine print "\nVoici la troisième ligne du fichier-protéine :\n\n"; print $proteine;

# Nous avons nos données, nous pouvons fermer le fichier close FIC_PROTEINE;

exit;

Résultat


Tableaux : lire la séquence d’une protéine contenue dans un fichier (troisième essai) I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Lire la séquence d’une protéine contenue dans un

# fichier. Troisième essai

#

# Le nom du fichier contenant la séquence de la protéine $nom_fichier_proteine = ’’;

# Nous devons tout d’abord ouvrir le fichier et lui associer un # descripteur de fichier qui permet par la suite d’accéder facilement au # fichier.

# Nous avons utilisé FIC_PROTEINE pour plus de lisibilité. open(FIC_PROTEINE, $nom_fichier_proteine);

# Nous pouvons à présent lire la séquence de la protéine depuis le

Tableaux : lire la séquence d’une protéine contenue dans un fichier (troisième essai) II

# fichier en utilisant les caractères < et > pour lire les

# informations depuis le descripteur de fichiers et la stocker dans la # variable tableau @proteine.

@proteine = <FIC_PROTEINE>;

# Affichons le contenu de la variable tableau @proteine print "\nVoici la séquence de la protéine lue dans le fichier :\n\n"; print @proteine;

# Nous avons nos données, nous pouvons fermer le fichier close FIC_PROTEINE;

exit;

Résultat

Contexte scalaire et contexte de liste

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Démonstration des contextes scalaire et liste #

# Le tableau contenant les quatre bases @bases = (’A’, ’C’, ’G’, ’T’); print "@bases\n";

# La variable $a re¸coit le nombre d’éléments du tableau @bases

$a = @bases; print $a, "\n";

# La variable $a re¸coit le premier élément du tableau @bases

($a) = @bases; print $a, "\n";

# Fin explicite exit;

Résultat

Plan

Représentation de données de séquences

Un programme pour stocker une séquence ADN

Concaténation de fragments ADN

Transcription : ADN en ARN

Calcul du complément inverse d’un brin d’ADN en Perl

Protéines, fichiers et tableaux

10  Exercices

11  Synthèse

Exercices I

1   Cet exercice permet de se rendre compte de la sensibilité des langages de programmation face aux erreurs de syntaxe. Essayez d’enlever le point virgule à la fin de n’importe quelle instruction de l’un de vos programmes et examinez le message d’erreur qu’il en résulte, s’il y en a un. Essayez de changer un autre élément de syntaxe : ajoutez une parenthèse ou un crochet; écrivez print ou n’importe quel autre mot réservé en faisant une faute d’orthographe; ajoutez ou retirez ce qu’il vous plait. Les programmeurs sont habitués à répéter ce genre d’erreurs, même en connaissant parfaitement le langage, il est fréquent d’avoir des erreurs de syntaxe au fur et à mesure que l’on ajoute des lignes de code. Remarquez combien une erreur sur une ligne peut mener à plusieurs lignes pour lesquelles les avertissements sont envoyés. Perl indique-t-il avec précision la ligne ou` se trouve l’erreur?

2   Ecrivez un programme qui stocke un entier dans une variable et´ l’affiche ensuite.

Exercices II

3   Ecrivez un programme qui affiche une séquence ADN (qui pourra être´ en majuscules ou en minuscules à l’origine) en utilisant des lettres minuscules (a,c,g,t). Ecrivez-en un autre qui écrit l’ADN en´ majuscules (A,C,G,T). Utilisez la fonction tr///.

4   Faites la même chose que l’exercice précédent mais utilisez les directives pour les chaˆ?nes de caractères \U pour majuscules (en anglais uppercase), et \L pour les minuscules (en anglais lowercase), au lieu d’utiliser la fonction tr///.

5   Parfois l’information circule de l’ARN vers l’ADN. Ecrivez un´ programme qui affiche une transcription inverse de lARN en ADN.

6   Lisez deux fichiers de données et affichez le contenu du premier suivi du conteu du second.

7   Ecrivez un programme permettant de lire un fichier et d’afficher´ ensuite ses lignes en ordre inverse (la dernière ligne en premier).

Fonctions pouvant être utiles : push, pop, shift, unshift, reverse.

Plan

Représentation de données de séquences

Un programme pour stocker une séquence ADN

Concaténation de fragments ADN

Transcription : ADN en ARN

Calcul du complément inverse d’un brin d’ADN en Perl

Protéines, fichiers et tableaux

10  Exercices

11  Synthèse

Synthèse

A la fin de cette partie, vous avez commencé à écrire des programmes perl qui manipulent des données de séquences biologiques, telles que l’ADN et les protéines.

Avec quelques séquences dans l’ordinateur il est possible de :

transcrire de l’ADN en ARN; concaténer des séquences; produire des séquences complémentaires; lire des données de séquences à partir de fichiers.

Vous avez manipulé des concepts de base en Perl :

les variables scalaires; les variables tableaux; des opérations sur les chaˆ?nes de caractères (substitution, traduction); la lecture de données à partir de fichiers.

Troisième partie III

Motifs et boucles (2009)

Plan de la partie

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

Controˆle du flux du programme

Contrôle de flux

Ordre dans lequel les instructions d’un programme sont exécutées.

Un programme s’éxécute de la première instruction (au début du programme) à la dernière instruction (en fin de programme), à moins qu’une sortie explicite en décide autrement.

 Pour modifier le contrôle de flux de programme :

I les instructions conditionnelles (if, unless); I les boucles (while, unless ).


L’instruction if

Bloc d’instructions

Booléens

En Perl, les règles pour représenter true ou false sont légèrement

étranges mais produisent le résultat attendu. L’expression de contre est évaluée comme une valeur de chaˆ?ne dans un contexte scalaire (s’il s’agit d’une chaˆ?ne, pas de changement, mais s’il s’agit d’un nombre, il est converti en chaˆ?ne). Si cette chaˆ?ne est soit une chaˆ?ne vide (de longueur nulle), soit la chaˆ?ne contenant un seul caractère 0 (le chiffre zero), la valeur de l’expression est false. Tout le reste est automatiquement true.

0         # se change en "0" donc false

1-1                   # se calcule en 0, puis se change en "0", donc false

1         # se change en "1" donc true

""                   # chaˆ?ne vide, donc false

"1"                   # non "" et non "0", donc true

"00"      # non "" et non "0", donc true (c’est surprenant, attention) "0.000" # est également true, même raison et même avertissement undef # est évalué en "", donc false


L’instrcution unless

L’instruction elsif I

L’instruction elsif II

Chaque expression (ici : expression_un, expression_deux et expression_trois) est calculée à tour de rôle.

Si une expression est vraie, la branche correspondante est exécutée et toutes les expressions de contrôle restantes et les blocs d’instructions correspondants sont sautés.

Si toutes les expressions sont fausses, la branche else est exécuté (si elle existe).

Vous pouvez avoir autant de branche elsif que vous voulez.


Exemple complet I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Les structures conditionnelles if-elsif-else #

$fragment = ’MNIDDKL’;

# Utilisons les structures conditionnelles if-elsif-else if ( $fragment eq ’QSTVSGE’ )

{ print "QSTVSGE\n";

} elsif ( $fragment eq ’MRQQDMISHDEL’ )

{ print "MRQQDMISHDEL\n";

} elsif ( $fragment eq ’MNIDDKL’ )

{

Exemple complet II

print "MNIDDKL : le fragment magique!\n";

} else { print "le fragment \"$fragment\" n’est pas trouvé \n";

} exit;

Boucles I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Lire les séquences des protéineis contenues dans un # fichier. Quatrième essai.

#

# Le nom du fichier contenant les séquences des protéines $nom_fichier_proteine = ’’;

# Nous devons tout d’abord « ouvrir » le fichier et, dans le cas où

# l’ouverture échoue, afficher un message d’erreur et quitter le

# programme unless ( open(FIC_PROTEINE, $nom_fichier_proteine) )

{ print "Impossible d’ouvrir le fichier $nom_fichier_proteine!\n"; exit;

}

Boucles II

# Lisons la séquence de la protéine depuis le fichier gr^ace à une # boucle while affichant les lignes au fur et à mesure de la lecture while( $proteine = <FIC_PROTEINE> )

{ print " ###### Voici la prochaine ligne du fichier :\n"; print $proteine; }

# Nous avons nos données, nous pouvons fermer le fichier close FIC_PROTEINE;

exit;

Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

Formattage du code I

 Une fois que vous avez commencé à utiliser des boucles et des instructions conditionneles, il faut penser sérieusement au format du code que vous allez produire. De nombreux choix sont possibles.

exemple :

I Format A : while ( $vivante ) { if ( $besoin_nutriments ) { print "La cellule a besoin de nutriments\n"; }

}

I Format B :

while ( $vivante )

{ if ( $besoin_nutriments )

{ print "La cellule a besoin de nutriments\n"; }

}

Formattage du code II

 suite exemple :

I Format C : while ( $vivante ) { if ( $besoin_nutriments )

{ print "La cellule a besoin de nutriments\n";

}

}

I Format D : while ($vivante){if($besoin_nutriments){print "La cellule a besoin de nutriments\n";}}

I man perlstyle ou perldoc perlstyle

Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

Motifs en bioinfo

recherche de motifs : courts segments d’ADN ou de protéines présentant un interet particulier exemple :

I recherche des éléments de régulation de l’ADN

I courtes portions de protéiness qui sont connues pour etre conservées chez de nombreuses espèces

I cf. site web PROSITE

 Il peut y avoir des variantes dans les motifs à rechercher, il peut y avoir des variations de taille

?utilisation d’expressions régulières

 Exemple de traitement :

I lire la séquence d’une protéine depusi un fichier

I organiser la séquence en une seule chaine de caractères pour faciliter la recherche

I rechercher dans la séquence les motifs entrés au clavier par l’utilisateur.


I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Rechercher des motifs

#

# Demandons à l’utilisateur le nom du fichier # contenant la séquence et lisons la réponse print "Entrer le nom du fichier à ouvrir : "; $nom_fichier_proteine = <STDIN>;

# Retirons le retour-chariot (\n) en fin de réponse chomp $nom_fichier_proteine;

# Nous devons tout d’abord « ouvrir » le fichier et, dans le cas où

# l’ouverture échoue, afficher un message d’erreur et quitter le

# programme unless ( open(FIC_PROTEINE, $nom_fichier_proteine) )

II

{ print "Impossible d’ouvrir le fichier $nom_fichier_proteine!\n"; exit;

}

# Nous pouvons à présent lire la séquence de la protéine gr^ace au descripteur

# de fichier FIC_PROTEINE placé entre les caractères < et >

# Nous la stockons dans la variable tableau @proteine @proteine = <FIC_PROTEINE>;

# Nous avons nos données, nous pouvons fermer le fichier close FIC_PROTEINE;

# Concaténons toutes les lignes pour placer la séquence de la protéine

# dans une seule cha^?ne de caractères. Il sera plus simple de rechercher

# un motif dans une cha^?ne plut^ot que dans un tableau de lignes

# (que se passe-t-il si le motif est à cheval sur deux lignes?)

$proteine = join(", @proteine);

III

# Retirons les éventuels espaces

$proteine =~ s/\s//g;

# Dans une boucle, demandons un motif à l’utilisateur d’entrer un motif

# Recherchons-le dans la protéine et affichons-le s’il est trouvé

# Fin du programme si aucun motif n’est entré do { print "Entrer un motif à rechercher : "; $motif = <STDIN>;

# Retirons le retour-chariot à la fin de $motif chomp $motif; # Recherchons le motif if ( $proteine =~ /$motif/ )

{ print "Je l’ai trouvé!\n\n";

} else

IV

{ print "Je ne l’ai pas trouvé.\n\n"; }

# Sortie de boucle si la cha^?ne est vide

} until ( $motif =~ /^\s*$/ );

exit;


Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

L’instruction while

Cela est répété jusqu’à ce que l’expression devienne fausse, moment ou` Perl se branche sur l’instruction suivant la boucle while.

Recherche de motifs à l’aide de while I

#! /usr/bin/perl -w

#

# Nom du programme : exemple5-3.1pl

# But du programme : Rechercher des motifs à l’aide de while #

#Définissons une courte séquence protéique

$proteine = "ACDEFGHIKLMNYVWTSRQP";

# Préparons la boucle en demandant à l’utilisateur

# d’entrer son motif au clavier. En m^eme temps que ce # motif est lu, enlevons le retour-chariot à la fin du motif print "Entrer un motif à rechercher : "; chomp ($motif = <STDIN>);

# L’instruction while suivante teste si le motif est vide # Si le motif n’est pas vide, la boucle est exécutée while ( $motif!~ /^$/ )

{

Recherche de motifs à l’aide de while II

if ($proteine =~ /$motif/ )

{ print "\nLe motif existe dans la séquence!\n\n";

} else { print "\nPas de motif dans la séquence!\n\n";

} print "Entrer un motif à rechercher : "; chomp ($motif = <STDIN>);

} exit;

Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

L’instruction do {} while

L’instruction do {} until

Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

L’instruction foreach I

L’instruction foreach II


I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Compter le nombre d’occurrence de chacune des bases

# d’une séquence d’ADN contenue dans un fichier #

# Demandons à l’utilisateur le nom du fichier contenant la séquence

# et lisons ce nom au clavier print "Entrer le nom du fichier à ouvrir : "; $nom_fichier_adn = <STDIN>;

# Retirons le retour-charriot de la fin de la réponse chomp $nom_fichier_adn;

# Nous devons tout d’abord « ouvrir » le fichier et, dans le cas où

# l’ouverture échoue, afficher un message d’erreur et quitter le

# programme

II

unless ( open(FIC_ADN, $nom_fichier_adn) )

{ print "Impossible d’ouvrir le fichier $nom_fichier_adn!\n"; exit; }

# Nous pouvons à présent lire la séquence d’ADN depuis le

# fichier en utilisant les caractères < et > pour lire les

# informations depuis le descripteur de fichiers et la stocker dans la # variable tableau @adn.

@adn = <FIC_ADN>;

# Nous avons nos données, nous pouvons fermer le fichier close FIC_ADN;

# Placons la séquence de la protéine dans une seule cha^?ne de caractères

# Il sera plus simple de rechercher un motif dans une cha^?ne plut^ot

# que dans un tableau de lignes (que se passe-t-il si le motif est à

# cheval sur deux lignes?)

III

$adn = join(", @adn);

# Retirons les éventuels espaces

$adn =~ s/\s//g;

# Séparons à présent la séquence d’ADN en un tableau où chaque lettre

# de la cha^?ne d’origine est un élément du tableau

# Cela permettra de déterminer facilement la position de chaque base # Remarquez que nous réutilisons @adn à cet effet.

@adn = split(", $adn );

# Initialisons les compteurs.

# Remarquez que nous utilisons des variables scalaires pour conserver

# les nombres

$nbre_de_A = 0;

$nbre_de_C = 0;

$nbre_de_G = 0;

$nbre_de_T = 0;

$nbre_d_erreurs = 0;

IV

# Nous allons, dans la boucle, inspecter chaque position, déterminer quel

# est le nucléotide à cette position et incrémenter le compteur

# correspondant foreach $base (@adn)

{

if ( $base eq ’A’ )

{

++$nbre_de_A;

}

elsif ( $base eq ’C’ )

{

++$nbre_de_C;

}

elsif ( $base eq ’G’ )

{

++$nbre_de_G;

}

elsif ( $base eq ’T’ )

V

{

++$nbre_de_T;

} else { print "!!!!!!!! Erreur - Je ne reconnais pas cette base : $base\n";

++$nbre_d_erreurs;

}

}

# Affichons les résultats print "A = $nbre_de_A\n"; print "C = $nbre_de_C\n"; print "G = $nbre_de_G\n"; print "T = $nbre_de_T\n"; print "Erreurs = $nbre_d_erreurs\n";

# Fin explicite exit;


Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

Gestion interne des nombres et chaˆ?nes I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Démonstration de la gestion interne des nombres et des

# cha^?nes en Perl #

$nombre = 1234;

$chaine = ’1234’;

# Affichons les valeurs des variables nombre et chaine print $nombre, " ", $chaine, "\n";

# Additionnons les variables en tant que nombres

$nombre_ou_chaine = $nombre + $chaine;

Gestion interne des nombres et chaˆ?nes II

print $nombre_ou_chaine, "\n";

# Concaténons les variables en tant que cha^?nes $nombre_ou_chaine = $nombre . $chaine;

print $nombre_ou_chaine, "\n";

exit;

Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

L’instruction for I

L’instruction for II


I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Compter le nombre d’occurrence de chacune des bases # d’une séquence d’ADN contenue dans un fichier.

# Deuxième essai.

#

# Demandons à l’utilisateur le nom du fichier contenant la séquence

# et récupérons ce nom print "Entrer le nom du fichier à ouvrir : "; $nom_fichier_adn = <STDIN>;

# Retirons le retour-chariot de la fin de la réponse chomp $nom_fichier_adn;

# Testons si le fichier existe unless ( -e $nom_fichier_adn)

II

{ print "Le fichier \"$nom_fichier_adn\" semble ne pas exister!!\n"; exit;

}

# Nous devons tout d’abord « ouvrir » le fichier et, dans le cas où

# l’ouverture échoue, afficher un message d’erreur et quitter le

# programme unless ( open(FIC_ADN, $nom_fichier_adn) )

{ print "Impossible d’ouvrir le fichier $nom_fichier_adn!\n"; exit; }

@adn = <FIC_ADN>;

close FIC_ADN;

$adn = join( ", @adn);

III

# Retirons les espacements

$adn =~ s/\s//g;

# Initialisons les compteurs.

# Remarquez que nous utilisons des variables scalaires pour conserver

# les nombres

$compteur_A = 0;

$compteur_C = 0;

$compteur_G = 0;

$compteur_T = 0;

$compteur_erreurs = 0;

# Nous allons, dans la boucle, inspecter chaque position, déterminer quel

# est le nucléotide à cette position et incrémenter le compteur

# correspondant for ( $position = 0; $position < length $adn; ++$position )

{

$base = substr($adn, $position, 1); if ( $base eq ’A’ )


IV

{

++$compteur_A;

}

elsif ( $base eq ’C’ )

{

++$compteur_C;

}

elsif ( $base eq ’G’ )

{

++$compteur_G;

}

elsif ( $base eq ’T’ )

{

++$compteur_T;

} else { print "!!!!!!!! Erreur - Je ne reconnais pas cette base : $base\n";

++$compteur_erreurs;

}

V

}

# Affichons les résultats print "A = $compteur_A\n"; print "C = $compteur_C\n"; print "G = $compteur_G\n"; print "T = $compteur_T\n"; print "Erreurs = $compteur_erreurs\n";

# Fin explicite exit;

Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse


I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Compter le nombre d’occurrence de chacune des bases # d’une séquence d’ADN contenue dans un fichier.

# Troisième essai.

#

# Demandons à l’utilisateur le nom du fichier contenant la séquence

# et récupérons ce nom print "Entrer le nom du fichier à ouvrir : "; $nom_fichier_adn = <STDIN>;

# Retirons le retour-charriot de la fin de la réponse chomp $nom_fichier_adn;

# Testons si le fichier existe unless ( -e $nom_fichier_adn)

II

{ print "Le fichier \"$nom_fichier_adn\" semble ne pas exister!!\n"; exit;

}

# Nous devons tout d’abord « ouvrir » le fichier et, dans le cas où

# l’ouverture échoue, afficher un message d’erreur et quitter le

# programme unless ( open(FIC_ADN, $nom_fichier_adn) )

{ print "Impossible d’ouvrir le fichier $nom_fichier_adn!\n"; exit; }

@adn = <FIC_ADN>;

close FIC_ADN;

$adn = join( ", @adn);

III

$adn =~ s/\s//g;

# Initialisons les compteurs.

# Remarquez que nous utilisons des variables scalaires pour conserver

# les nombres

$a = 0; $c = 0; $g = 0; $t = 0; $e = 0;

# Utilisons les expressions régulières pour faire cinq boucles et # trouver le nombre d’occurrences de chacune des bases et les erreurs while ( $adn =~ /a/ig ) { $a++ } while ( $adn =~ /c/ig ) { $c++ } while ( $adn =~ /g/ig ) { $g++ } while ( $adn =~ /t/ig ) { $t++ } while ( $adn =~ /[^acgt]/ig ) { $e++ }

print "A=$a C=$c G=$g T=$t Erreurs=$e\n";

# Affichons le résultat de nos recherches dans le fichier nommé « compte_bases »

IV

$fic_sortie = "compte_bases";

unless ( open(COMPTE_BASES, ">$fic_sortie") )

{ print "Impossible d’ouvrir le fichier \"$fic_sortie\" en sortie!!\n\n"; exit; }

print COMPTE_BASES "A=$a C=$c G=$g T=$t Erreurs=$e\n";

close(COMPTE_BASES);

# Fin explicite exit;


Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

I

1   Utilisez une boucle pour écrire un programme qui s’exécute sans fin. Le test doit être évalué à vrai à chaque tour de boucle. Remarquez que certains systèmes vont se rendre compte que vous êtes dans une boucle infinie et stopper le programme automatiquement. La fa¸con de terminer le programme dépend de votre système d’exploitation : <Ctrl><C> sous Unix et Linux, en mode commandes MS-DOS sous Windows et dans une fenêtre shell de Mac OS X.

2   Demandez à l’utilisateur d’entrer deux (courtes) séquences d’ADN. Concaténez les deux séquences ADN en ajoutant la seconde à la fin de la première à l’aide de l’opérateur d’affectation .=. Affichez ensuite les deux séquences concaténées, ainsi que la seconde séquence en l’alignant sur la fin des séquences concaténées. Par exemple, si les séquences sont AAAA et TTTT, la sortie sera :

AAAATTTT TTTT

II

3   Ecrivez un programme qui affiche tous les nombres de 1 à 100. Le´ nombre de lignes de votre programme devra être inférieur à 100!

4   Ecrivez un programme qui calcule le complément inverse d’un brin´ d’ADN sans utiliser les commandes s/// ou tr///. Utilisez la fonction substr et examinez les bases une par une dans une variable originelle pendant que vous construirez le complément inverse (astuce : il est plus facile d’examiner la séquence d’origine de droite à gauche plutôt que de gauche à droite, même si les deux sens de parcours sont possibles).

5   Ecrivez un programme qui affiche le pourcentage d’acides aminés´ hydrophobes dans une séquence de protéines.

6   Ecrivez un programme qui teste si deux chaˆ?nes données en arguments´ sont les compléments inverses l’une de l’autre. Utilisez les fonctions Perl intégrées split, pop, shift et l’opérateur de comparaison eq.

7   Ecrivez un programme qui affiche le pourcentage de GC d’une´ séquence ADN.

III

8   Modifiez l’exercice pour trouver non seulement les motifs désignés par les expressions régulières mais également afficher le motif qui a été trouvé. Par exemple, si vous cherchez (en utilisant une expression régulière) le motif EE.*EE, votre programme devra afficher EETVKNDEE. Vous pouvez utiliser la variable spéciale $&. Après une recherche de motif réussie, cette variable spéciale contient le motif qui correspond à votre recherche.

9   Ecrivez un programme qui échange deux bases dans une séquence´ d’ADN à des positions spécifiées (astuce : vous pouvez utiliser les fonctions Perl substr et splice).

10    Ecrivez un programme qui crée un fichier temporaire, le remplit de´ données, puis le supprime. La fonction unlink supprime le fichier, par exemple :

unlink "fic_tempo"; et teste si la fonction unlink s’est exécutée correctement.


Plan

12  Contrôle du flux du programme

13  Formattage du code

14  Recherche de motifs

15  Boucle while

16  Boucles do while/until

17  Boucle foreach

18  Gestion interne des nombres et chaˆ?nes

19  Boucle for

20  Ecriture dans les fichiers´

21  Exercices

22  Synthèse

Synthèse

Vous devriez maintenant être capable de : rechercher des motifs dans des séquences d’ADN ou de protéines;

écrire un programme interactif; écrire des données dans des fichiers; utiliser des boucles; utiliser des expressions régulières élémentaires effectuer différentes actions en fonction de tests conditionnels; examiner les données de séquence en détail en utilisant des chaˆ?nes de caractères et des tableaux.

Quatrième partie IV Sous-programmes (2009)

Plan

23  Sous-programmes

24  Portée et sous-programmes

25  Arguments de la ligne de commande et tableaux

26  Transmission de données aux sous-programmes

27  Modules et bibliothèques de sous-programmes

28  Correction de bogues

29  Exercices

30  Synthèse

Sous-programmes

Un sous programme est un morceau de code qui peut-etre considéré comme un programme dans le programme son utilisation ou son invocation est couramment dénommé « appel du sous-programme » on lui attribue un nom grace auquel le programme peut l’appeler on peut lui transmettre des données qu’il doit traiter une fois son exécution terminée, le sous-programme retourne les résultats au programme principal qui peut alors reprendre son cours sous programme = petite portion de code qui exécute une tache bien définie

Il peut etre utilisé plusieurs fois dans un meme programme ou dans des programmes différents

Avantages des sous-programmes

 Les sous programmes permettent d’écrire un programme :

I plus court

I plus rapide à écrire

I plus facile à comprendre

I plus réutilisable

I plus évolutif

I plus facile à tester

I plus fiable


I

 Exemple de sous-programme devant ajouter ACGT à une séquence d’ADN :

I appel : ajouter_ACGT($adn);

I la valeur de retour est récupéré dans le programme

 Dans les versions anciennes de Perl, il fallait précéder le nom de l’appel par le caractère &. Il est toujours possible de la faire.

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall



# But du programme : Un programme contenant un sous-programme permettant

# d’ajouter ACGT à une séquence d’ADN

# La cha^?ne d’ADN d’origine

$adn = ’CGACGTCTTCTC’;

II

# Appel au sous-programme ajouter_ACGT

# Un argument qui est transmis à la fonction est stocké dans

$adn, la

# valeur retournée par la fonction est stocké dans adn_etendu

$adn_etendu = ajouter_ACGT($adn); print "J’ai ajouté ACGT à $adn pour obtenir $adn_etendu\n\n"; exit;

#################################################################### #

# Sous-programmes pour l’exemple 6-1

#

# nom du sous-programme : ajouter_ACGT

# but du sous-programme : ajouter ACGT à la cha^?ne passée en argument

# nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères

# sub ajouter_ACGT

III

{

# Récupérons l’argument passé au sous-programme my($adn) = @_;

# Concaténons ACGT à la variable $adn existante. équivalent à :

# $adn = $adn . ’ACGT’;

$adn .= ’ACGT’;

# Retournons la cha^?ne étendue return $adn;

}

# Fin des sous-programmes

#

####################################################################


Plan

23  Sous-programmes

24  Portée et sous-programmes

25  Arguments de la ligne de commande et tableaux

26  Transmission de données aux sous-programmes

27  Modules et bibliothèques de sous-programmes

28  Correction de bogues

29  Exercices

30  Synthèse

I

la portée d’une variable correspond à la zone de visibilité de la variable dans le programme

Pour limiter la portée d’une variable dans un sous-programme on utiliser la déclaration my

my($x) ou my $x

 Illustration des pièges lorsque l’on n’utilise pas my :

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Illustrer les pièges rencontrés lorsque nous n’utilisons

# pas les variables my

$adn = ’AAAAA’;

$resultat = A_en_T($adn);

II

print "J’ai changé tous les A en T dans $adn et voilà le résultat : "; print "$resultat\n\n"; exit;

#################################################################### #

# Sous-programme pour l’exemple 6-2

#

# nom du sous-programme : A_en_T

# but du sous-programme : changer tous les A en T dans la cha^?ne passée

# en argument

# nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères

# sub A_en_T

{ my($entree) = @_;

III

$adn = $entree;

$adn =~ s/A/T/g; return $adn;

}

# Fin du sous-programme

#

####################################################################


Plan

23  Sous-programmes

24  Portée et sous-programmes

25  Arguments de la ligne de commande et tableaux

26  Transmission de données aux sous-programmes

27  Modules et bibliothèques de sous-programmes

28  Correction de bogues

29  Exercices

30  Synthèse

I

#! /usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Compter le nombre de G présents dans une squence d’ADN passée en argument au programme principal

# use strict;

# Récuprons la séquence d’ADN passe en argument sur la ligne de # commandes (lors de l’appel du programme).

# Si aucun argument n’est donné, afficher une aide et terminer. # $0 est une variable spciale qui contient le nom du programme my($USAGE) = "USAGE : $0 fragment_ADN\n\n";

# @ARGV est un tableau contenant tous les arguments de la ligne

# de commande. S’il est vide, le test va échouer et afficher le # contenu de la variable USAGE et terminer le programme.

unless ( @ARGV )

{

II

print $USAGE; exit;

}

# Lisons la squence d’ADN partir de la ligne de commande my($adn) = $ARGV[0];

# Appelons le sous-programme qui effectue le vrai travail et récupère le résultat my($nombre_de_G) = compter_G( $adn );

# Affichons le résultat print "\nLa squence d’ADN $adn possède $nombre_de_G G!\n\n"; exit;

#################################################################### #

# Sous-programme pour l’exemple 6-3 #

# nom du sous-programme : compter_G

# but du sous-programme : compter le nombre de G présents dans la chaine passée en argument

III

# nombre d’arguments : 1

# nature de l’argument : chaine de caractères

# sub compter_G

{

# Initialisons les arguments et les variables my($adn) = @_; my($compte) = 0;

# Utiliser la quatrième méthode pour compter les nucléotides comme cela a été présent dans le chapitre Motifs et boucles

$compte = ( $adn =~ tr/Gg// ); return $compte;

}

# Fin du sous-programme

#

####################################################################


Plan

23  Sous-programmes

24  Portée et sous-programmes

25  Arguments de la ligne de commande et tableaux

26  Transmission de données aux sous-programmes

27  Modules et bibliothèques de sous-programmes

28  Correction de bogues

29  Exercices

30  Synthèse

Passage par valeur

les valeurs des arguments sont copiées et transmises aux ss-pg sans que cela les affecte dans le pg principal.

Perl transmet la valeur des arguments au ss-pg dans le tableau @ Exemple :

my $i = 2; print "dans le pg principal, avant appel : \$i vaut $i\n " sous_pg($i); print "dans le pg principal, après appel : \$i vaut $i\n " exit;

;ajouter_ACGT($adn);

# sous_pg sub sous_pg { my($i) = @_; $i += 100; print "dans le sous-pg : \$i vaut $i\n "

}

Passage par référence

Les variables transmises sont modifiées par le sous pg et les modif. retransmises au prog. Pricipal.

Perl transmet le nom des arguments au ss-pg dans le tableau @ Exemple :

my @i = (‘1’, ‘2’, ‘3’); my @j = (‘a’, ‘b’, ‘c’); print "dans le pg principal, avant appel : \$i vaut @i\n" print "dans le pg principal, avant appel : \$j vaut @j\n" sous_pg_ref(\@i, \@j); print "dans le pg principal, après appel : \$i vaut @i\n" print "dans le pg principal, après appel : \$j vaut @j\n" exit; sub sous_pg_ref { my($i, $j) = @_; print "dans le sous-pg : \$i vaut @$i\n "; print "dans le sous-pg : \$j vaut @$j\n "; push(@$i, ‘4’); shift(@$j);

}

Plan

23  Sous-programmes

24  Portée et sous-programmes

25  Arguments de la ligne de commande et tableaux

26  Transmission de données aux sous-programmes

27  Modules et bibliothèques de sous-programmes

28  Correction de bogues

29  Exercices

30  Synthèse

Modules et bibliothèques de sous-programmes

Regrouper des sous-pg dans des fichiers .pm (exemple : use IntroPerlBioinfo;)

Insérer à la fin : 1; (pour indiquer qu’il n’y a pas eu d’erreur et renvoyer une valeur différente de la valeur false)

Insérer au début du pg : use NomModule1;

Insérer avant éventuellement : use /home/monrep/TP;

Plan

23  Sous-programmes

24  Portée et sous-programmes

25  Arguments de la ligne de commande et tableaux

26  Transmission de données aux sous-programmes

27  Modules et bibliothèques de sous-programmes

28  Correction de bogues

29  Exercices

30  Synthèse

Correction de bogues

 Ajout de directives Perl pour améliorer les controles :

I use warning;

I use strict;

 Activer les avertissements :

I en début de programme :

#! /usr/bin/perl -w

(-w : active les avertissements) I ou bien en indiquant : use warning;

(permet d’activer les avertissements)

 En utilisant des commentaires (pour isoler des portions de codes problématiques) et en utilisant l’instruction print (pour afficher le contenu de variables)

 En utilisant le debogueur

Utilisation du débogueur

Le débogueur permet de résoudre des cas difficiles à cerner.

Lancement :

$ perl -d

I -d pour activer le mode debug

I q : quitter

I demander l’aide : h

I demander l’aide en résumé : h h

Progresser dans les instructions

 Le débogueur indique la ligne qu’il est sur le point d’exécuter : DB

<n ligne> afficher des valeurs p $adn afficher la variable $ ou @ p exécuter une instruction s (step) ou n (next) évite d’entrer dans un ss-pg réexécuter la même commande « entrée » afficher plusieurs instructions w (window) placer un point d’arrêt b numéro ligne continuer jusqu’au point d’arrêt c supprimer tous les points d’arrêt D indiquer si une variable est modifiée W $Nom var

Plan

23  Sous-programmes

24  Portée et sous-programmes

25  Arguments de la ligne de commande et tableaux

26  Transmission de données aux sous-programmes

27  Modules et bibliothèques de sous-programmes

28  Correction de bogues

29  Exercices

30  Synthèse


I

1   Ecrivez un sous-programme quiconcatène deux séquences ADN.´

2   Ecrivez un sous-programme qui retourne le pourcentage de chacune´ des bases dans une séquence ADN. Vous avez vu l’opérateur addition

+, vous pourriez également avoir besoin des opérateurs de multiplication * et de division /. Comptez le nombre de chacune des bases, divisez par la longueur totale de la séquence ADN, puis multipliez par 100 pour obtenir le pourcentage. Vos arguments devront etre la séquence ADN et le nucléotide sur lequel porte votre calcul. La fonction int peut etre utilisée pour supprimer la partie décimale, au besoin.

3   Ecrivez un sous-programme demandant à un utilisateur un message´ quelconque et récupérez la réponse de l’utilisateur. L’argument du sous-programme devra etre le message et la valeur retournée devra etre la réponse (sur une ligne).

II

4   Ecrivez un sous-programme qui examine les arguments de la ligne de´ commandetels que -help, -h et –help. Rappelez-vous que les arguments sont accessibles dans le tableau @ARGV. Appeler le sous-programme a partir du programme principal. Si vous donnez au programme un des arguments nommés, vous les transmettrez au sous-programme qui devra retourner une valeur vraie. Si c’est le cas, le message devra afficher un message d’aide stocké dans une variable $USAGE et quitter le programme.

5   Ecrivez un sous-programme qui teste l’existence d’un fichier, puis qui´ détermine de quel type de fichier il s’agit et enfin qui vérifie qu’il n’est pas vide. Utilisez pour cela les tests d’opérateurs sur les fichiers.

6   Utilisez l’exercice 3 dans un sous-programme qui repose la question jusqu’à ce qu’un nom de fichier valide soit entré par l’utilisateur ou s’arrete après cinq échecs.’

III

7   Ecrivez un module dont les sous-programmes retournent diverses´ statistiques sur les séquences d’ADN, par exemple la longueur, le contenu en GC, la présence ou l’absence de séquences poly-T (longs fragments ne contenant presque que des T apparaissant à l’extrémité 5’ de nombreuses séquences d’ADN) et d’autres mesures qui vous sempleraient intéressantes.

8   Lisez la documentation du débogueur et familiarisez-vous avec son utilisation pendant le développement de vos programmes.

9   Ecrivez un sous-programme qui modifie un tableau de lignes´ provenant d’un fichier. Utilisez le passage par référence pour le tableau, une expression régulière et une chaine de caractèrespour remplacer l’expression régulière. Toules les lignes du tableau devront etre modifiées en substituant les occurences de l’expression régulière par la chaine de caractères de remplacement.


Plan

23  Sous-programmes

24  Portée et sous-programmes

25  Arguments de la ligne de commande et tableaux

26  Transmission de données aux sous-programmes

27  Modules et bibliothèques de sous-programmes

28  Correction de bogues

29  Exercices

30  Synthèse

Synthèse

 Dans ce chapitre vous avez abordé deux concepts :

I les sous-programmes : jouent un role prépondérant dans la structuration des programmes.

I le débogueur Perl : il permet d’examiner l’exécution des programmes « au ralenti » et aide à localiser les bogues.

Cinquième partie V Mutations et nombres aléatoires (2010)

Mutations et nombres aléatoires I

Mutations

Modifications ponctuelle de l’ADN : insertion, délétion ou remplacement d’un très petit nombre de bases contigues¨ modifications de longs segments d’ADN comme certains réarangements chromosomiques (duplication, translocation) résultant d’échange de fragments entre chromosomes.

Les mutations survenant dans les séquences d’ADN peuvent être causées par :

des radiations des agents chimiques des erreurs de réplication ou d’autres facteurs

Mutations et nombres aléatoires II

Elles se produisent fréquemment dans les cellules. Heureusement le faible pourcentage d’ADN codant, la dégénérescence du code génétique et des mécanismes cellulaires de réparation de l’ADN font que les mutations ponctuelles sont souvent sans effet pour l’expression des gènes et pour l’individu. Cependant, certaines mutations, mêmes infimes, peuvent avoir des conséquences dramatiques et conduire au développement de pathologies comme des cancers ou des maladies génétiques transmissibles à la descendance.

Plan

31  Générateurs de nombres aléatoires

32  Un programme qui utilise les nombres aléatoires

33  Un programme pour simuler les mutations dans les séquences ADN

34  Générer une séquence d’ADN aléatoire

35  Analyse d’une séquence d’ADN

36  Synthèse


Génération de nombres aléatoires

Génération de nombres aléatoires

Technique informatique présente dans un grand nombre de programmes utilisés quotidiennement, par exemple en cryptograhie, afin de générer un mot de passe difficile à deviner.

En bioinformatique :

modéliser et rechercher des mécanismes de mutation des séquences

ADN

rechercher les effets des mutations sur l’activité biologique des protéines correspondantes

simuler le « désordre organisé » d’un système biologique

La simulation est un outil puissant indispensable à l’étude des systèmes et à la prédiction de leur comportements.

La capacité de simuler des mutations à l’aide de programmes informatiques peut aider à l’étude de l’évolution, des maladies et des processus cellulaires de base comme le mécanisme de division ou de réparation de l’ADN.

Générateurs de nombres aléatoires

Nombres pseudo-aléatoires

La génération de nombres aléatoires se fait par l’appel d’une fonction spécialisée de Perl.

Les valleurs fournies peuvent être différentes de celles que nous pourrions obtenir en observant des événements aléatoires réels

Ce ne sont donc pas réellement des nombres aléatoires : on les appelle des nombres pseudo-aléatoires

Un générateur de nombres aléatoire est prévisible car il s’agit d’un algorithme

Le germe à partir duquel sont générés les nombres aléatoires doit lui-même être le plus aléatoire possible

On utilise pour cela un nombre qui dépend du système d’exploitation et qui varie de fa¸con erratique au cours du temps (par exemple le numéro de processus de votre programme)

Plan

31  Générateurs de nombres aléatoires

32  Un programme qui utilise les nombres aléatoires

33  Un programme pour simuler les mutations dans les séquences ADN

34  Générer une séquence d’ADN aléatoire

35  Analyse d’une séquence d’ADN

36  Synthèse


I

Le programme ci-dessous introduit des nombres aléatoires à partir d’un programme simple : il combine au hasard des portions de phrases pour construire une histoire.

#!/usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Un jeu d’enfants, qui utilise un générateur

# de nombres aléatoires pour sélectionner différentes

# parties d’une phrase

# use strict; use warnings;

# Déclarons les variables my $compte; my $entree; my $nombre;

II

my $phrase; my $histoire;

# Les tableaux contenant les éléments de base d’une phrase my @noms =

(

’Papa’,

’Maman’,

’Groucho’,

’Chico’,

’Harpo’,

’Laurel’,

’Hardy’,

’Charlot’, );

my @verbes =

(

’court vers’,

’danse avec’,

III

’saute par dessus’,

’chante des chansons stupides avec’,

’verse de la sauce pimentée dans le jus d\’orange de’,

’conduit la voiture de’,

);

my @prepositions =

(

’dans un magasin’,

’sur l\’arc en ciel’,

’pour le plaisir’,

’à la plage’,

’avant le diner’,

’à Paris’,

’dans un r^eve’,

’autour du monde’, );

# Initialisons le générateur de nombres aléatoires avec la fonction srand

IV

# time|$$ combine l’heure courante avec l’identificateur du processus courant.

# Cette méthode est classique et le germe peut donc ^etre facilement deviné

# par un pirate habile srand( time | $$ );

# Cette boucle do until construit une histoire en six phrases

# jusqu’à ce que l’utilisateur entre « quitter » do

{

# (Ré)Initialisons la variable $histoire à la cha^?ne vide

$histoire = ";

# Construisons une histoire en six phrases for ( $compte = 0; $compte < 6; $compte++ )

{

# Remarques sur les instructions suivantes :

# 1) scalar @tableau retourne le nombre d’éléments du tableau,

# 2) rand retourne un nombre aléatoire supérieur à

# 0 et inférieur à scalar @tableau,

V

# 3) int retire la partie décimale d’un nombre, # 4) . concatène des cha^?nes de caractères.

$phrase = $noms[int(rand(scalar @noms))] . " " . $verbes[int(rand(scalar @verbes))]

. " " . $noms[int(rand(scalar @noms))]

. " " . $prepositions[int(rand(scalar @prepositions))] . ’. ’; $histoire .= "$phrase\n";

}

# Affichons l’histoire print "\n",$histoire;

# Demandons à l’utilisateur ce qu’il veut faire print "\nEntrer \"quitter\", ou « Entrée » pour continuer : ";

$entree = <STDIN>;

# Sortons de la boucle si l’utilisateur le désire

} until ( $entree =~ /^\s*q/i );

exit;


Initialisation du générateur time|$$ : germe different à chaque appel du programme (time :

représentant de l’heure combiné avec un OU logique à $$ : numéro de processus)

Plan

31  Générateurs de nombres aléatoires

32  Un programme qui utilise les nombres aléatoires

33  Un programme pour simuler les mutations dans les séquences ADN

34  Générer une séquence d’ADN aléatoire

35  Analyse d’une séquence d’ADN

36  Synthèse

Un programme pour simuler les mutations dans les séquences ADN

L’exemple précédent nous a procuré mes outils dont nous aurons besoin pour les séquences d’ADN.

Dans les exemples qui suivent, une séquence d’ADN sera une chaine de caractères con,stitués de A, C, G et T

Nous allons sélectionner au hasard les positions dans la chaˆ?ne et utiliser la fonction substr pour modifier le contenu de la séquence d’ADN

 Commen¸cons par écrire quelsques sous-programmes qui pourront être utiles par la suite.

Conception d’un pseudo code

Commencons par écrire un pseudo-code simple décrivant un sous-programme qui accepte une séquence d’ADN et échange, pour une position aléatoire, un nucléotide par un autre :

1   sélectionner au hasard une position dans la séquence d’ADN

2   sélectionner au hasard un nucléotide

3   placer ce nucléotide à la position précédemment trouvée.

Selectionner une position aléatoire dans la séquence ADN

# nom du sous-programme : position_hasard

# but du sous-programme : tirer au hasard une position dans une cha^?ne de

#                                                  caracte`res

# nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères sub position_hasard

{ my($chaine) = @_;

# Décomposons la valeur retournée

#

# $chaine : la cha?^ne de caractères

# length $chaine : la longueur de la cha^?ne de caractères

# rand length $chaine : un nombre décimal aléatoire entre 0 et la longueur

     #                                               de la cha^?ne de caracte`res

# int rand length $chaine : la partie entière du nombre aléatoire #

# la totalité de l’expression retourne un entier aléatoire entre 0 et la longueur de la cha^?ne de caracte`res, qui déterminera la position ou` la mutation va appara?^tre

return int rand length $chaine;

}

Sélectionner un nucléotide aléatoire

# nom du sous-programme : nucleotide_hasard

# but du sous-programme : tirer au hasard un des quatre nucle´otides

# nombre d’arguments : 0

# sub nucleotide_hasard

{ my(@nucleotides) = (’A’, ’C’, ’G’, ’T’); return element_hasard(@nucleotides);

}

#

# nom du sous-programme : position_hasard

# but du sous-programme : tirer au hasard une position dans une

# cha?^ne de caractères

# nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères

Placer le nucléotide aléatoire à la position aléatoire

# nom du sous-programme : mutation

# but du sous-programme : effectuer une mutation dans la cha^?ne de caracte`res

# nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères sub mutation

{ my($adn) = @_; my(@nucleotides) = (’A’, ’C’, ’G’, ’T’); # Tirons au hasard une position dans la se´quence my($position) = position_hasard($adn); # Tirons au hasard un nucléotide my($nouv_base) = nucleotide_hasard();

# Inse´rons le nucléotide tiré à la position tireé dans la se´quence # Les arguments de la commande substr correspondent à :

# dans la cha^?ne « adn », a` la « position », e´changer « 1 » lettre # par le contenu de la cha?^ne « nouv_base ». substr($adn,$position,1,$nouv_base); return $adn;

}

Combiner les sous-programmes I

#! /usr/bin/perl

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Effectuer des mutations utilisant un ge´ne´rateur de nombres # aléatoires pour se´lectionner les bases qui vont muter.

# use strict; use warnings;

# Déclarons les variables

# La se´quence d’ADN est ici choisie de fa¸con à repe´rer facilement les mutations my $ADN = ’AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA’;

# La variable $i est souvent utilisé comme compteur de variable (i vient de # l’anglais integer, qui signifie entier. C’est une vieille re´miniscence # du langage FORTRAN).

my $i; my $mutant;

# Initialisons le générateur de nombres aléatoires

# time|$$ combine l’heure et l’identificateur du processus srand(time|$$);

# Testons notre ensemble de sous-programmes

$mutant = mutation($ADN); print "\nMutation ADN\n";

Combiner les sous-programmes II

print "\nVoici la séquence d’ADN d’origine :\n\n"; print "$ADN\n"; print "\nVoici la séquence d’ADN après mutation :\n\n"; print "$mutant\n";

# Créons maintenant une boucle pour observer la fac¸on dont la

# séquence accumule des mutations print "\nVoici dix mutations successives :\n\n"; for ( $i=0; $i < 10; ++$i )

{

$mutant = mutation($mutant); print "$mutant\n";

} exit;

Plan

31  Générateurs de nombres aléatoires

32  Un programme qui utilise les nombres aléatoires

33  Un programme pour simuler les mutations dans les séquences ADN

34  Générer une séquence d’ADN aléatoire

35  Analyse d’une séquence d’ADN

36  Synthèse

Générer une séquence d’ADN aléatoire

 Les statisticiens ont souvent recours à la génération de données aléatoires afinde comparer un phénomène réel avec des données de même type mais « aléatoires »

On peut alors en déduire la probabilité avec laquelle le phénomène observé n’est pas duˆ au hasard

Nous allons créer un ensemble de fragments aléatoires d’ADN de longueurs variables. Le programme devra tenir compte de plusieurs paramètres : la longueur minimale, la longueur maximale et le nombre de fragments à créer.


I

#! /usr/bin/perl

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Utiliser un ge´ne´rateur de nombres ale´atoires pour # tirer des bases au hasard.

# use strict; use warnings;

# Déclarons et initialisons les variables my $taille_ensemble = 12; my $longueur_max = 30; my $longueur_min = 15;

# Un tableau, initialisé à la liste vide, permettant de stocker les

# séquences d’ADN my @ADN_hasard = ( );

# Initialisons le générateur de nombres aléatoires

# time|$$ combine l’heure et l’identificateur du processus srand(time|$$);

# Voici l’appel du sous-programme qui fait tout le travail

@ADN_hasard = ensemble_ADN_hasard( $longueur_min,

$longueur_max,

$taille_ensemble );

II

# Affichons les re´sultats, un par ligne print "Voici un tableau de $taille_ensemble séquences d’ADN "; print "avec des longueurs comprises au hasard entre "; print "$longueur_min et $longueur_max :\n\n"; foreach my $adn (@ADN_hasard)

{ print "$adn\n";

} print "\n"; exit;

########################################################################## #

# Sous-programmes pour l’exemple 7-3

#

# Nous avons plusieurs sous-programmes, que nous allons indiquer

# par ordre alphabétique

# ATTENTION : il faut absolument appeler la fonction srand pour initialiser # le ge´nérateur de nombres aléatoires avant d’appeler une de ces fonctions.

#

# nom du sous-programme : ensemble_ADN_hasard

# but du sous-programme : construire un ensemble de séquences d’ADN

# aléatoires

# nombre d’arguments : 3

III

# nature des arguments : entier longueur_min des séquences

# entier longueur_max des séquences

# entier nombre_sequences dans l’ensemble

# sub ensemble_ADN_hasard

{

# Récupérons les arguments my($longueur_min, $longueur_max, $nombre_sequences) = @_;

# longueur de chacune des séquences my $longueur; # séquence d’ADN my $adn;

# ensemble de séquences d’ADN my @ensemble;

# Créons un ensemble de séquences aléatoires for ( my $i = 0; $i < $nombre_sequences; ++$i )

{

# tirons au hasard une longueur entre les valeurs minimales et

# maximales

$longueur = longueur_hasard ($longueur_min, $longueur_max);

# construisons la séquence d’ADN aléatoire

$adn = sequence_ADN_hasard ( $longueur );

# ajoutons la séquence $adn a` @ensemble

IV

push( @ensemble, $adn );

} return @ensemble;

}

# Nous venons d’ajouter un nouveau sous-programme dont nous avons

# besoin : longueur_hasard, qui retournera un nombre compris

# entre une valeur minimale et une valeur maximale

#

# nom du sous-programme : longueur_hasard

# but du sous-programme : retourner une valeur aléatoire entre les

# valeurs minimales et maximales

# nombre d’arguments : 2

# nature des arguments : entier longueur_min

# entier longueur_max

# sub longueur_hasard { # Récupérons les arguments my($longueur_min, $longueur_max) = @_;

# Calculons et retournons un nombre aléatoire dans l’intervalle désire´.

# La fonction rand retourne un nombre ale´atoire compris entre 0 et son # argument. Nous ne pouvons utiliser rand ($longueur_max) car cela ne

# respecterait pas la borne inférieure $longueur_min. L’intervalle que # nous désirons se situe entre 0 et ($longueur_max - $longueur_min). à

V

# la valeur ale´atoire située dans cet intervalle, nous devons ensuite # ajouter $longueur_min pour obtenir la longueur de la séquence.

return int ( rand ($longueur_max - $longueur_min + 1) + $longueur_min );

}

#

# nom du sous-programme : sequence_ADN_hasard

# but du sous-programme : retourner une séquence d’ADN de longueur donnée

# nombre d’arguments : 1

# nature de l’argument : entier longueur

# sub sequence_ADN_hasard

{

# Récuperons les arguments my($longueur) = @_; my $adn; for ( my $i=0; $i < $longueur; ++$i )

{

$adn .= nucleotide_hasard();

} return $adn;

}

#

# nom du sous-programme : element_hasard

VI

# but du sous-programme : tirer au hasard un e´lément d’un tableau

# nombre d’arguments : 1

# nature de l’argument : un tableau

# sub element_hasard

{ my(@tableau) = @_; return $tableau[rand @tableau];

}

#

# nom du sous-programme : nucleotide_hasard

# but du sous-programme : tirer au hasard un des quatre nucle´otides

# nombre d’arguments : 0

# sub nucleotide_hasard

{ my(@nucleotides) = (’A’, ’C’, ’G’, ’T’); return element_hasard(@nucleotides);

}


Plan

31  Générateurs de nombres aléatoires

32  Un programme qui utilise les nombres aléatoires

33  Un programme pour simuler les mutations dans les séquences ADN

34  Générer une séquence d’ADN aléatoire

35  Analyse d’une séquence d’ADN

36  Synthèse

Analyse d’une séquence d’ADN I

 Calcul de quelques statistiques sur les séquences ADN pour répondre à la question « en moyenne, quel est le pourcentage de bases identiques entre deux séquences aléatoires? »

 Générons un ensemble de séquences aléatoires d’ADN, toutes de même longueur, puis posons-nous la question suivante : « Quel est le pourcentage moyen de positions identiques dans les paires de séquences d’ADN de cet ensemble? »

Algorithme

générer un ensemble de séquences aléatoires d’ADN, de même longueur pour chaque paire de séquences d’ADN faire quelle est la proportion de séquences identiques entre les deux séquences

de la paire?

fin pour retourner la moyenne des calculs précédents sous forme de pourcentage

Analyse d’une séquence d’ADN II

Nous pouvons réaliser un programme de comparaison en nous basant sur l’analyse de chacune des bases d’une séquence ADN

Ecrivons un algorithme pour comparer chaque nucléotide d’une séquence avec le nucléotide situé à la même position de l’autre séquence


I

#! /usr/bin/perl

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Calculer les pourcentages moyens de positions identiques

# entre deux se´quences d’ADN dans un ensemble de dix

# séquences

# use strict; use warnings;

# Déclarons et initialisons les variables my $pourcentage; my @pourcentages; my $resultat;

# Un tableau, initialisé à la liste vide, permettant de stocker les

# séquences d’ADN my @ADN_hasard = ( );

# Initialisons le générateur de nombres aléatoires

# time|$$ combine l’heure et l’identificateur du processus srand(time|$$);

# Générons les dix séquences de longueur 10

@ADN_hasard = ensemble_ADN_hasard( 10, 10, 10 );

II

# Itérons dans tous les couples de se´quences for ( my $k = 0; $k < scalar @ADN_hasard - 1; ++$k )

{

for ( my $i = ($k + 1); $i < scalar @ADN_hasard; ++$i )

{

# Calculons et sauvegardons les pourcentages d’identités

$pourcentage = pourcentage_match($ADN_hasard[$k], $ADN_hasard[$i]); push(@pourcentages, $pourcentage);

}

}

# Calculons le résultat moyen :

$resultat = 0; foreach $pourcentage (@pourcentages)

{

$resultat += $pourcentage;

}

$resultat = $resultat / scalar(@pourcentages);

# Transformons resultat en un pourcentage effectif

$resultat = int ($resultat * 100); print "Lors de cette expe´rience, le pourcentage moyen de\n"; print "positions identiques est : $resultat%\n\n"; exit;

III

########################################################################## #

# Sous-programmes pour l’exemple 7-4

#

# Nous avons plusieurs sous-routine que nous allons indiquer

# par ordre alphabétique

#

# nom du sous-programme : pourcentage_match

# but du sous-programme : calculer le pourcentage de bases identiques # dans deux séquences d’ADN de me^me longueur.

# nombre d’arguments : 2

# nature des arguments : les deux cha?^nes de caracte`res à tester

# sub pourcentage_match

{ my($chaine1, $chaine2) = @_;

# Nous supposerons que les cha^?nes de caractères sont de m^eme longueur my($longueur) = length $chaine1; my($position); my($compte) = 0; for ( $position=0; $position < $longueur; ++$position )

{ if ( substr($chaine1,$position,1) eq substr($chaine2,$position,1) )

IV

{

++$compte;

} } return $compte / $longueur;

}

# ATTENTION : il faut absolument appeler la fonction srand pour initialiser # le ge´nérateur de nombres aléatoires avant d’appeler une de ces fonctions.

#

# nom du sous-programme : ensemble_ADN_hasard

# but du sous-programme : construire un ensemble de séquences d’ADN

# aléatoires

# nombre d’arguments : 3

# nature des arguments : entier longueur_min des séquences

# entier longueur_max des séquences

# entier nombre_sequences dans l’ensemble

# sub ensemble_ADN_hasard

{

# Récupérons les arguments my($longueur_min, $longueur_max, $nombre_sequences) = @_;

# longueur de chacune des séquences my $longueur;

V

# séquence d’ADN my $adn;

# ensemble de séquences d’ADN my @ensemble;

# Créons un ensemble de séquences aléatoires for ( my $i = 0; $i < $nombre_sequences; ++$i )

{

# tirons au hasard une longueur entre les valeurs minimales et

# maximales

$longueur = longueur_hasard ($longueur_min, $longueur_max);

# construisons la séquence d’ADN aléatoire

$adn = sequence_ADN_hasard ( $longueur ); # ajoutons la séquence $adn a` @ensemble push( @ensemble, $adn );

} return @ensemble;

}

# Nous venons d’ajouter un nouveau sous-programme dont nous avons

# besoin : longueur_hasard, qui retournera un nombre compris

# entre une valeur minimale et une valeur maximale

#

# nom du sous-programme : longueur_hasard

# but du sous-programme : retourner une valeur aléatoire entre les

VI

# valeurs minimales et maximales

# nombre d’arguments : 2

# nature des arguments : entier longueur_min

# entier longueur_max

# sub longueur_hasard { # Récupérons les arguments my($longueur_min, $longueur_max) = @_;

# Calculons et retournons un nombre aléatoire dans l’intervalle désire´

# Les valeurs limites doivent ^etre acceptées (d’où le + 1), nous

# calculons l’intervalle entre les bornes et nous ajoutons la borne

# infe´rieure return int ( rand ($longueur_max - $longueur_min + 1) + $longueur_min );

}

#

# nom du sous-programme : sequence_ADN_hasard

# but du sous-programme : retourner une séquence d’ADN de longueur donnée

# nombre d’arguments : 1

# nature de l’argument : entier longueur

# sub sequence_ADN_hasard

{

# Récuperons les arguments

VII

my($longueur) = @_; my $adn; for ( my $i=0; $i < $longueur; ++$i )

{

$adn .= nucleotide_hasard();

} return $adn;

}

#

# nom du sous-programme : element_hasard

# but du sous-programme : tirer au hasard un e´lément d’un tableau

# nombre d’arguments : 1

# nature de l’argument : un tableau

# sub element_hasard

{ my(@tableau) = @_; return $tableau[rand @tableau];

}

#

# nom du sous-programme : nucleotide_hasard

# but du sous-programme : tirer au hasard un des quatre nucle´otides

# nombre d’arguments : 0

VIII

# sub nucleotide_hasard

{ my(@nucleotides) = (’A’, ’C’, ’G’, ’T’);

return element_hasard(@nucleotides);

}

# Fin des sous-programmes

#

########################################################################


Plan

31  Générateurs de nombres aléatoires

32  Un programme qui utilise les nombres aléatoires

33  Un programme pour simuler les mutations dans les séquences ADN

34  Générer une séquence d’ADN aléatoire

35  Analyse d’une séquence d’ADN

36  Synthèse

Synthèse

 Dans ce chapitre vous avez abordé deux concepts :

I la sélection aléatoire d’un indice dans un tableau et d’une position dans une chaˆ?ne de caractère, ce qui permet de tirer au hasard des bases dans une séquence d’ADN (ou autre);

I la modélisation d’une mutation à l’aide de nombres aléatoires en sélectionnant aléatoirement un nucléotide dans une séquence d’ADN et en le remplac¸ant par un autre nucléotide tiré au hasard;

I l’utilisation des nombres aléatoires pour générer des ensembles de séquences d’ADN, utilisées pour étudier dans quelle mesure les séquences génomiques sont aléatoires;

I la répétition de mutations dans les séquences d’ADN afin d’étudier l’effet des mutations successives au cours de l’évolution.

I

1   Ecrivez un programme qui vous demande de choisir un acide aminé et´ tire au hasard des acides aminés jusqu’à deviner celui que vous avez choisi.

2   Ecrivez un programme qui choisit un nucléotide et tire au hasard des´ nucléotides jusqu’à deviner celui que vous avez choisi.

3   Ecrivez un sous-programme qui mélange aléatoirement les éléments´ d’un tableau. Le sous-programme doit accepter le tableau en argument et doit retourner un tableau contenant les memes arguments mais mélangés aléatoirement. Chaque élément du tableau d’origine doit apparaitre une seule fois dans le tableau final.

4   Ecrivez un programme qui simule une mutation dans une séquence de´ protéine, en s’inspirant du code de l’exemple 2 qui simule une mutation dans une séquence d’ADN.

5   Ecrivez un sous-programme qui, étant donné un codon (fragment´ d’ADN de longueur 3), retourne une mutation aléatoire dans le codon.


II

6   Certaines versions de Perl initialisent automatiquement le germe du générateur de nombes aléatories, il n’est donc plus nécessaire de faire appel à la fonction srand avant d’utiliser rand pour générer des nombres aléatoires. Vérifiez si votre version de rand appelle automatiquement la fonction srand, ou si vous devez le faire vous-meme comme cela a été le cas dans les codes de ce chapitre.

7   Ecrivez un sous-programme qui retourne aléatoirement un nucléotide,´ les probabilités des quatre nucléotides étant transmises en argument au sous-programme. Si chaque probabilité est de 0.25, le sous-programme retournera les nucléotides de fac¸on equiprobables. Il faudra s’assurer que la somme des quatre probabilités est bien égale à 1.

Indication : pour accomplir cela, vous pouvez, par exemple diviser l’intervalle [0,1] en quatre intervalles dont les longueurs correspondent aux probabilités des nucléotides respectifs. Il vous suffit alors de tirer

III

au hasard un combre entre 0 et 1, voir à quel intervalle il appartient, et retourner le nucléotide correspondant.

8      Voici un exercice plus difficile. La fonction Perl study peut accélérer les recherches de motifs dans les séquences d’ADN et de protéines. Reportez-vous à la documentation Perl associée à cette fonction. Elle est simple d’utilisation : étant donné une séquence stockée dans une variable $sequence, il vous suffit d’entrer :

study $sequence;

avant d’effectuer des recherches. Pensez-vous que cela va accélérer vos recherches dans les séquences d’ADN et de protéines, en vous basant sur ce que vous avez lu sur ces fonctions?

Pour en savoir encore plus, lisez la documentation Perl sur le module standard Benchmark (entrez perldoc Benchmark ou rendez-vous sur le site de la page d’accueil de Perl à l’adresse . Ecrivez maintenant un programme qui´

IV

cherche des motifs dans une séquence d’ADN avec ou sans la fonction study. Aviez-vous deviné juste?


Sixième partie VI Le code génétique (cours 2010)

Plan de la partie

37  Tableau de hachage

38  Structures de données et algorithmes pour la biologie

39  Stockage des informations

40  Code génétique

41  Traduire de l’ADN en protéines

42  ADN contenu dans des fichiers

43  Cadres de lecture

44  Exercices

Le code génétique

Jusqu’à présent nous avons utilisé Perl pour rechercher des motifs, simuler des mutations dans des séquences ADN, générer des nombres aléatoires et transcrired e l’ADN en ARN. Nous allons maintenant écrire des programmes Perl pour simuler la fac¸on dont le code génétique dirige la traduction d’une séquence d’ADN en une séquence de protéines. Nous allons introduire un nouveau type de donné, très utilisé en Perl, le « hachage » ou « tableau associatif ».

Plan

37  Tableau de hachage

38  Structures de données et algorithmes pour la biologie

39  Stockage des informations

40  Code génétique

41  Traduire de l’ADN en protéines

42  ADN contenu dans des fichiers

43  Cadres de lecture

44  Exercices

Définition tableau de hachage

Un hachage (ou tableau associatif) représente une collection de données, dont les éléments individuels sont sélectionnés grâce à une valeur d’indice.

Les valeur d’indice d’un hachage sont des scalaires quelconques. Les éléments d’un hachage sont dans un ordre quelconque.

Variables hachage

Le nom d’une variable hachage est constitué d’un signe pourcentage (%) suivi d’une lettre, suivis d’un ou plusieurs carractères lettre, chiffre et souligné.

Le nom du hachage reprend donc les mêmes règles que pour les scalaires et les tableaux.

Il n’y a pas de relation entre les variables %nom, $nom et @nom

Chaque élément d’un hachage est situé dans une variable scalaire distincte, à laquelle on accède par un indice chaˆ?ne, nommé clé.

Pour accéder à un élément : $dico{$nom}.

$clé représente n’importe quelle expression scalaire.

Remarque

L’accès à un élément d’un hachage nécéssite une ponctuation différente de celui du hachage complet.

Exemples de variables de hachage

Créer deux éléments dans un hachage :

Fonctions de hachage

La fonction keys

La fonction values

La fonction each

La fonction delete


I

De même qu’avec toutes les autres fonctions intégrées, les parenthèses sont optionnelles : keys %fred est similaire à keys(%fred)

II

foreach $cle (keys (%fred)) { # une fois pour chaque clé de %fred print "à $cle on a $fred{$cle}\n";

# affiche la clé et la valeur

}

Notez que les éléments individuels d’un hachage peuvent être interpolés dans les chaˆ?nes à apostrophes doucles.

On ne peut toutefois interpoler un hachage entier.

Dans un contexte scalaire, la fonction keys donne le nombre d’éléments du hachage.

III


La fonction values

La fonction each

each(%unhachage) renvoie un couple clé-valeur sous forme d’une liste à deux éléments. A chaque application de cette fonction sur un même hachage, le couple clé-valeur suivant est renvoyé, jusqu’à ce que l’on ait accédé à tous les éléments. Lorsqu’il n’existe plus de couples, each renvoie une liste vide.

Exemple

while (($prenom,$nom) = each(%noms)) {

print "Le nom de $prenom est $nom\n";

}

Le fait d’assigner une nouvelle valeur au hachage entier ré-initialise la fonction each au début.

Le fait d’ajouter ou de supprimer des éléments du hachage est susceptible de perturber each.

La fonction delete

La fonction delete permet de supprimer des éléments d’un hachage. L’opérande de delete est une référence à un hachage, comme si vous accédiez simplement à une valeur particulière. Perl supprime le couple clé-valeur du hachage.

%fred = ("aaa","bbb",234.5,34.56); # donne deux éléments à

%fred

delete $fred{"aaa"};

# %fred ne contient plus qu’une seule paire-valeur

Tranches de hachage I

Tranches de hachage II

Plan

37  Tableau de hachage

38  Structures de données et algorithmes pour la biologie

39  Stockage des informations

40  Code génétique

41  Traduire de l’ADN en protéines

42  ADN contenu dans des fichiers

43  Cadres de lecture

44  Exercices

Structure de donnée et algorithmes pour la biologie

Les biologistes explorent les données biologiques et essayent d’imainer comment les utiliser en se basant sur leur structure effective au sein des systèmes vivants. La bioinformatique est souvent utilisée pour modéliser cette structure aussi finement que possible.

Les bioinformatitiens suivent parfois une approche légèrement différente de celle des biologistes. Ils partent de ce qu’ils veulent faire des données et essayent de les organiser pour atteindre ce but : ils essayent de trouver un algorithme en représentant les données dans une structure de donnée appropriée.

Maintenant que vous connaissez trois structures de données différentes en Perl (scalaires, tableaux et hachages) examinons ces sujets étroitement liés que sont les algorithmes et les structures de données.

Des algorithmes différents nécessitent souvent des structures de données différentes.

Cas étude : base de données d’expression de gènes

Un organisme = 30000 gènes au total (ex : génome humain)

Examinons un type de cellule qui n’a jamais été correctement caractérisé dans certaines conditions environnementales intéreessantes, et déterminons pour chaque gène s’il est exprimé ou non (ie. transcrit en ARN)

Nons disposons de puces à ADN qui nous ont donné les informations d’expression pour cette cellule

Nous devons rechercher pour chacun des gènes s’il est exprimé par la cellule

Nous souhaiterons inclure cette fonctionalité de recherche sur un site web

Il y a plusieurs fac¸ons de procéder. Voyons dans un premier temps la nature des données à notre disposition. Imaginons que nous ayons le nom de tous les gènes de l’organisme associé à un nombre indiquant le niveau d’expression, les gènes non exprimés ont pour valeur 0

Solution 1 : Utiliser des tableaux non triés

 Supposons que nous souhaitons voir si les gènes ont été exprimé sans se préoccuper du niveau. Utilisons les tableaux, structure que nous connaissons.

 Rassemblons dans un tableau le nom des gènes exprimés et écartons les autres. Ex : 8000 gènes exprimés. Pour chaque requête il faudra comparer avec les 8000 gènes jusqu’à les trouver. On peut parcourir tout le tableau sans trouver.

 Ca focntionne mais c’est très lent. En moyenne : 1 requête gène exprimé = examen de 4000 gènes; 1 gène non exprimé = 8000 requêtes.

 Si le gène est manquant on ne pourra répondre que par la négative, et non un message indiquant que le gène cherché ne fait pas parti de notre expérience.

Solution 2 : Utiliser des tableaux triés I

Solution 2 : Utiliser des tableaux triés II

 fonction cmp en Perl :

’ZZZ’ cmp ’ZZZ’; #retourne 0

’AAA’ cmp ’ZZZ’; #retourne -1 ’ZZZ’ cmp ’AAA’; #retourne 1  fonction sort en Perl :

@tableau_trie = sort @tableau;

@tableau_nombres_trie = sort {$a <=> $b}

@tableau_nombres

Solution 3 : Utiliser des hachages

 contruire un hachage :

I clés = nom des gènes

I valeur = niveau d’expression

Savoir si un gène recherché est dans votre ensemble de données :

if ( defined $nom_hachage{’ma_clé’ ] ) { }

Si vous voulez trier les éléments stockés :

@cles_tries = sort keys %mon_hachage; ca peut être long pour un tableau de taille importante!

En résumé

un hachage sera adapté si vous devez uniquement vérifier la présence d’un élément dans un ensemble qu’il n’est pas nécessaire de trier un tableau trié associé à un algorithme de recherche binaire est adapté si vous avez besoin d’un ensemble ordonné et d’un accès relativement rapide et que vous n’avez pas besoin d’ajouter et supprimer des éléments fréquemment  un tableau accompagné de fonctions perl push et pop sera adapté si vous n’avez pas besoin de trier les éléments mais que vous devez rapidement aller au dernier élément ajouté  un tableau Perl avec les fonctions push et shift sera adapté si les éléments n’ont pas besoin d’être ordonné mais que vous devez ajouter des éléments. Ceci est particulièrement utile pour exprimer le « plus vieil » élément (celui qui est dans le tableau depuis longtemps).

Plan

37  Tableau de hachage

38  Structures de données et algorithmes pour la biologie

39  Stockage des informations

40  Code génétique

41  Traduire de l’ADN en protéines

42  ADN contenu dans des fichiers

43  Cadres de lecture

44  Exercices

Stockage des informations

base de donnée relationnelle SGBD : de gratuit à très couteux accès aux bases : modules Perl/DBI SGBDR : tables + requetes SQL

DBM (Database management)

I comment Perl sauvegarde ses hachages

I une fois démarré : il met en correspondance un hachage et un fichier

I permet la réutilisation d’un hachage

I = SGBD simple et très utile

Plan

37  Tableau de hachage

38  Structures de données et algorithmes pour la biologie

39  Stockage des informations

40  Code génétique

41  Traduire de l’ADN en protéines

42  ADN contenu dans des fichiers

43  Cadres de lecture

44  Exercices

Code génétique : introduction

ADN détermine la séquence des acides aminés des acides aminés des protéines

ADN <transcription> ARN <traduction> acides aminés (dogme central bio mol)

Ici = ADN -> acides aminés = traduction codon = triple de bases

43 acides aminés possible mais seulement 2à acides aminés (code redontant) chaque codon = 1 acide aminé


I

# nom du sous-programme : codon_en_aa

# but du sous-programme : traduire la séquence passée en argument

# en traduisant codon par codon. Version 1

# nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères sub codon_en_aa

{ my($codon) = @_;

#

if ( $codon =~ /TCA/i ) { return ’S’ } # Sérine elsif ( $codon =~ /TCC/i ) { return ’S’ } # Sérine elsif ( $codon =~ /TCG/i ) { return ’S’ } # Sérine elsif ( $codon =~ /TCT/i ) { return ’S’ } # Sérine elsif ( $codon =~ /TTC/i ) { return ’F’ } # Phénylalanine elsif ( $codon =~ /TTT/i ) { return ’F’ } # Phénylalanine elsif ( $codon =~ /TTA/i ) { return ’L’ } # Leucine elsif ( $codon =~ /TTG/i ) { return ’L’ } # Leucine elsif ( $codon =~ /TAC/i ) { return ’Y’ } # Tyrosine elsif ( $codon =~ /TAT/i ) { return ’Y’ } # Tyrosine elsif ( $codon =~ /TAA/i ) { return ’*’ } # Codon Stop



II

elsif ( $codon =~ /TAG/i ) { return ’*’ } # Codon Stop elsif ( $codon =~ /TGC/i ) { return ’C’ } # Cystéine elsif ( $codon =~ /TGT/i ) { return ’C’ } # Cystéine elsif ( $codon =~ /TGA/i ) { return ’*’ } # Codon Stop elsif ( $codon =~ /TGG/i ) { return ’W’ } # Tryptophane elsif ( $codon =~ /CTA/i ) { return ’L’ } # Leucine elsif ( $codon =~ /CTC/i ) { return ’L’ } # Leucine elsif ( $codon =~ /CTG/i ) { return ’L’ } # Leucine elsif ( $codon =~ /CTT/i ) { return ’L’ } # Leucine elsif ( $codon =~ /CCA/i ) { return ’P’ } # Proline elsif ( $codon =~ /CCC/i ) { return ’P’ } # Proline elsif ( $codon =~ /CCG/i ) { return ’P’ } # Proline elsif ( $codon =~ /CCT/i ) { return ’P’ } # Proline elsif ( $codon =~ /CAC/i ) { return ’H’ } # Histidine elsif ( $codon =~ /CAT/i ) { return ’H’ } # Histidine elsif ( $codon =~ /CAA/i ) { return ’Q’ } # Glutamine elsif ( $codon =~ /CAG/i ) { return ’Q’ } # Glutamine elsif ( $codon =~ /CGA/i ) { return ’R’ } # Arginine elsif ( $codon =~ /CGC/i ) { return ’R’ } # Arginine elsif ( $codon =~ /CGG/i ) { return ’R’ } # Arginine

III

elsif ( $codon =~ /CGT/i ) { return ’R’ } # Arginine elsif ( $codon =~ /ATA/i ) { return ’I’ } # Isoleucine elsif ( $codon =~ /ATC/i ) { return ’I’ } # Isoleucine elsif ( $codon =~ /ATT/i ) { return ’I’ } # Isoleucine elsif ( $codon =~ /ATG/i ) { return ’M’ } # Méthionine elsif ( $codon =~ /ACA/i ) { return ’T’ } # Thréonine elsif ( $codon =~ /ACC/i ) { return ’T’ } # Thréonine elsif ( $codon =~ /ACG/i ) { return ’T’ } # Thréonine elsif ( $codon =~ /ACT/i ) { return ’T’ } # Thréonine elsif ( $codon =~ /AAC/i ) { return ’N’ } # Asparagine elsif ( $codon =~ /AAT/i ) { return ’N’ } # Asparagine elsif ( $codon =~ /AAA/i ) { return ’K’ } # Lysine elsif ( $codon =~ /AAG/i ) { return ’K’ } # Lysine elsif ( $codon =~ /AGC/i ) { return ’S’ } # Sérine elsif ( $codon =~ /AGT/i ) { return ’S’ } # Sérine elsif ( $codon =~ /AGA/i ) { return ’R’ } # Arginine elsif ( $codon =~ /AGG/i ) { return ’R’ } # Arginine elsif ( $codon =~ /GTA/i ) { return ’V’ } # Valine elsif ( $codon =~ /GTC/i ) { return ’V’ } # Valine elsif ( $codon =~ /GTG/i ) { return ’V’ } # Valine

IV

elsif ( $codon =~ /GTT/i ) { return ’V’ } # Valine elsif ( $codon =~ /GCA/i ) { return ’A’ } # Alanine elsif ( $codon =~ /GCC/i ) { return ’A’ } # Alanine elsif ( $codon =~ /GCG/i ) { return ’A’ } # Alanine elsif ( $codon =~ /GCT/i ) { return ’A’ } # Alanine elsif ( $codon =~ /GAC/i ) { return ’D’ } # Acide Aspartique elsif ( $codon =~ /GAT/i ) { return ’D’ } # Acide Aspartique elsif ( $codon =~ /GAA/i ) { return ’E’ } # Acide Glutamique elsif ( $codon =~ /GAG/i ) { return ’E’ } # Acide Glutamique elsif ( $codon =~ /GGA/i ) { return ’G’ } # Glycine elsif ( $codon =~ /GGC/i ) { return ’G’ } # Glycine elsif ( $codon =~ /GGG/i ) { return ’G’ } # Glycine elsif ( $codon =~ /GGT/i ) { return ’G’ } # Glycine else { print STDERR "$codon contient une lettre autre que A,C,G,T"; exit;

}

}


La redondance du code génétique I

# nom du sous-programme : codon_en_aa

# but du sous-programme : traduire la séquence passée en argument

# en traduisant codon par codon. Version 2

# nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères sub codon_en_aa

{ my($codon) = @_; if ( $codon =~ /GC./i) { return ’A’ }        # Alanine elsif ( $codon =~ /TG[TC]/i) { return ’C’ } # Cystéine elsif ( $codon =~ /GA[TC]/i) { return ’D’ } # Acide Aspartique elsif ( $codon =~ /GA[AG]/i) { return ’E’ } # Acide Glutamique elsif ( $codon =~ /TT[TC]/i) { return ’F’ } # Phénylalanine elsif ( $codon =~ /GG./i) { return ’G’ } # Glycine elsif ( $codon =~ /CA[TC]/i) { return ’H’ } # Histidine elsif ( $codon =~ /AT[TCA]/i) { return ’I’ }# Isoleucine elsif ( $codon =~ /AA[AG]/i) { return ’K’ } # Lysine elsif ( $codon =~ /TT[AG]|CT./i) { return ’L’ } # Leucine elsif ( $codon =~ /ATG/i) { return ’M’ }  # Méthionine elsif ( $codon =~ /AA[TC]/i) { return ’N’ } # Asparagine

La redondance du code génétique II elsif ( $codon =~ /CC./i) { return ’P’ }   # Proline elsif ( $codon =~ /CA[AG]/i) { return ’Q’ } # Glutamine elsif ( $codon =~ /CG.|AG[AG]/i) { return ’R’ } # Arginine elsif ( $codon =~ /TC.|AG[TC]/i) { return ’S’ } # Sérine elsif ( $codon =~ /AC./i) { return ’T’ } # Thréonine elsif ( $codon =~ /GT./i) { return ’V’ }               # Valine elsif ( $codon =~ /TGG/i) { return ’W’ }    # Tryptophane elsif ( $codon =~ /TA[TC]/i) { return ’Y’ } # Tyrosine elsif ( $codon =~ /TA[AG]|TGA/i) { return ’*’ } # Codon Stop else { print STDERR "$codon contient une lettre autre que A,C,G,T"; exit;

}

}

I

# nom du sous-programme : codon_en_aa

# but du sous-programme : traduire la séquence passée en argument

# en traduisant codon par codon en utilisant

# une table de hachage. Version 3

# nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères

# sub codon_en_aa

{ my($codon) = @_; $codon = uc $codon; my(%code_genetique) =

(

’TCA’ => ’S’, # Sérine

’TCC’ => ’S’, # Sérine

’TCG’ => ’S’, # Sérine

’TCT’ => ’S’, # Sérine

’TTC’ => ’F’, # Phénylalanine

’TTT’ => ’F’, # Phénylalanine

’TTA’ => ’L’, # Leucine


II

’TTG’ => ’L’, # Leucine

’TAC’ => ’Y’, # Tyrosine

’TAT’ => ’Y’, # Tyrosine

’TAA’ => ’*’, # Codon Stop

’TAG’ => ’*’, # Codon Stop

’TGC’ => ’C’, # Cystéine

’TGT’ => ’C’, # Cystéine

’TGA’ => ’*’, # Codon Stop

’TGG’ => ’W’, # Tryptophane

’CTA’ => ’L’, # Leucine

’CTC’ => ’L’, # Leucine

’CTG’ => ’L’, # Leucine

’CTT’ => ’L’, # Leucine

’CCA’ => ’P’, # Proline

’CCC’ => ’P’, # Proline

’CCG’ => ’P’, # Proline

’CCT’ => ’P’, # Proline

’CAC’ => ’H’, # Histidine

’CAT’ => ’H’, # Histidine

’CAA’ => ’Q’, # Glutamine

III

’CAG’ => ’Q’, # Glutamine

’CGA’ => ’R’, # Arginine

’CGC’ => ’R’, # Arginine

’CGG’ => ’R’, # Arginine

’CGT’ => ’R’, # Arginine

’ATA’ => ’I’, # Isoleucine

’ATC’ => ’I’, # Isoleucine

’ATT’ => ’I’, # Isoleucine

’ATG’ => ’M’, # Méthionine

’ACA’ => ’T’, # Thréonine

’ACC’ => ’T’, # Thréonine

’ACG’ => ’T’, # Thréonine

’ACT’ => ’T’, # Thréonine

’AAC’ => ’N’, # Asparagine

’AAT’ => ’N’, # Asparagine

’AAA’ => ’K’, # Lysine

’AAG’ => ’K’, # Lysine

’AGC’ => ’S’, # Sérine

’AGT’ => ’S’, # Sérine

’AGA’ => ’R’, # Arginine

IV

’AGG’ => ’R’, # Arginine

’GTA’ => ’V’, # Valine

’GTC’ => ’V’, # Valine

’GTG’ => ’V’, # Valine

’GTT’ => ’V’, # Valine

’GCA’ => ’A’, # Alanine

’GCC’ => ’A’, # Alanine

’GCG’ => ’A’, # Alanine

’GCT’ => ’A’, # Alanine

’GAC’ => ’D’, # Acide Aspartique

’GAT’ => ’D’, # Acide Aspartique

’GAA’ => ’E’, # Acide Glutamique

’GAG’ => ’E’, # Acide Glutamique

’GGA’ => ’G’, # Glycine

’GGC’ => ’G’, # Glycine

’GGG’ => ’G’, # Glycine

’GGT’ => ’G’, # Glycine

); if ( exists $code_genetique{$codon} )

{

V

return $code_genetique{$codon};

} else { print STDERR "$codon contient une lettre autre que A,C,G,T"; exit;

}

}


Plan

37  Tableau de hachage

38  Structures de données et algorithmes pour la biologie

39  Stockage des informations

40  Code génétique

41  Traduire de l’ADN en protéines

42  ADN contenu dans des fichiers

43  Cadres de lecture

44  Exercices

Traduire de l’ADN en protéines I

#! /usr/bin/perl

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Traduire une équence d’ADN en protéine

# use strict; use warnings; use IntroPerlBioinfo; # Initialisons les variables my $adn = ’CGACGTCTTCGTACGGGACTAGCTCGTGTCGGTCGC’; my $proteine = "; my $codon;

# Traduisons chaque triplet de bases en l’acide aminé correspondant et

# ajoutons-les à la protéine for ( my $i=0; $i < (length($adn) - 2); $i += 3 )

{

$codon = substr($adn,$i,3);

$proteine .= codon_en_aa($codon);

Traduire de l’ADN en protéines II

} print "J’ai traduit la séquence d’ADN\n\n$adn\n\npour obtenir "; print "la protéine\n\n$proteine\n\n"; exit;

Plan

37  Tableau de hachage

38  Structures de données et algorithmes pour la biologie

39  Stockage des informations

40  Code génétique

41  Traduire de l’ADN en protéines

42  ADN contenu dans des fichiers

43  Cadres de lecture

44  Exercices

Lire des séquences ADN contenues dans des fichiers

FASTA FASTA et BLAST (Basic Local Alignment Search Tool).

Format le plus généralement utilisé.

GenBank (Genetic séquence Data Bank)

Genbank est un recueil de toutes les données génétiques diffusées publiquement.

EMBL (European Molecular Biology Laboratory)

Idem GenBBank mais format un peu différent

RAW (Données brutes) pas de format spécifique sorties de séquenceurs automatique d’ABI ou autres programmes

GCC (Genetics Computer Group)

GCC Wisconsin package d’Accelrys. Utilisé par de grands laboratoires. Format spécifique.

Format FASTA

Exemple de séquence ADN (en-tete FASTA ordinaire) :

agatggcggcgctgaggggtcttgggggctctaggccggccacctactgg tttgcagcggagacgacgcatggggcctgcgcaataggagtacgctgcct gggaggcgtgactagaagcggaagtagttgtgggcgcctttgcaaccgcc tgggacgccgccgagtggtctgtgcaggttcgcgggtcgctggcgggggt cgtgagggagtgcgccgggagcggagatatggagggagatggttcagacc cagagcctccagatgccggggaggacagcaagtccgagaatggggagaat gcgcccatctactgcatctgccgcaaaccggacatcaactgcttcatgat cgggtgtgacaactgcaatgagtggttccatggggactgcatccggatca ctgagaagatggccaaggccatccgggagtggtactgtcgggagtgcaga gagaaagaccccaagctagagattcgctatcggcacaagaagtcacggga gcgggatggcaatgagcgggacagcagtgagccccgggatgagggtggag ggcgcaagaggcctgtccctgatccagacctgcagcgccgggcagggtca gggacaggggttggggccatgcttgctcggggctctgcttcgccccacaa atcctctccgcagcccttggtggccacacccagccagcatcaccagcagc agcagcagcagatcaaacggtcagcccgcatgtgtggtgagtgtgaggca tgtcggcgcactgaggactgtggtcactgtgatttctgtcgggacatgaa gaagttcgggggccccaacaagatccggcagaagtgccggctgcgccagt gccagctgcgggcccgggaatcgtacaagtacttcccttcctcgctctca ccagtgacgccctcagagtccctgccaaggccccgccggccactgcccac ccaacagcagccacagccatcacagaagttagggcgcatccgtgaagatg agggggcagtggcgtcatcaacagtcaaggagcctcctgaggctacagcc acacctgagccactctcagatgaggaccta

Lecture de fichiers FASTA I

# nom du sous-programme : lire_donnees_depuis_fichier

# but du sous-programme : lire les données contenues dans un fichier et les

# transférer dans un tableau qui sera retourné

# nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères

# sub lire_donnees_depuis_fichier

{ my($nom_fichier) = @_; use strict; use warnings;

# Initialisons les variables my @donnees_fichier = ( ); unless ( open(fichier_donnees, $nom_fichier) )

{ print STDERR "Impossible d’ouvrir le fichier \"$nom_fichier\"\n\n"; exit; }

Lecture de fichiers FASTA II

@donnees_fichier = <fichier_donnees>; close fichier_donnees; return @donnees_fichier;

}

Extraire une séquence depuis un fichier FASTA I

# nom du sous-programme : extraire_sequence_depuis_fichier_fasta

# but du sous-programme : extraire une séquence depuis un fichier FASTA

# et la ranger dans une cha^?ne de caractères

# nombre d’arguments : 1

# nature de l’argument : tableau

# sub extraire_sequence_depuis_fichier_fasta

{ my(@donnees_fichier_fasta) = @_; use strict; use warnings; my $sequence = "; foreach my $ligne (@donnees_fichier_fasta)

{

# Supprimons les lignes vides if ( $ligne =~ /^\s*$/ )

{ next;

}

# Supprimons la ligne d’en-tete FASTA

Extraire une séquence depuis un fichier FASTA II

elsif ( $ligne =~ /^>/ )

{ next;

}

# Cette ligne n’est ni une ligne vide ni la ligne d’en-tete. Donc # conservons-la et concaténons-la avec la cha^?ne de caractères # de la séquence.

else

{

$sequence .= $ligne;

}

}

# Retirons les données étrangères à la séquence, dans le cas # présent les caractères d’espacements et les numérotations.

$sequence =~ s/\s//g; $sequence =~ s/[0-9]//g; return $sequence;

}

Ecrire des données de séquences formatées

# nom du sous-programme : afficher_sequence

# but du sous-programme : afficher une séquence

# nombre d’arguments : 2

# nature de l’argument : la cha^?ne de caractères et la longueur de

# la ligne sub afficher_sequence

{ my($sequence, $longueur) = @_; use strict; use warnings;

# Affichons la séquence par lignes de $longueur caractères for ( my $pos = 0; $pos < length($sequence); $pos += $longueur )

{ print substr($sequence, $pos, $longueur), "\n";

}

}

Plan

37  Tableau de hachage

38  Structures de données et algorithmes pour la biologie

39  Stockage des informations

40  Code génétique

41  Traduire de l’ADN en protéines

42  ADN contenu dans des fichiers

43  Cadres de lecture

44  Exercices

Cadres de lecture

6 cadres de lecture pour trouver les régions codantes qu’utilise la cellule pour créer des protéines.

ADN codant sur le brin complément inverse : 3 -> 6 cadres


I

# nom du sous-programme : revcom

# but du sous-programme : calculer le reverse complément d’une séquence

# nombre d’arguments : 1

# nature des arguments : cha^?ne de caractères

# sub revcom

{ my($adn) = @_;

# Commen¸cons par déterminer la séquence du brin complémentaire my $revcom = reverse $adn;

# à présent, complémentons la séquence, en gérant la casse des lettres

# A->T, a->t, T->A, t->a, C->G,c->g, G->C,g->c

$revcom =~ tr/ACGTacgt/TGCAtgca/; return $revcom;

}

# nom du sous-programme : traduire_cadre

# but du sous-programme : traduire suivant l’un des cadres

# nombre d’arguments : 2 (ou 3)

# nature des arguments : cha^?ne de caractères, début (et fin)

II

#

# nom du sous-programme : traduire_phase

# but du sous-programme : traduire suivant l’une des phases

# nombre d’arguments : 2 (ou 3)

# nature des arguments : cha^?ne de caractères, début (et fin)

# sub traduire_cadre

{ my($sequence, $debut, $fin) = @_; my $proteine;

# Pour faciliter l’utilisation du sous-programme, vous n’aurez pas # à spécifier la position de fin, la fin sera par défaut la fin de la # séquence. unless ( $fin )

{

$fin = length($sequence);

}

# Pour terminer, calculer et retourner la traduction return adn_en_peptide ( substr ( $sequence,

$debut - 1,

III

$fin - $debut + 1) );

} sub traduire_phase

{ my($sequence, $debut, $fin) = @_; my $proteine;

# Pour faciliter l’utilisation du sous-programme, vous n’aurez pas # à spécifier la position de fin, la fin sera par défaut la fin de la # séquence. unless ( $fin )

{

$fin = length($sequence);

}

# Pour terminer, calculer et retourner la traduction return adn_en_peptide ( substr ( $sequence,

$debut - 1,

$fin - $debut + 1) );

}


Plan

37  Tableau de hachage

38  Structures de données et algorithmes pour la biologie

39  Stockage des informations

40  Code génétique

41  Traduire de l’ADN en protéines

42  ADN contenu dans des fichiers

43  Cadres de lecture

44  Exercices

I

1   Ecrivez un sous-programme qui teste une séquence et retourne vrai´ s’il s’agit d’une séquence ADN. Ecrivez un sous-programme qui teste une séquence et retourne vrai s’il s’agit d’une séquence de protéines.

2   Ecrivez un programme capable de rechercher un gène par son nom´ dans un tableau non trié.

3   Ecrivez un programme capable de rechercher un gène par son nom´ dans un tableau trié; utilisez la fonction Perl sort pour trier le tableau. Exercice complémentaire : écrivez un sous-programme de recherche binaire qui effectue cette recherche.

4   Ecrivez un sous-programme qui insère un élément dans un tableau´ trié. Suggestion : utilisez la fonction Perl splice pour insérer un élément comme cela est indiqué dans le chapitre 2.

II

5   Ecrivez un programme qui recherche un gène par son nom dans un´ hachage. Utilisez les gènes sur lesquels vous travaillez ou essayez de télécharger une liste de tous les gènes d’un organisme donné depuis le site du NCBI (). Faites un hachage de tous les gènes (clé=nom, valeur = identification du gène (ID) ou séquence).

Suggestion : écrivez un petit programme Perl reformatant la liste des gènes avec lesquels vosu allez commecner pour faciliter leur insertion dans le hachage.

6   Ecrivez un programme qui vérifie un tableau de données et retourne´ vrai s’il est au format FASTA. FASTA gère les codes standard IUB/IUPAC pour les acides aminés et les acides nucléiques, plus le tiret (-) qui représente une brèche de n’importe quelle longueur. L’astérisque (*) représente un codon stop pour les acides aminés. Faites attention lorsque vous utiilserez un astérisque dans une expression régulière; utilisez \* pour rechercher le caractère *.

III

Les exercices suivants sont liés aux effets des mutations de l’ADN sur les protéines qu’il code. Ils associent des notions d’aléatoire et de mutation rencontré au cours du chapitre précédent et le code génétique.

7   Pour chaque codon, indiquez l’effet produit par une mutation élémentaire (un seul nucléotide) de ce codon : le codon code-t-il même acide aminé ou bien code-t-il un acide aminé différent? lequel? Ecrivez un sous-programme qui prend en argument un codon et´ retourne la liste des acides aminés possibles pouvant résulter de n’importe quelle mutation élémentaire du codon.

8   Ecrivez un sous-programme qui prend comme argument un acied´ aminé et le transforme aléatoirement en un des acides aminés déterminés dans l’exercice 7.

IV

9    Ecrivez un programme qui effectue une mutation aléatoire des acides´ aminés de la séquence d’une protéine, en se limitant à des mutations

élémentaires des codons d’origine, comm eexpliqué dans les exercices 7 et 8.

10  Certains codons sont présents plus souvent que d’autres dans une séquence aléatoire d’ADN. Ecrivez un sous-programme qui prend´ comme argument un acide aminé et retourne la probabilité qu’il soit codé par un codon généré aléatoirement.

11  Ecrivez un sous-programme qui accepte trois arguments : un acide´ aminé, une position (1, 2 ou 3) et un nucléotide. Il prend ensuite chaque codon pour cet acide aminé (il peut y avoir de un à six codons), et le mute à la position donnée avec le nucléotide spécifié; En fin de compte, la fonction retourne l’ensemble des acides aminés resultant des codons mutés.


Septième partie VII

Cartes de restriction et expressions régulières (cours 2010)

Plan de la partie

45  Les expressions régulières

46  Opérations Perl

47  Exercices

48  Synthèse

Plan

45  Les expressions régulières

46  Opérations Perl

47  Exercices

48  Synthèse


I

# nom du sous-programme : IUB_en_expreg

# but du sous-programme : transformer les codes d’ambigu¨?té IUB en

# expressions régulières # nombre d’arguments : 1

# nature de l’argument : cha^?ne de caractères

#

# Voici les codes IUB (Eur. J. Biochem. 150: 1-5, 1985) :

# R = G ou A

# Y = C ou T

# M = A ou C

# K = G ou T

# S = G ou C

# W = A ou T

# B = non A (C ou G ou T)

# D = non C (A ou G ou T)

# H = non G (A ou C ou T)

# V = non T (A ou C ou G)

# N = A ou C ou G ou T

sub IUB_en_expreg

{

# Récupérons le site de restriction

II

my($iub) = @_; my $expression_reguliere = ";

my %iub_en_classe_caracteres = (

A => ’A’,

C => ’C’,

G => ’G’,

T => ’T’,

R => ’[GA]’,

Y => ’[CT]’,

M => ’[AC]’,

K => ’[GT]’,

S => ’[GC]’,

W => ’[AT]’,

B => ’[CGT]’,

D => ’[AGT]’,

H => ’[ACT]’,

V => ’[ACG]’,

N => ’[ACGT]’, );

# Retirons les signes ^ des sites de restriction

III

$iub =~ s/\^//g;

# Traduisons chaque caractère dans la séquence iub for ( my $i = 0; $i < length($iub); ++$i )

{

$expression_reguliere .=

$iub_en_classe_caracteres{substr($iub, $i, 1)};

}

return $expression_reguliere;

}

# Fin du sous-programmes


I

# nom du sous-programme : filtrer_REBASE

# but du sous-programme : filtrer un fichier REBASE pour retourner un

# hachage avec pour clé les noms des enzymes de restriction et pour valeurs les sites

# de restriction (ou les expressions régulières) séparés par des caracte`res espace

# nombre d’arguments : 1

# nature de l’argument : tableau de cha^?nes de caractères

sub filtrer_REBASE

{ my($fichier_REBASE) = @_;

use strict; use warnings; use IntroPerlBioinfo; # Voir chapitre 6 pour ce module

# Declarons les variables my @fichier_REBASE = ( ); my %hachage_REBASE = ( ); my $nom; my $site;

II

my $expreg;

# Lisons dans le fichier REBASE my $descripteur_fichier_REBASE = ouvrir_fichier($fichier_REBASE);

while ( <$descripteur_fichier_REBASE> )

{

# Supprimons les lignes d’en-t^ete ( 1 .. /Rich Roberts/ ) and next;

# Supprimons les lignes vides

/^\s*$/ and next;

# Séparons les deux (ou trois si les noms sont parenthésés) champs my @champs = split(/\s+/, $_);

# Récupérons et stockons les noms et les sites de restriction

# Pour simplifier, retirons les noms parenthésés et

# conservons uniquement le premier et le dernier champ

$nom = shift @champs;

$site = pop @champs;

III

# Traduisons les sites de restriction en expressions re´gulières

$expreg = IUB_en_expreg($site);

# Stockons les données dans un tableau de hachage

$hachage_REBASE{$nom} = "$site $expreg";

}

# Retournons le tableau de hachage contenant les données reformatées return %hachage_REBASE;

}


I

!/usr/bin/perl -w

#

# Nom du programme :

# Auteur : James Tisdall

# But du programme : Construire la carte de restriction a` partir des

# requ^etes de l’utilisateur portant sur les noms

# des enzymes de restriction

#

use strict; use warnings; use IntroPerlBioinfo;

# Déclarons et initialisons les variables my %hachage_rebase = (); my @fichier_donnees = (); my $requete = "; my $adn = "; my $site_reconnaissance = "; my $expreg = "; my @emplacements = ();

II

# Lisons dans le fichier « »

@fichier_donnees = lire_donnees_depuis_fichier("");

# Extrayons la séquence d’ADN depuis le fichier « »

$adn = extraire_sequence_depuis_fichier_fasta(@fichier_donnees);

# Obtenons les données REBASE à partir du fichier « bionet » et

# plac¸ons les infos dans un tableau de hachage %hachage_rebase = filtrer_REBASE("bionet");

# Demandons à l’utilisateur les noms des enzymes de restriction, créons

# la carte de restrictions associée do { print "Rechercher un site de restriction pour quelle enzyme (Entreé pour quitter)? :";

$requete = <STDIN>; chomp $requete;

III

# Fin explicite lorsque la ligne est vide if ( $requete =~ /^\s*$/ )

{ exit; }

# Effectuons la recherche dans la séquence d’ADN if ( exists $hachage_rebase{$requete} )

{

($site_reconnaissance, $expreg) = split (/\s+/, $hachage_rebase{$requete});

# Créons une carte de restriction

@emplacements = positions_expreg($expreg, $adn);

# Affichons la carte de restriction if (@emplacements) { print "Rechercher : $requete $site_reconnaissance $expreg\n"; print "Sites de restriction pour $requete aux emplacements :\n"; print join(" ", @emplacements), "\n";

} else { print "Pas de site de restriction pour l’enzyme $requete dans la séquence\n";

IV

} } print "\n"; } until ( $requete =~ /^\s*$/ );

exit;


Plan

45  Les expressions régulières

46  Opérations Perl

47  Exercices

48  Synthèse

Précédence et associativité des opérateurs

Associativité Opérateur

Non associatif ++ --

Droite ** (élévation à la puissance)

Droite ! ~ \ + - (non logique, complément à 1, opérateur de référence, plus unaire, moins unaire)

Gauche =~ (correspondance) !~ (pas de correspondance)

Gauche * / % x (multiplication, division, modulo, recopie de chaˆ?ne)

Gauche + - . (addition, soustraction, concaténation de chaˆ?ne)

Non associatif Opérateurs unaire nomms (comme chomp)

Gauche && (et logique)

Gauche || (ou logique)

Droite = += -= *= (assignation, et assignation binaire) Droite not (non logique)

Gauche and (et logique)

Gauche or xor (ou logique, ou exclusif logique)

Du plus associatif au moins associatif

Expressions régulières

Motif

Une expression régulière est un motif dont certaines parties sont comparées à des caractères d’un certain type de la chaˆ?ne. D’autres correspondent à plusieurs caractères.


I

II

Les crochets

Une classe de caractères de correspondance est représenté par une paire de crochets, ouvert et fermés, encadrant une série de caractères. Pour qu’il y ait correspondance avec les motifs, il faut et il suffit qu’un seul de ces caractères soit présent dans la partie correspondante.

/[abcde]/

correspond à une chaˆ?ne contenant n’importe laquelle des cinq premières lettres de l’alphabet en minuscule.

/[aeiouAEIOU]/

correspond à une chaˆ?ne contenant n’importe laquelle des cinq voyelles, en minuscules ou majuscules.

III

 Pour insérer un crochet droit (]) dans la série, il faut le faire précéder d’une barre oblique inverse ou le mettre en première position de la série.

Les plages (intervalles) de caractères comme « de a à z » peuvent être abrégés en indiquant leur limites séparées par un tiret (-)

Pour avoir un tiret littéral dans la série il faut le faire précéder d’une barre oblique inverse ou le mettre à la fin

Exemples

[0123456789] # correspond à n’importe quel caractère isolé

[0-9]                        # idem

[0-9\-]                   # correspond à 0-9, ou à moins

[a-zA-Z]                 # correspond à n’importe quelle lettre minuscule ou # majuscule

[a-zA-Z0-9_] # correspond à n’importe quelle lettre, chiffre ou souligné

IV

 Il existe une classe d’exclusion de caractères, semblable à une classe de caractères, mais avec un accent circonflexe (^) situé immédiatement après le crochet gauche.

Cela correspond à tout caractère individuel non présent dans la série.

Par commodité, certaines classes de caractères courantes sont pré-définies, comme le montre le tableau suivant :

V

Construction

Classe équivalente

Constructeur de négation

Classe de négation

\d (un chiffre)

[0-9]

\D (pas un chiffre)

[^0-9]

\w (caractère de mot)

[a-zA-Z0-9_]

\W (pas un mot)

[^a-zA-Z0-9_]

\s (caractère espace)

[ \r\t\n\f]

\S (pas un espace)

[^ \r\t\n\f]


I

II

III

Multiplicatif général

Le multiplicatif général consiste en une parire d’accolades encadrant un ou deux nombres. Le caractère qui précède immédiatement doit être trouvé dans le nombre de répétitions indiqué par les accolades.

Exemple

/x{5,10}/ # x doit être trouvé entre 5 et 10 fois

/x{5,}/ # x doit être trouvé 5 fois au plus

/x{0,5}/ # x doit être trouvé au moins 5 fois

/x{5}/              # x doit être trouvé exactement 5 fois

*, + et ? peuvent donc aussi s’écrire {0,}, {1,} et {0,1}!


IV

Avidité des opérateurs

Si deux multiplicatifs apparaissent dans une expression, la règle d’avidité est affinée par « le plus à gauche est le plus avide ».

On peut forcer un multiplicatif à être non avide (donc « paresseux ») en le faisant suivre d’un point d’interrogation. Tous les multiplicatifs sont éligibles : ?, +, * et {m,n}.

Exemple

$               = "a xxx c xxxxxxxx c xxx d";

/a.*c.*d/; #.*c correspond à " xxx c xxxxxxxx "

/a.*?c.*d/; #.*?c correspond à " xxx " seulement

Si une expression ne correspond pas, elle est réessayé sur une autre partie de la chaˆ?ne qui pourrait correspondre (système de « backtracking »).

V

Une expression régulière complexe peut conduire à de nombreux « backtrackings », allongeant la durée d’éxécution.

Une correspondance paresseuse (terminée par un «? ») simplifiera réellement le travail de Perl, tenez-en compte.

Parenthèses de mémorisation

Une paire de parenthèses, encadrant une partie quelconque d’un motif, est un autre opérateur de regroupement. Elles ne modifient pas le fait que les motifs correspondent ou non, mais permet de mémoriser la partie correspondante au motif, afin que l’on puisse s’y référer ultérieurement. Pour manipuler une partie de chaˆ?ne mémoriée, il faut insérer une barre oblique inverse, suivie d’un entier. Une telle construction représente la série de caractères correspondant à la paire de arenthèses de même ordre (en comptant à partir de un).

Exemple

/fred(.)barney\1/ # correspond avec "fredxbarneyx"

# mais pas avec "fredxbarneyz"

/fred.barney./                   # correspond avec les deux

/a(.)b(.)c\2d\1/ # correspond avec "axbycydx"

/a(.*)b\1c/                             # correspond avec "aFREDbFREDc" ou "abc"

# mais pas avec "aXXbXXXc"


Alternatives

I

Plusieurs notations particulières permettent d’ancrer un motif.

Normalement lorsqu’un motif est mis en correspondance avec la chaˆ?ne, le début du motif est virtuellement déplacé de gauche à droite durant la comparaison avec la chaˆ?ne, entrant en correspondance à la première occasion possible. Les ancres permettent de s’assurer que certaines parties du motif sont alignées avec des parties particulières de la chaˆ?ne.

l’ancre \b correspond à une limite de mot

une limite de mots est l’endroit situé entre les caractères qui correspondent à \w et ceux correspondant à \W (ou entre \w et la fin de la chaˆ?ne)

 l’ancre \B demande qu’il n’y ait pas de limite de mot à l’endroit indiqué

II

Exemples

/fred\b/; # correspond à fred, mais pas à frederick

/\bmo/;                # correspond à moe et à mole, mais pas à Elmo

/\bFred\b/; # correspond à Fred, mais pas à Frederick ni à AlFred

/\b\+\b/; # correspond à "x+y" mais pas à ”++”ou à " + "

/abc\bdef/; # ne correspond jamais (impossible de trouver une limite ici)

/\bFred\B/; # correspond à "Frederick", mais pas à "Fred

Flinstone"

ˆ (accent circonflexe) correspond au départ de la chaˆ?ne (s’il est situé

à un endroit censé correspondre à celà)

/^a/; # correspond au caractère a en début de chaˆ?ne

/a^/; # correspond à deux acractères a et ^ à n’importe quel endroit de la chaˆ?ne

III

 $ correspond à l’ancre symbolisant la fin de chaˆ?ne (s’il est situé à un endroit censé correspondre à celà)

/c$/; # correspond au caractère c en fin de chaˆ?ne

/$c/; # correspond à deux acractères $ et c à n’importe quel endroit de la chaˆ?ne

D’autres ancres sont disponibles (\A et \Z) et des ancres de poursuite crées à partir de ?= et ?! : cf. livre Programmation en Perl ou bien la page de manuel perlre


Précédence

Comme tous les opérateurs, les motifs de regroupement et d’ancrage disposent d’une précédence. Celle-ci est présentée dans le tableau ci-dessous, de la plus élevée à la plus faible.

Nom

Représentation

Parenthèses

() (? : )

Multiplicatifs

? + * {m,n}?? +? *? {m,n}?

Série et ancrage

abc ˆ $ \A \Z (? = ) (?! )

Alternatives

|

/a|b*/   # un seul a ou n’importe quelle quantité de b /abc*/ # correspond à ab, abc, abcc, abccc, etc.

/(abc)*/                              # correspond à "", abc, abcabc, abcabcabc, etc.

/^x|y/                             # correspond à x en début de ligne ou à y ailleurs

/^(x|y)/                          # correspond à x ou à y au début d’une ligne


/a|bc|d/                         #a, ou bc, ou d

/(a|b)(c|d)/           #ac, ad, bc ou bd /(song|blue)bird/ #songbird ou bluebird

              J. Farinas (IRIT)                                                          PERL bioinfo


                                                                                                                       21 octobre 2010             281 / 293

Plan

45  Les expressions régulières

46  Opérations Perl

47  Exercices

48  Synthèse

Exercices I

1   Modifiez l’exemple 9-3 afin qu’il accepte une séquence d’ADN entrée en ligne de commande; ou si rien n’est spécifié, qu’il demande à l’utilisateur un nom de fichier et y lise la séquence d’ADN

2   Modifiez l’exercice 1 pour qu’il lise et construise un tableau de hachage à partir de la totalité des données sur les sites de restriction REBASE du fichier bionet.

3   Modifiez l’exercice 2 afin de stocker le hachage REBASE créé, dans un fichier DBM s’il n’existe pas ou afin d’utiliser le fichier DBM s’il existe.

4   Modifiez l’exemple 5-3 pour afficher les positions des motifs trouvés, même si un motif apparaˆ?t plusieurs fois dans la séquence.

Exercices II

5   Incluez une sortie graphique des sites de coupure sur la carte de restriction, en affichant les séquences et en nommant les sites de restriction par le nom de l’enzyme. Comment construire une carte qui prenne en compte plusieurs enzymes de restrction? Comment manipuler des sites de restriction chevauchant?

6   Ecrivez un sous-programme qui retourne les fragments de restriction,´ c’est-à-dire les fragments d’ADN résultant de la réaction de restriction. Pensez à prendre en compte la localisation du site de coupure, ce qui nécessite de filtrer le fichier bionet de REBASE de fac¸on différente. Vous pouvez, si vous le désirez, ignorer les enzymes de restriction pour lesquelles le site de coupure n’est pas indiqué par ˆ.

7   Etendez le programme qui crée la carte de restriction afin qu’il prenne´ en compte les brins opposés pour les sites de reconnaissance non palindromiques.

Plan

45  Les expressions régulières

46  Opérations Perl

47  Exercices

48  Synthèse

Synthèse

Cette partie vous a permis d’avoir une vue d’ensemble des expressions régulières et des opérateurs Perl.

Vous avez également appris à écrire un programme permettant d’utiliser une technique standard et fondamentale en biologie moléculaire : la détermination de la carte de restriction d’une séquence.

L’utilisation de frangments de restrictions est une des premières techniques permettant la réalisation d’empreintes d’ADN

Les cartes de restriction constituent un outil essentiel à la conception d’expériences de clonage. Ex : insertion d’un fragment d’ADN donné dans un vecteur.

 Utile également dans les projets de séquen¸cage. Ex : en shotgun ou en séquencage direct.

Huitième partie VIII

Projet (2008)

Plan 49 Sujet de projet


I

 Le sujet de projet proposé ici comprend deux parties :

I une partie commune a tout le monde qui va vous permettre de comprendre le mécanisme de stockage de l’information de type Genbank

I une partie ou` vous devrez apporter votre propre contribution, en introduisant des traitements originaux et utiles sur les données GenBank.

 La banque de séquence GenBank (Genetic Sequence Data Bank), une banque de données de fichiers plat, joue un rôle important en biologie moderne et en bioinformatique. Cette banque de données est internationale et regroupe des séquences nucléotidiques (bactéries, plantes, animaux).

 On se propose dans ce projet d’écrire en Perl des programmes pour extraire rechercher et afficher les informations contenues dans les entrées et les divisions de GenBank, créer des bases de données DBM (DataBase Manager) pour le stockage.

II

 Les entrées GenBank contiennent un grand nombre d’informations complémentaires à la séquence :

I des identificateurs (numéros d’accès et noms des gènes),

I une classification phylogénétique,

I des références bibliographiques,

I et éventuellement une table (feature table) contenant les caractéristiques suivantes :

I localisation des sites de régulation,

I séquences des protéines associées, I introns et exons.

 Vous pourrez consulter une documentation exhaustive de ce format de structure de données ici :

exemple commenté :

III

 Exemple de fichier que vous utiliserez pour vos premiers tests :

1      Ecrire une application qui demande le nom du fichier à traiter et qui´ propose un menu avec les fonctionalités suivantes :

I récupération de la séquence contenue dans le fichier (méthode 1 : en utilisant un parcours ligne à ligne du tableau contenant le fichier)

I récupération de la séquence contenue dans le fichier (méthode 2 : en filtrant une variable scalaire contenant le fichier)

I affichage des informations d’identification (le locus, le numéro d’accès et le nom de l’organisme)

I affichage du champ définition

I affichage d’un champ quelconque dont le mot clé est demandé à l’utilisateur (en vérifiant qu’il existe bien)

I affichage d’un niveau quelconque de la table des caractéristiques (FEATURES1) dont le nom est demandé à l’utilisateur (en vérifiant qu’il existe bien)

IV

I affichez convenablement à partir de la séquence contenue dans le fichier le nombre de chacun des fragments de longueur 4 triés en fonction de leur fréquence. Une séquence de 4 bases (il y en a 256 différentes) peut commencer à la position 1, 2, 3, etc.

I stockez le fichier au format DBM (DataBase Management)

Vous proposerez une option dans le menu qui permettra à l’utilisateur de quitter votre application.

Pour tester le dernier traitement :

I Proposez un programme qui charge le fichier DBM http:

(contenant une collection d’enregistrements GenBank) et qui permette d’afficher la liste des numéros d’accès disponibles et d’afficher à partir d’un numéro d’accès les enregistrements associés.

2      Proposez des fonctionnalités supplémentaires (au moins trois) à vos programmes pour manipuler et traiter les données GenBank. Basez-vous sur les recherches qui sont réalisées dans ce domaine, ou` sur les traitements que vous connaissez sur le génome.

V

 A l’issue de ce projet vous devrez rendre :

I un document présentant vos programmes, justifiant vos choix de programmation et présentant votre démarche en vue de les tester.

I un exposé oral de 20 minutes ou` vous présenterez le fonctionnement de vos programmes (captures d’écran ou démonstration en temps réel) et l’adéquation de vos programmes avec ce qui était demandé dans le sujet. En conclusion, vous présenterez les traitements courament réalisés en bio-informatique et l’interet et les avantages de Perl pour la réalisation de ces programmes.



56