Il vous est peut-être arrivé d'attendre qu'un logiciel A ait fini son travail pour pouvoir lancer un logiciel B, qui lui utilise la sortie du logiciel A. Si l'exécution de A ne prend que quelques secondes cela n'est pas trop grave. Par contre, si elle prend des heures et que vous devez vérifier régulièrement s’il a fini, cela peut très vite devenir fatigant. Une bonne solution serait de faire que le logiciel B s'exécute automatiquement quand A a fini et c'est cela que l'on appelle un pipeline. Aujourd'hui je vais éclaircir pour vous ce terme et donner quelque exemples, très simples, de pipelines sous GNU/Linux.
C'est quoi un pipeline ?
Il s'agit d'un terme anglais, en informatique il désigne un groupe de logiciels exécutés en série de telle façon que la sortie d'un logiciel sert d'entrée pour le suivant. Il y a différents intérêts à la construction d'un pipeline. On peut par exemple chercher à exécuter à la chaîne une série de logiciels pouvant écrire sur la sortie standard et ainsi éviter de créer des fichiers intermédiaires. On peut également chercher à ce que toute une série de tâches s'exécutent les unes après les autres, sans intervention de l'utilisateur.
Dans sa forme la plus simple, le pipeline n'est qu'une chaîne où chaque logiciel attend la sortie du précédent, mais on peut construire des pipelines où plusieurs logiciels dépendent de la sortie d'un autre et vice-versa (cf. Shéma). Certains pipelines contiennent même des boucles pour vérifier si la commande précédente s'est bien exécutée, et si se n'est pas le cas, la relancer au lieu de lancer le logiciel suivant. La complexité augmente, bien sûr, avec le nombre d'étapes dans le pipeline et le nombre de connexions entre elles.
Pour illustrer la notion de pipeline, je vais vous présenter quelque exemples qui pourront vous servir pour des petites tâches de la vie de tous les jours (enfin, celle des bio-informaticiens).
Premier pipeline sur sortie standard
Sous GNU/Linux il existe une façon très simple de faire un pipeline, en ligne de commande, avec le symbole pipe '|'.
Voici un petit exemple : dans un terminal, on peut rechercher une commande que l'on a tapée précédemment avec à la commande 'history', mais elle résume parfois des milliers de commandes et si celle que vous cherchez est la millième cela peut être difficile de la trouver. Du coup il serait bien de pouvoir chercher notre commande grâce à un mot qu'elle contient. On peut le faire avec la commande 'grep', qui permet de chercher un terme spécifique dans un texte et d'afficher la ou les lignes qui le contiennent. Un moyen simple de connecter ces deux commandes est d'utiliser le pipe et de construire notre premier pipeline.
Dans cet exemple, je recherche les commandes que j'ai utilisées avec le logiciel 'samtools':
1 2 3 4 |
$history | grep samtools 844 bsub -M6000000 'samtools view ‑Sb test_all.VIR.sam ‑o test_all.VIR.bam' 870 bsub -M6000000 'samtools sort test_all.VIR.bam test_all.VIR_sorted' |
Comme vous pouvez le voir, le chiffre en début de ligne indique la position où se trouvait chaque commande, je n'avais pas utilisé samtools depuis un petit moment et j'aurais eu de la peine à retrouver ma commande sans ce petit pipeline.
Une autre façon d'utiliser la sortie standard est de faire appel à la commande 'xargs'. Imaginons cette fois que je cherche un fichier et dont je veux afficher le début. Je peux utiliser la fonction 'find' pour trouver mon fichier et 'head' pour en afficher le début.
Essayons avec le pipe :
1 2 3 4 5 6 |
$find . -name info.csv ./test/info.csv $find . -name info.csv | head ./test/info.csv |
Et mince, 'head' imprime ici le début du résultat de notre commande 'find' et non pas le début du fichier. Il faut donc une méthode pour faire comprendre à 'head' que les information qu'on lui envoie doivent être utilisées comme argument et non pas comme simple texte. Utilisons xargs pour résoudre ce problème.
1 2 3 |
$find . -name info.csv | xargs head Ceci est la première et dernière ligne du fichier info. |
Et voilà problème résolu, la commande 'find' trouve mon fichier et la commande 'head' affiche les premières lignes. Si il y avait eu plusieurs fichiers, chacun d'entre eux aurait été envoyé à la commande 'head' et leurs débuts auraient été imprimés les uns à la suite des autres.
(Pour les plus curieux, on peut le faire aussi avec l'option '-exec' de la commande find, mais dans ce cas pas besoin de pipeline)
Pipeline avec fichiers intermédiaires
Les deux exemples précédents utilisaient la sortie standard comment entrée pour la commande suivante. Je vais maintenant vous montrer comment enchaîner deux commandes et utiliser un fichier créé par la première.
Dans votre terminal c'est en fait très simple, il suffit d'écrire les deux commandes sur une seule ligne, mais en les séparent avec un point-virgule.
Voici un petit exemple avec les commandes samtools que j'ai cherchées dans le premier exemple :
1 2 3 |
samtools view -Sb test_all.VIR.sam -o test_all.VIR.bam samtools sort test_all.VIR.bam test_all.VIR_sorted |
La première commande crée le fichier 'test_all.VIR.bam' et la deuxième le trie. Pour mettre un petit contrôle on peut par exemple écrire dans un fichier que la commande est terminée. Ici ce n'est pas bien important, mais imaginez-vous aligner six ou sept commandes pour comprendre l'importance de ce rapport d'exécution. En effet si une commande rencontre une erreur, alors toutes les suivantes ne seront pas exécutées.
1 |
$samtools view -Sb test_all.VIR.sam -o test_all.VIR.bam ; echo 'commande 1 terminee' > rapport_execution.txt ; samtools sort test_all.VIR.bam test_all.VIR_sorted ; echo 'commande 2 terminee' >> rapport_execution.txt |
Et voilà, les commandes vont s'exécuter les unes après les autres et si quelque chose se passe mal, je saurai à quel niveau, grâce à mon fichier de contrôle.
Les méthodes présentées dans cet article ne vous serviront pas pour construire un pipeline robuste, qui exécute à la suite toute l'analyse de vos données de séquençage. Vous pouvez utiliser pour cela des logiciels tel que Galaxy, déjà présenté sur le blog (Galaxy ). Mais il existe de nombreuses méthodes et je présenterai dans un prochain article comment utiliser le système de queue d'un cluster pour construire un pipeline plus complexe.
En attendant n'hésitez pas à faire part des méthodes que vous utilisez dans les commentaires et si l'envie vous en prend, faites un article et proposez-le aux admins, nous sommes toujours contents d'avoir de nouvelles méthodes à partager/publier.
Je tiens à remercier Yoann, Nolwenn et Nelly pour leur relecture.
Laisser un commentaire