{"id":1588,"date":"2015-10-01T11:21:21","date_gmt":"2015-10-01T15:21:21","guid":{"rendered":"http:\/\/bioinfo.iric.ca\/fr\/?p=1588"},"modified":"2022-06-09T12:35:37","modified_gmt":"2022-06-09T12:35:37","slug":"manipuler-de-gros-fichiers","status":"publish","type":"post","link":"https:\/\/bioinfo.iric.ca\/fr\/manipuler-de-gros-fichiers\/","title":{"rendered":"Manipuler de gros fichiers"},"content":{"rendered":"<p>\u00c0 la plateforme, je fais r\u00e9guli\u00e8rement des analyses de donn\u00e9es de s\u00e9quen\u00e7age de nouvelle g\u00e9n\u00e9ration (<em>Next Generation Sequencing<\/em> ou NGS).  L&rsquo;une des questions qui revient fr\u00e9quemment chez mes clients est : comment ouvrir les fichiers de s\u00e9quences g\u00e9n\u00e9r\u00e9s?  Consid\u00e9rant l&rsquo;\u00e9norme taille de ces fichiers (souvent plusieurs millions de lignes) et, par cons\u00e9quent, l&rsquo;espace qu&rsquo;ils requi\u00e8rent en m\u00e9moire, ils ne devraient pas \u00eatre ouverts d&rsquo;une quelconque fa\u00e7on, ils devraient plut\u00f4t \u00eatre<em> process\u00e9s<\/em>.<\/p>\n<p>La plupart des programmes con\u00e7us pour traiter les donn\u00e9es de NGS proc\u00e8dent s\u00e9quentiellement (<em>stream<\/em>), c&rsquo;est-\u00e0-dire qu&rsquo;ils chargent seulement la quantit\u00e9 de donn\u00e9es requise du disque en m\u00e9moire, la traitent, produisent en sortie un r\u00e9sultat et lib\u00e8rent la m\u00e9moire utilis\u00e9e.<\/p>\n<p>Historiquement, les ordinateurs n&rsquo;ont jamais eu autant de m\u00e9moire vive (RAM).  Ainsi, dans les ann\u00e9es 70 (!), une multitude d&rsquo;outils ont \u00e9t\u00e9 d\u00e9velopp\u00e9s sous UNIX pour effectuer ce genre d&rsquo;op\u00e9rations directement dans un terminal.  Ces outils sont maintenant couramment utilis\u00e9s et sont disponibles par d\u00e9faut sous Linux et MacOS.  <\/p>\n<p>Je pr\u00e9senterai ici quelques-uns des outils les plus utiles pour manipuler et traiter de larges fichiers.   Les outils pr\u00e9sent\u00e9s sont de plus des incontournables pour construire de petits <em>pipelines<\/em> pour l&rsquo;analyse de donn\u00e9es de NGS. <\/p>\n<p><strong>sed<\/strong><\/p>\n<p><em>sed<\/em> est apparu en 1974 comme un \u00e9diteur de flux (abr\u00e9viation de Stream EDitor, \u00ab \u00e9diteur de flux \u00bb) pour UNIX capable d&rsquo;effectuer toutes sortes de manipulations sur des fichiers textes.  Son utilisation la plus fr\u00e9quente est probablement comme outil de remplacement de texte m\u00eame si plusieurs autres fonctionnalit\u00e9s sont <a href=\"http:\/\/sed.sourceforge.net\/sed1line.txt\">disponibles<\/a>.  Par exemple, supposons que vous t\u00e9l\u00e9chargez une annotation de g\u00e8nes de Ensembl et que vous r\u00e9alisez apr\u00e8s coup que les chromosomes sont num\u00e9rot\u00e9s de 1 \u00e0 MT alors que dans votre g\u00e9nome de r\u00e9f\u00e9rence, ils \u00e9taient num\u00e9rot\u00e9s de chr1 \u00e0 chrM.  Deux appels cons\u00e9cutifs \u00e0 <em>sed<\/em> vous permettront de convertir le format de l&rsquo;un vers l&rsquo;autre: <\/p>\n<pre><code class=\"bash\">sed 's\/^\/chr\/g' Homo_sapiens.GRCh37.75.gtf | sed 's\/chrMT\/chrM\/g' > Homo_sapiens.GRCh37.75.modified.gtf<\/code><\/pre>\n<p><em>sed<\/em> peut aussi \u00eatre utile pour extraire des parties d&rsquo;un fichier.  Pour un simple fichier delimit\u00e9 par des tabulations (<em>tab-delimited<\/em>), un champ donn\u00e9, disons le champ x, peut \u00eatre extrait facilement avec la commande <em>cut -f x <file><\/em>.  Par contre, pour un cas moins bien structur\u00e9, par exemple un fichier GTF o\u00f9 les attributs sont conserv\u00e9s sous forme de liste sans ordre particulier, vous aurez besoin de la puissance de <em>sed<\/em> et des expressions r\u00e9guli\u00e8res pour extraire le champ d\u00e9sir\u00e9.  Par exemple, pour extraire le nom des g\u00e8nes dans un fichier GTF, en sachant que le huiti\u00e8me champ contient une cha\u00eene de caract\u00e8res similaire \u00e0 <em>gene_name \u00ab\u00a0GAPDH\u00a0\u00bb<\/em>, vous pouvez utiliser la commande <em>sed<\/em> suivante pour r\u00e9cup\u00e9rer cette portion de chacune des lignes : <\/p>\n<pre><code class=\"bash\">sed 's\/.*gene_name \"\\([^\"]*\\)\".*;\/\\1\/g' Homo_sapiens.GRCh37.75.gtf<\/code><\/pre>\n<p>Vous pouvez ensuite diriger (<em>pipe<\/em>) le r\u00e9sultat vers deux autres commandes tr\u00e8s utiles, <em>sort<\/em> et <em>uniq<\/em>, pour obtenir une liste non redondante de tous les g\u00e8nes.<\/p>\n<pre><code class=\"bash\">sed 's\/.*gene_name \"\\([^\"]*\\)\".*;\/\\1\/g' Homo_sapiens.GRCh37.75.gtf | sort | uniq > gene_list.txt\r\n<\/code><\/pre>\n<p><strong>awk<\/strong><br \/>\n<em>awk<\/em> a \u00e9t\u00e9 d\u00e9velopp\u00e9 quelques ann\u00e9es plus tard, en 1977, avec un but similaire en t\u00eate, c&rsquo;est-\u00e0-dire faciliter les modifications de fichiers texte une ligne \u00e0 la fois.  <em>awk<\/em> offre par contre un plus grand nombre de fonctionnalit\u00e9s.  En particulier, il permet l&rsquo;utilisation de conditions et de variables.  Prenons un exemple.  Supposons que vous voulez calculer la couverture moyenne de r\u00e9gions sp\u00e9cifiques dans une exp\u00e9rience de capture d&rsquo;exome.  Vous pouvez utiliser les excellents outils de <a href=\"http:\/\/bedtools.readthedocs.org\">bedtools<\/a> pour calculer, dans un premier temps, la profondeur \u00e0 chacune des positions des \u00e9l\u00e9ments d&rsquo;un fichier d&rsquo;annotation et diriger ce r\u00e9sultat vers <em>awk<\/em> pour obtenir la valeur moyenne de couverture.  Dans ce cas-ci, le dernier champ de chaque ligne ($NF) est additionn\u00e9 pour faire une somme, mais seule la moyenne est retourn\u00e9e en sortie.<\/p>\n<pre><code class=\"bash\">bedtools coverage -d  -a targets.bed -b sample.bam -split \\\r\n| awk '($1 == \"chr1\") { sum += $NF } END { print sum\/NR }'\r\n<\/code><\/pre>\n<p><strong>Redirection de flux (<em>Stream redirection<\/em>)<\/strong><\/p>\n<p>Dans l&rsquo;exemple pr\u00e9c\u00e9dent, nous avons sauv\u00e9 de l&rsquo;espace disque en n&rsquo;\u00e9crivant pas la sortie de bedtools sur le disque.  Toutefois, si nous voulons maintenant calculer le nombre de bases ayant une couverture sup\u00e9rieure ou \u00e9gale \u00e0 20X, il faudrait attendre quelques minutes pendant que nous recalculons la couverture ou bien il faudrait sauver le r\u00e9sultats interm\u00e9diaire sur le disque (typiquement quelques GB).  Nous pouvons optimiser ceci en utilisant la commande <em>tee<\/em>.<\/p>\n<p>Cet outil est utilis\u00e9 pour s\u00e9parer la sortie standard (<em>standard output<\/em>) d&rsquo;un programme pour qu&rsquo;elle puisse \u00eatre \u00e0 la fois affich\u00e9e et sauvegard\u00e9e dans un fichier.  En utilisant quelques trucs additionnels, nous pouvons diriger la sortie vers deux processus \u00e0 la fois : <\/p>\n<pre><code class=\"bash\">bedtools coverage -d -a targets.bed -b sample.bam -split \\\r\n | tee >(awk '{ sum += $NF } END { print sum\/NR }' > coverage_mean.txt) \\\r\n | awk '$NF>=20' | wc -l > coverage_20x.txt\r\n<\/code><\/pre>\n<p>Un dernier exemple concernant les donn\u00e9es \u00e0 passer en entr\u00e9e (<em>input<\/em>) \u00e0 des programmes, plus particuli\u00e8rement quand vous voulez utiliser la sortie d&rsquo;un programme comme entr\u00e9e d&rsquo;un autre programme qui n&rsquo;a ps \u00e9t\u00e9 con\u00e7u pour accepter <em>stdin<\/em> comme entr\u00e9e ou si vous voulez diriger deux <em>stdout<\/em> en m\u00eame temps vers le m\u00eame programme. Reprenons l&rsquo;exemple utilisant bedtools encore une fois. Nous pouvons calculer la couverture sur le chromosome 1 en utilisant l&rsquo;unique commande suivante : <\/p>\n<pre><code class=\"bash\">bedtools coverage -d  -a <(grep ^chr1 targets.bed) -b <(samtools view sample.bam chr1) -split<\/code><\/pre>\n<p>Ici, nous avons remplac\u00e9 les param\u00e8tres de fichiers (-a et -b) par des appels \u00e0 d'autres commandes.  En arri\u00e8re-plan, des descripteurs de fichiers seront cr\u00e9\u00e9s comme tampons pour diriger les donn\u00e9es entre les programmes, mais encore une fois, rien ne sera \u00e9crit sur disque.<\/p>\n<p>\u00c9videmment, nous n'avons survol\u00e9 ici que la surface de toutes les fonctionnalit\u00e9s offertes par les commandes UNIX dans le terminal.  Plusieurs autres outils existent et m\u00e9ritent d'\u00eatre mentionn\u00e9s notamment <em>grep<\/em>, <em>cat<\/em>, <em>join<\/em>, <em>cut<\/em>, <em>wc<\/em>, etc.  Je vous encourage \u00e0 aller y jeter un coup d'oeil pour am\u00e9liorer vos comp\u00e9tences en mati\u00e8re de scripts (<em>shell scripting<\/em>)!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00c0 la plateforme, je fais r\u00e9guli\u00e8rement des analyses de donn\u00e9es de s\u00e9quen\u00e7age de nouvelle g\u00e9n\u00e9ration (Next Generation Sequencing ou NGS). L&rsquo;une des questions qui revient fr\u00e9quemment chez mes clients est : comment ouvrir les fichiers de s\u00e9quences g\u00e9n\u00e9r\u00e9s? Consid\u00e9rant l&rsquo;\u00e9norme taille de ces fichiers (souvent plusieurs millions de lignes) et, par cons\u00e9quent, l&rsquo;espace qu&rsquo;ils requi\u00e8rent en m\u00e9moire, ils ne devraient pas \u00eatre ouverts d&rsquo;une quelconque fa\u00e7on, ils devraient plut\u00f4t \u00eatre process\u00e9s. La plupart des programmes con\u00e7us pour traiter les donn\u00e9es <a href=\"https:\/\/bioinfo.iric.ca\/fr\/manipuler-de-gros-fichiers\/\"> [&#8230;]<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[161,69,70],"tags":[151,93],"class_list":["post-1588","post","type-post","status-publish","format-standard","hentry","category-analyse-de-donnees-fr","category-analyse-de-donnees","category-scripts","tag-manipulation-de-fichier","tag-megadonnees"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/posts\/1588","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/comments?post=1588"}],"version-history":[{"count":14,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/posts\/1588\/revisions"}],"predecessor-version":[{"id":100113,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/posts\/1588\/revisions\/100113"}],"wp:attachment":[{"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/media?parent=1588"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/categories?post=1588"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/tags?post=1588"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}