Aller au contenu

Partie 4 : Hello Modules

Traduction assistée par IA - en savoir plus et suggérer des améliorations

Voir la playlist complète sur la chaîne YouTube de Nextflow.

📗 La transcription de la vidéo est disponible ici.

Cette section couvre comment organiser votre code de workflow pour rendre le développement et la maintenance de votre pipeline plus efficaces et durables. Plus précisément, nous allons démontrer comment utiliser des modules.

Dans Nextflow, un module est un fichier de code autonome, encapsulant souvent une définition de processus unique. Pour utiliser un module dans un workflow, vous ajoutez simplement une instruction include sur une seule ligne à votre fichier de code de workflow ; ensuite vous pouvez intégrer le process dans le workflow de la même manière que vous le feriez normalement. Cela permet de réutiliser des définitions de process dans plusieurs workflows sans produire plusieurs copies du code.

Quand nous avons commencé à développer notre workflow, nous avons tout écrit dans un seul fichier de code. Maintenant, nous allons déplacer les process dans des modules individuels.

hello-modules.nfsayHello.nfconvertToUpper.nfcollectGreetings.nfincludemodules/sayHelloconvertToUppercollectGreetings

Cela rendra notre code plus partageable, flexible et maintenable.

Comment commencer à partir de cette section

Cette section du cours suppose que vous avez complété les Parties 1-3 du cours Hello Nextflow, mais si vous êtes à l'aise avec les bases couvertes dans ces sections, vous pouvez commencer ici sans rien faire de spécial.


0. Échauffement : Exécuter hello-modules.nf

Nous allons utiliser le script de workflow hello-modules.nf comme point de départ. Il est équivalent au script produit en travaillant à travers la Partie 3 de ce cours de formation, sauf que nous avons changé les destinations de sortie :

hello-modules.nf
output {
    first_output {
        path 'hello_modules'
        mode 'copy'
    }
    uppercased {
        path 'hello_modules'
        mode 'copy'
    }
    collected {
        path 'hello_modules'
        mode 'copy'
    }
    batch_report {
        path 'hello_modules'
        mode 'copy'
    }
}

Juste pour s'assurer que tout fonctionne, exécutez le script une fois avant d'effectuer des modifications :

nextflow run hello-modules.nf
Sortie de la commande
 N E X T F L O W   ~  version 25.10.2

Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d

executor >  local (7)
[0f/8795c9] sayHello (3)       [100%] 3 of 3 ✔
[6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔
[af/479117] collectGreetings   [100%] 1 of 1 ✔

Comme précédemment, vous trouverez les fichiers de sortie dans le répertoire spécifié dans le bloc output (ici, results/hello_modules/).

Contenu du répertoire
results/hello_modules/
├── Bonjour-output.txt
├── COLLECTED-batch-output.txt
├── Hello-output.txt
├── Holà-output.txt
├── batch-report.txt
├── UPPER-Bonjour-output.txt
├── UPPER-Hello-output.txt
└── UPPER-Holà-output.txt

Si cela a fonctionné pour vous, vous êtes prêt·e à apprendre comment modulariser votre code de workflow.


1. Créer un répertoire pour stocker les modules

Il est recommandé de stocker vos modules dans un répertoire spécifique. Vous pouvez appeler ce répertoire comme vous le souhaitez, mais la convention est de l'appeler modules/.

mkdir modules

2. Créer un module pour sayHello()

Dans sa forme la plus simple, transformer un process existant en module n'est guère plus qu'une opération de copier-coller. Nous allons créer un fichier stub pour le module, copier le code pertinent puis le supprimer du fichier de workflow principal.

Ensuite, tout ce que nous aurons à faire est d'ajouter une instruction include pour que Nextflow sache récupérer le code pertinent à l'exécution.

2.1. Créer un fichier stub pour le nouveau module

Créons un fichier vide pour le module appelé sayHello.nf.

touch modules/sayHello.nf

Cela nous donne un endroit pour mettre le code du process.

2.2. Déplacer le code du processus sayHello vers le fichier module

Copiez l'ensemble de la définition du process du fichier de workflow vers le fichier module.

modules/sayHello.nf
/*
 * Utilise echo pour imprimer 'Hello World!' dans un fichier
 */
process sayHello {

    input:
    val greeting

    output:
    path "${greeting}-output.txt"

    script:
    """
    echo '${greeting}' > '${greeting}-output.txt'
    """
}

Une fois cela fait, supprimez la définition du process du fichier de workflow.

2.3. Ajouter une déclaration d'importation avant le bloc workflow

La syntaxe pour inclure un process depuis un module est assez simple :

Syntaxe : Déclaration d'importation
include { <NOM_DU_PROCESS> } from '<chemin_vers_le_module>'

Insérons cela au-dessus du bloc params et remplissons-le de manière appropriée.

hello-modules.nf
// Inclure les modules
include { sayHello } from './modules/sayHello.nf'

/*
* Paramètres du pipeline
*/
params {
    greeting: Path = 'data/greetings.csv'
    batch: String = 'batch'
}
hello-modules.nf
/*
* Paramètres du pipeline
*/
params {
    greeting: Path = 'data/greetings.csv'
    batch: String = 'batch'
}

Vous voyez que nous avons renseigné le nom du process, sayHello, et le chemin vers le fichier contenant le code du module, ./modules/sayHello.nf.

2.4. Exécuter le workflow

Nous exécutons le workflow avec essentiellement le même code et les mêmes entrées qu'avant, donc exécutons avec le flag -resume et voyons ce qui se passe.

nextflow run hello-modules.nf -resume
Sortie de la commande
N E X T F L O W   ~  version 25.10.2

Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3

[f6/cc0107] sayHello (1)       | 3 of 3, cached: 3 ✔
[3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔
[1a/bc5901] collectGreetings   | 1 of 1, cached: 1 ✔

Cela devrait s'exécuter très rapidement car tout est en cache. N'hésitez pas à vérifier les sorties publiées.

Nextflow a reconnu que c'est toujours le même travail à faire, même si le code est divisé en plusieurs fichiers.

À retenir

Vous savez comment extraire un process dans un module local et vous savez que faire cela ne casse pas la reprise du workflow.

Et ensuite ?

Pratiquez la création de plus de modules. Une fois que vous en avez fait un, vous pouvez en faire un million de plus... Mais faisons-en juste deux de plus pour l'instant.


3. Modulariser le processus convertToUpper()

3.1. Créer un fichier stub pour le nouveau module

Créez un fichier vide pour le module appelé convertToUpper.nf.

touch modules/convertToUpper.nf

3.2. Déplacer le code du processus convertToUpper vers le fichier module

Copiez l'ensemble de la définition du process du fichier de workflow vers le fichier module.

modules/convertToUpper.nf
/*
 * Utilise un outil de remplacement de texte pour convertir la salutation en majuscules
 */
process convertToUpper {

    input:
    path input_file

    output:
    path "UPPER-${input_file}"

    script:
    """
    cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}'
    """
}

Une fois cela fait, supprimez la définition du process du fichier de workflow.

3.3. Ajouter une déclaration d'importation avant le bloc params

Insérez la déclaration d'importation au-dessus du bloc params et remplissez-la de manière appropriée.

hello-modules.nf
// Inclure les modules
include { sayHello } from './modules/sayHello.nf'
include { convertToUpper } from './modules/convertToUpper.nf'

/*
* Paramètres du pipeline
*/
params {
    greeting: Path = 'data/greetings.csv'
    batch: String = 'batch'
}
hello-modules.nf
// Inclure les modules
include { sayHello } from './modules/sayHello.nf'

/*
* Paramètres du pipeline
*/
params {
    greeting: Path = 'data/greetings.csv'
    batch: String = 'batch'
}

Cela devrait commencer à sembler très familier.

3.4. Exécuter à nouveau le workflow

Exécutez ceci avec le flag -resume.

nextflow run hello-modules.nf -resume
Sortie de la commande
N E X T F L O W   ~  version 25.10.2

Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0

[c9/763d42] sayHello (3)       | 3 of 3, cached: 3 ✔
[60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔
[1a/bc5901] collectGreetings   | 1 of 1, cached: 1 ✔

Cela devrait toujours produire la même sortie que précédemment.

Deux de faits, plus qu'un !


4. Modulariser le processus collectGreetings()

4.1. Créer un fichier stub pour le nouveau module

Créez un fichier vide pour le module appelé collectGreetings.nf.

touch modules/collectGreetings.nf

4.2. Déplacer le code du processus collectGreetings vers le fichier module

Copiez l'ensemble de la définition du process du fichier de workflow vers le fichier module.

modules/collectGreetings.nf
/*
 * Collecter les salutations en majuscules dans un seul fichier de sortie
 */
process collectGreetings {

    input:
    path input_files
    val batch_name

    output:
    path "COLLECTED-${batch_name}-output.txt", emit: outfile
    path "${batch_name}-report.txt", emit: report

    script:
    count_greetings = input_files.size()
    """
    cat ${input_files} > 'COLLECTED-${batch_name}-output.txt'
    echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt'
    """
}

Une fois cela fait, supprimez la définition du process du fichier de workflow.

4.3. Ajouter une déclaration d'importation avant le bloc params

Insérez la déclaration d'importation au-dessus du bloc params et remplissez-la de manière appropriée.

hello-modules.nf
// Inclure les modules
include { sayHello } from './modules/sayHello.nf'
include { convertToUpper } from './modules/convertToUpper.nf'
include { collectGreetings } from './modules/collectGreetings.nf'

/*
* Paramètres du pipeline
*/
params {
    greeting: Path = 'data/greetings.csv'
    batch: String = 'batch'
}
hello-modules.nf
// Inclure les modules
include { sayHello } from './modules/sayHello.nf'
include { convertToUpper } from './modules/convertToUpper.nf'

/*
* Paramètres du pipeline
*/
params {
    greeting: Path = 'data/greetings.csv'
    batch: String = 'batch'
}

Dernier !

4.4. Exécuter le workflow

Exécutez ceci avec le flag -resume.

nextflow run hello-modules.nf -resume
Sortie de la commande
N E X T F L O W   ~  version 25.10.2

Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f

[f6/cc0107] sayHello (1)       | 3 of 3, cached: 3 ✔
[3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔
[1a/bc5901] collectGreetings   | 1 of 1, cached: 1 ✔

Cela devrait toujours produire la même sortie que précédemment.

À retenir

Vous savez comment modulariser plusieurs process dans un workflow.

Félicitations, vous avez fait tout ce travail et absolument rien n'a changé dans le fonctionnement du pipeline !

Blague à part, maintenant votre code est plus modulaire, et si vous décidez d'écrire un autre pipeline qui fait appel à l'un de ces process, vous n'avez qu'à taper une courte instruction include pour utiliser le module pertinent. C'est mieux que de copier-coller le code, parce que si plus tard vous décidez d'améliorer le module, tous vos pipelines hériteront des améliorations.

Et ensuite ?

Prenez une courte pause si vous le souhaitez.

Quand vous êtes prêt·e, passez à la Partie 5 : Hello Containers pour apprendre comment utiliser les conteneurs pour gérer les dépendances logicielles de manière plus pratique et reproductible.


Quiz

#

Qu'est-ce qu'un module dans Nextflow ?

#

Quelle convention est généralement utilisée pour stocker les fichiers de modules ?

#

Quelle est la syntaxe correcte pour utiliser un module ?

#

Que se passe-t-il avec la fonctionnalité -resume lors de l'utilisation de modules ?

#

Quels sont les avantages de l'utilisation de modules ? (Sélectionnez toutes les réponses applicables)