Salta el contingut

Part 3: Utilitzar un mòdul nf-core

Traducció assistida per IA - més informació i suggeriments

En aquesta tercera part del curs de formació Hello nf-core, us mostrem com trobar, instal·lar i utilitzar un mòdul nf-core existent al vostre pipeline.

Un dels grans avantatges de treballar amb nf-core és la capacitat d'aprofitar mòduls preconstruïts i provats del repositori nf-core/modules. En lloc d'escriure cada procés des de zero, podeu instal·lar i utilitzar mòduls mantinguts per la comunitat que segueixen les millors pràctiques.

Per demostrar com funciona això, substituirem el mòdul personalitzat collectGreetings pel mòdul find/concatenate de nf-core/modules al pipeline core-hello.

Com començar des d'aquesta secció

Aquesta secció del curs assumeix que heu completat la Part 2: Reescriure Hello per a nf-core i teniu un pipeline core-hello funcional.

Si no heu completat la Part 2 o voleu començar de nou per a aquesta part, podeu utilitzar la solució core-hello-part2 com a punt de partida. Executeu aquesta comanda des del directori hello-nf-core/:

cp -r solutions/core-hello-part2 core-hello
cd core-hello

Això us proporciona un pipeline nf-core completament funcional preparat per afegir mòduls. Podeu comprovar que s'executa correctament executant la comanda següent:

nextflow run . --outdir core-hello-results -profile test,docker

1. Trobar i instal·lar un mòdul nf-core adequat

Primer, aprendrem com trobar un mòdul nf-core existent i instal·lar-lo al nostre pipeline.

Volem substituir el procés collectGreetings, que utilitza la comanda Unix cat per concatenar múltiples fitxers de salutacions en un de sol. Concatenar fitxers és una operació molt comuna, així que és raonable pensar que ja podria existir un mòdul a nf-core dissenyat per a aquest propòsit.

Comencem.

1.1. Explorar els mòduls disponibles al lloc web d'nf-core

El projecte nf-core manté un catàleg centralitzat de mòduls a https://nf-co.re/modules.

Navegueu a la pàgina de mòduls al vostre navegador web i utilitzeu la barra de cerca per cercar 'concatenate'.

resultats de cerca de mòduls

Com podeu veure, hi ha força resultats, molts d'ells mòduls dissenyats per concatenar tipus de fitxers molt específics. Entre ells, hauríeu de veure un anomenat find_concatenate que és de propòsit general.

Convenció de nomenclatura de mòduls

El guió baix (_) s'utilitza com a substitut del caràcter barra (/) als noms de mòduls.

Els mòduls nf-core segueixen la convenció de nomenclatura programari/comanda quan una eina proporciona múltiples comandes, com samtools/view (paquet samtools, comanda view) o gatk/haplotypecaller (paquet GATK, comanda HaplotypeCaller). Per a eines que només proporcionen una comanda principal, els mòduls utilitzen un sol nivell com fastqc o multiqc.

Feu clic a la caixa del mòdul find_concatenate per veure la documentació del mòdul.

La pàgina del mòdul mostra:

  • Una breu descripció: "A module for concatenation of gzipped or uncompressed files getting around UNIX terminal argument size"
  • Comanda d'instal·lació: nf-core modules install find/concatenate
  • Estructura del canal d'entrada i sortida
  • Paràmetres disponibles

1.2. Llistar els mòduls disponibles des de la línia de comandes

Alternativament, també podeu cercar mòduls directament des de la línia de comandes utilitzant les eines nf-core.

nf-core modules list remote
Sortida de la comanda (truncada)
...
│ fastqc                                                │
│ find/concatenate                                      │
│ gatk4/applybqsr                                       │
│ gatk4/baserecalibrator                                │
...

Això mostrarà una llista de tots els mòduls disponibles al repositori nf-core/modules, tot i que és una mica menys convenient si no coneixeu ja el nom del mòdul que esteu cercant. No obstant això, si el coneixeu, podeu canalitzar la llista a grep per trobar mòduls específics:

nf-core modules list remote | grep 'find/concatenate'
Sortida de la comanda
│ find/concatenate                                      │

Tingueu en compte que l'enfocament amb grep només extraurà resultats amb el terme de cerca al seu nom.

1.3. Obtenir informació detallada sobre el mòdul

Per veure informació detallada sobre un mòdul específic des de la línia de comandes, utilitzeu la comanda info:

nf-core modules info find/concatenate

Això mostra documentació sobre el mòdul, incloent les seves entrades, sortides i informació bàsica d'ús.

Sortida de la comanda
                                          ,--./,-.
          ___     __   __   __   ___     /,-._.--~\
    |\ | |__  __ /  ` /  \ |__) |__         }  {
    | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                          `._,._,'

    nf-core/tools version 4.0.2 - https://nf-co.re


INFO     Reinstalling modules found in 'modules.json' but missing from
         directory:
╭─ Module: find/concatenate  ──────────────────────────────────────────────────╮
│ 🌐 Repository: https://github.com/nf-core/modules.git                        │
│ 🔧 Tools: find, pigz                                                         │
│ 📖 Description: A module for concatenation of gzipped or uncompressed files  │
│ getting around UNIX terminal argument size                                   │
╰──────────────────────────────────────────────────────────────────────────────╯
                  ╷                                                    ╷
 📥 Inputs        │Description                                         │Pattern
╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸
 input[0]         │                                                    │
╶─────────────────┼────────────────────────────────────────────────────┼───────╴
  meta  (map)     │Groovy Map containing sample information e.g. [     │
                  │id:'test' ]                                         │
╶─────────────────┼────────────────────────────────────────────────────┼───────╴
  files_in  (file)│List of either compressed or uncompressed files     │      *
                  ╵                                                    ╵
                                  ╷                                ╷
 📥 Outputs                       │Description                     │    Pattern
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━╸
 file_out                         │                                │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  meta  (map)                     │Groovy Map containing sample    │
                                  │information e.g. [ id:'test' ]  │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  ${prefix}  (file)               │Concatenated file. Will be      ${file_out}
                                  │gzipped if ${prefix} ends with  │
                                  │".gz" or inputs are gzipped,    │
                                  │will be uncompressed otherwise. │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
 versions_find                    │                                │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  ${task.process}  (string)       │The name of the process         ╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  find  (string)                  │The name of the tool            │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  find --version | sed '1!d; s/.* │The expression to obtain the    │
 //'  (eval)                      │version of the tool             │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
 versions_pigz                    │                                │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  ${task.process}  (string)       │The name of the process         ╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  pigz  (string)                  │The name of the tool            │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  pigz --version 2>&1 | sed       │The expression to obtain the    │
 's/pigz //g'  (eval)             │version of the tool             │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
 versions_coreutils               │                                │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  ${task.process}  (string)       │The name of the process         ╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  coreutils  (string)             │The name of the tool            │
╶─────────────────────────────────┼────────────────────────────────┼───────────╴
  cat --version | sed '1!d; s/.*  │The expression to obtain the    │
 //'  (eval)                      │version of the tool             │
                                  ╵                                ╵

 💻  Installation command: nf-core modules install find/concatenate

Aquesta és exactament la mateixa informació que podeu trobar al lloc web.

Podeu ignorar el missatge INFO Reinstalling modules found in 'modules.json' but missing from directory; l'emet nf-core/tools 4.0.2 per a qualsevol mòdul que consulteu amb info, estigui o no instal·lat, i no té cap efecte ja que la comanda info no escriu cap fitxer.

1.4. Instal·lar el mòdul find/concatenate

Ara que hem trobat el mòdul que volem, hem d'afegir-lo al codi font del nostre pipeline.

La bona notícia és que el projecte nf-core inclou eines per facilitar aquesta part. Específicament, la comanda nf-core modules install permet automatitzar la recuperació del codi i fer-lo disponible al vostre projecte en un sol pas.

Assegureu-vos que el vostre directori de treball actual és l'arrel del projecte de pipeline core-hello i executeu la comanda d'instal·lació:

cd core-hello
nf-core modules install find/concatenate
Sortida de la comanda
                                      ,--./,-.
      ___     __   __   __   ___     /,-._.--~\
|\ | |__  __ /  ` /  \ |__) |__         }  {
| \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                      `._,._,'

nf-core/tools version 4.0.2 - https://nf-co.re


INFO     Installing 'find/concatenate'
NotADirectoryError: [Errno 20] Not a directory:
'modules/local/cowpy.nf/meta.yml'

La comanda descarrega els fitxers del mòdul a modules/nf-core/find/concatenate/ i actualitza modules.json per fer seguiment del mòdul instal·lat. Podeu ignorar el NotADirectoryError al final; es produeix perquè nf-core/tools 4.0.2 espera que cada mòdul local resideixi al seu propi directori (modules/local/<nom>/main.nf), mentre que core-hello encara utilitza mòduls locals d'un sol fitxer en aquesta etapa. No obstant això, el mòdul find/concatenate s'instal·la correctament i modules.json s'actualitza com s'espera. Convertirem cowpy a l'estructura de directoris a la Part 4.

Comprovem que els fitxers del mòdul estan al seu lloc:

tree -L 4 modules
Contingut del directori
modules
├── local
│   ├── collectGreetings.nf
│   ├── convertToUpper.nf
│   ├── cowpy.nf
│   └── sayHello.nf
└── nf-core
    └── find
        └── concatenate
            ├── environment.yml
            ├── main.nf
            ├── meta.yml
            └── tests

5 directories, 7 files

També podeu confirmar la instal·lació inspeccionant modules.json, que ara llista find/concatenate sota el repositori nf-core/modules.

Contingut del fitxer
modules.json
{
    "name": "core/hello",
    "homePage": "https://github.com/core/hello",
    "repos": {
        "https://github.com/nf-core/modules.git": {
            "modules": {
                "nf-core": {
                    "find/concatenate": {
                        "branch": "master",
                        "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120",
                        "installed_by": [
                            "modules"
                        ]
                    }
                }
            },
            "subworkflows": {
                "nf-core": {
                    "utils_nextflow_pipeline": {
                        "branch": "master",
                        "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d",
                        "installed_by": [
                            "subworkflows"
                        ]
                    },
                    "utils_nfcore_pipeline": {
                        "branch": "master",
                        "git_sha": "a3fb7351b1fdb2b1de282b765816bbea190e86a8",
                        "installed_by": [
                            "subworkflows"
                        ]
                    },
                    "utils_nfschema_plugin": {
                        "branch": "master",
                        "git_sha": "fdc08b8b1ae74f56686ce21f7ea11ad11990ce57",
                        "installed_by": [
                            "subworkflows"
                        ]
                    }
                }
            }
        }
    }
}

Això confirma que el mòdul find/concatenate ara forma part del codi font del vostre projecte. No obstant això, per utilitzar realment el nou mòdul, hem d'importar-lo al nostre pipeline.

Finalment, també podeu utilitzar la comanda nf-core modules list local per comprovar quins mòduls es fan seguiment actualment al vostre pipeline.

nf-core modules list local
Sortida de la comanda
                                      ,--./,-.
      ___     __   __   __   ___     /,-._.--~\
|\ | |__  __ /  ` /  \ |__) |__         }  {
| \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                      `._,._,'

nf-core/tools version 4.0.2 - https://nf-co.re


INFO     Repository type: pipeline
INFO     Modules installed in '.':

┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Module Name      ┃ Repository      ┃ Version SHA ┃ Message                                                                       ┃ Date       ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ find/concatenate │ nf-core/modules │ 6d46786     │ Support for apptainer as well as singularity for .sif in `container` (#11260) │ 2026-04-23 │
└──────────────────┴─────────────────┴─────────────┴───────────────────────────────────────────────────────────────────────────────┴────────────┘

Això mostra find/concatenate a la taula resultant juntament amb el seu repositori, SHA de versió, missatge i data.

1.5. Actualitzar les importacions de mòduls

Substituïm la declaració include del mòdul collectGreetings per la de FIND_CONCATENATE a la secció d'importacions del workflow workflows/hello.nf.

Com a recordatori, l'eina d'instal·lació de mòduls ens va proporcionar la declaració exacta a utilitzar:

Import statement produced by install command
include { FIND_CONCATENATE } from '../modules/nf-core/find/concatenate/main'

Tingueu en compte que la convenció nf-core és utilitzar majúscules per als noms de mòduls quan s'importen.

Obriu core-hello/workflows/hello.nf i feu la substitució següent:

core-hello/workflows/hello.nf
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
include { paramsSummaryMap       } from 'plugin/nf-schema'
include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline'
include { sayHello               } from '../modules/local/sayHello.nf'
include { convertToUpper         } from '../modules/local/convertToUpper.nf'
include { FIND_CONCATENATE       } from '../modules/nf-core/find/concatenate/main'
include { cowpy                  } from '../modules/local/cowpy.nf'
core-hello/workflows/hello.nf
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
include { paramsSummaryMap       } from 'plugin/nf-schema'
include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline'
include { sayHello               } from '../modules/local/sayHello.nf'
include { convertToUpper         } from '../modules/local/convertToUpper.nf'
include { collectGreetings       } from '../modules/local/collectGreetings.nf'
include { cowpy                  } from '../modules/local/cowpy.nf'

Observeu com el camí per al mòdul nf-core difereix dels mòduls locals:

  • Mòdul nf-core: '../modules/nf-core/find/concatenate/main' (referència a main.nf)
  • Mòdul local: '../modules/local/collectGreetings.nf' (referència a un sol fitxer)

El mòdul ara està disponible per al workflow, així que només cal que substituïm la crida a collectGreetings per utilitzar FIND_CONCATENATE. Oi?

No tan ràpid.

En aquest punt, podríeu estar temptats de començar a editar codi, però val la pena prendre's un moment per examinar acuradament què espera el nou mòdul i què produeix.

Tractarem això com una secció separada perquè implica un nou mecanisme que encara no hem cobert: els mapes de metadades.

Info

Opcionalment podeu eliminar el fitxer collectGreetings.nf:

rm modules/local/collectGreetings.nf

No obstant això, potser voldreu conservar-lo com a referència per entendre les diferències entre mòduls locals i nf-core.

Conclusió

Sabeu com trobar un mòdul nf-core i fer-lo disponible al vostre projecte.

Què segueix?

Avaluar què requereix un nou mòdul i identificar qualsevol canvi important necessari per integrar-lo a un pipeline.


2. Avaluar els requisits del nou mòdul

Específicament, hem d'examinar la interfície del mòdul, és a dir, les seves definicions d'entrada i sortida, i comparar-la amb la interfície del mòdul que volem substituir. Això ens permetrà determinar si podem tractar el nou mòdul com un reemplaçament directe o si haurem d'adaptar part del cablejat.

Idealment això és quelcom que hauríeu de fer abans fins i tot d'instal·lar el mòdul, però bé, més val tard que mai. (Per cert, hi ha una comanda uninstall per desfer-se dels mòduls que decidiu que ja no voleu.)

Info

El procés FIND_CONCATENATE inclou una gestió força intel·ligent de diferents tipus de compressió, extensions de fitxer i altres aspectes que no són estrictament rellevants per al que intentem mostrar-vos aquí, així que ignorarem la major part i ens centrarem només en les parts que són importants.

2.1. Comparar les interfícies dels dos mòduls

Com a recordatori, així és com es veu la interfície del nostre mòdul collectGreetings:

modules/local/collectGreetings.nf (excerpt)
process collectGreetings {

    publishDir 'results', mode: 'copy'

    input:
        path input_files
        val batch_name

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

El mòdul collectGreetings pren dues entrades:

  • input_files conté un o més fitxers d'entrada a processar;
  • batch_name és un valor que utilitzem per assignar un nom específic de l'execució al fitxer de sortida, que és una forma de metadades.

En completar-se, collectGreetings produeix un sol camí de fitxer, emès amb l'etiqueta outfile.

En comparació, la interfície del mòdul find/concatenate és més complexa:

modules/nf-core/find/concatenate/main.nf (excerpt)
process FIND_CONCATENATE {
    tag "${meta.id}"
    label 'process_low'

    conda "${moduleDir}/environment.yml"
    container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container
        ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/7f/7fd226561e12b32bcacdf4f5ff74577e76233adf52ae5cbc499a2cdfe0e27d82/data'
        : 'community.wave.seqera.io/library/findutils_pigz:c4dd5edc44402661'}"

    input:
    tuple val(meta), path(files_in)

    output:
    tuple val(meta), path("${prefix}"), emit: file_out
    tuple val("${task.process}"), val("find"), eval("find --version | sed '1!d; s/.* //'"), topic: versions, emit: versions_find
    tuple val("${task.process}"), val("pigz"), eval("pigz --version 2>&1 | sed 's/pigz //g'"), topic: versions, emit: versions_pigz
    tuple val("${task.process}"), val("coreutils"), eval("cat --version | sed '1!d; s/.* //'"), topic: versions, emit: versions_coreutils

El mòdul FIND_CONCATENATE pren una sola entrada, però aquesta entrada és una tupla que conté dues coses:

  • meta és una estructura que conté metadades, anomenada metamap;
  • files_in conté un o més fitxers d'entrada a processar, equivalent a input_files de collectGreetings.

En completar-se, FIND_CONCATENATE lliura les seves sortides en dues parts:

  • Una tupla que conté el metamap i el fitxer de sortida concatenat, emès amb l'etiqueta file_out;
  • Tres tuples de versió (una per eina utilitzada) publicades al canal de tema versions per al seguiment de versions de programari.

Tingueu en compte també que per defecte, el fitxer de sortida es nomenarà basant-se en un identificador que forma part de les metadades (codi no mostrat aquí).

Això pot semblar molt a tenir en compte només mirant el codi, així que aquí teniu un diagrama per ajudar-vos a visualitzar com encaixa tot plegat.

[],[],input_filesfiles_inmetaoutfile${prefix}metacollectGreetingsbatch_namefile_outversions (YML)FIND_CONCATENATE

Podeu veure que els dos mòduls tenen requisits d'entrada similars pel que fa al contingut (un conjunt de fitxers d'entrada més algunes metadades) però expectatives molt diferents sobre com s'empaqueta aquest contingut. Ignorant la sortida de versions per ara, la seva sortida principal també és equivalent (un fitxer concatenat), excepte que FIND_CONCATENATE també emet el metamap conjuntament amb el fitxer de sortida.

Les diferències d'empaquetament seran força fàcils de gestionar, com veureu d'aquí a poc. No obstant això, per entendre la part del metamap, hem d'introduir-vos a algun context addicional.

2.2. Entendre els metamaps

Acabem de dir-vos que el mòdul FIND_CONCATENATE espera un mapa de metadades com a part de la seva tupla d'entrada. Prenguem-nos uns minuts per examinar més de prop què és això.

El mapa de metadades, sovint anomenat metamap per abreujar, és un mapa d'estil Groovy que conté informació sobre unitats de dades. En el context dels pipelines Nextflow, les unitats de dades poden ser qualsevol cosa que vulgueu: mostres individuals, lots de mostres o conjunts de dades complets.

Per convenció, un metamap nf-core s'anomena meta i conté el camp obligatori id, que s'utilitza per nomenar sortides i fer seguiment d'unitats de dades.

Per exemple, un mapa de metadades típic podria tenir aquest aspecte:

Example of sample-level metamap
[id: 'sample1', single_end: false, strandedness: 'forward']

O en un cas on les metadades s'adjunten a nivell de lot:

Example of batch-level metamap
[id: 'batch1', date: '25.10.01']

Ara posem això en el context del procés FIND_CONCATENATE, que espera que els fitxers d'entrada s'empaqueten en una tupla amb un metamap, i també produeix el metamap com a part de la tupla de sortida.

modules/nf-core/find/concatenate/main.nf (excerpt)
input:
tuple val(meta), path(files_in)

output:
tuple val(meta), path("${prefix}"), emit: file_out

Com a resultat, cada unitat de dades viatja pel pipeline amb les metadades rellevants adjuntes. Els processos posteriors poden accedir fàcilment a aquestes metadades també.

Recordeu com us vam dir que el fitxer produït per FIND_CONCATENATE es nomenarà basant-se en un identificador que forma part de les metadades? Aquest és el codi rellevant:

modules/nf-core/find/concatenate/main.nf (excerpt)
prefix = task.ext.prefix ?: "${meta.id}${file_extensions[0]}"

Això es tradueix aproximadament com segueix: si es proporciona un prefix mitjançant el sistema de paràmetres de tasca extern (task.ext), utilitzeu-lo per nomenar el fitxer de sortida; en cas contrari, creeu-ne un utilitzant ${meta.id}, que correspon al camp id del metamap.

Podeu imaginar el canal d'entrada que arriba a aquest mòdul amb continguts com aquest:

Example input channel contents
ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']],
            [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']],
            [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]]

Llavors el contingut del canal de sortida que surt seria així:

Example output channel contents
ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'],
            [[id: 'batch2', date: '25.10.26'], 'batch2.txt'],
            [[id: 'batch3', date: '25.11.14'], 'batch3.txt']]

Com s'ha esmentat anteriorment, la configuració d'entrada tuple val(meta), path(files_in) és un patró estàndard utilitzat a tots els mòduls nf-core.

Esperem que pugueu començar a veure com d'útil pot ser això. No només us permet nomenar sortides basant-vos en metadades, sinó que també podeu fer coses com utilitzar-les per aplicar diferents valors de paràmetres, i en combinació amb operadors específics, fins i tot podeu agrupar, ordenar o filtrar dades mentre flueixen pel pipeline.

Més informació sobre metadades

Per a una introducció completa sobre com treballar amb metadades als workflows Nextflow, incloent com llegir metadades des de fulls de mostres i utilitzar-les per personalitzar el processament, consulteu la missió secundària Metadades als workflows.

2.3. Resumir els canvis a fer

Basant-nos en el que hem revisat, aquests són els canvis principals que hem de fer al nostre pipeline per utilitzar el mòdul find/concatenate:

  • Crear un metamap que contingui el nom del lot;
  • Empaquetar el metamap en una tupla amb el conjunt de fitxers d'entrada a concatenar (provinents de convertToUpper);
  • Canviar la crida de collectGreetings() a FIND_CONCATENATE;
  • Extreure el fitxer de sortida de la tupla produïda pel procés FIND_CONCATENATE abans de passar-lo a cowpy.

Això hauria de ser suficient! Ara que tenim un pla, estem preparats per començar.

Conclusió

Sabeu com avaluar la interfície d'entrada i sortida d'un nou mòdul per identificar els seus requisits, i heu après com els metamaps són utilitzats pels pipelines nf-core per mantenir les metadades estretament associades amb les dades mentre flueixen pel pipeline.

Què segueix?

Integrar el nou mòdul en un workflow.


3. Integrar FIND_CONCATENATE al workflow hello.nf

Ara que sabeu tot sobre els metamaps (o prou per als propòsits d'aquest curs, almenys), és hora d'implementar realment els canvis que hem descrit anteriorment.

Per claredat, dividirem això i cobrirem cada pas per separat.

Info

Tots els canvis mostrats a continuació es fan a la lògica del workflow al bloc main del fitxer de workflow core-hello/workflows/hello.nf.

3.1. Crear un mapa de metadades

Primer, hem de crear un mapa de metadades per a FIND_CONCATENATE, tenint en compte que els mòduls nf-core requereixen que el metamap contingui almenys un camp id.

Com que no necessitem cap altra metadada, podem mantenir-ho simple i utilitzar quelcom així:

Syntax example
def cat_meta = [id: 'test']

Excepte que no volem codificar el valor id de forma fixa; volem utilitzar el valor del parametre params.batch. Així que el codi es converteix en:

Syntax example
def cat_meta = [id: params.batch]

Sí, és literalment així de simple crear un metamap bàsic.

Afegim aquestes línies després de la crida a convertToUpper, eliminant la crida a collectGreetings:

core-hello/workflows/hello.nf
    // emet una salutació (actualitzat per utilitzar la convenció nf-core per a fulls de mostres)
    sayHello(ch_samplesheet)

    // converteix la salutació a majúscules
    convertToUpper(sayHello.out)

    // crea un mapa de metadades amb el nom del lot com a ID
    def cat_meta = [ id: params.batch ]

    // genera art ASCII de les salutacions amb cowpy
    cowpy(collectGreetings.out.outfile, params.character)
core-hello/workflows/hello.nf
    // emet una salutació (actualitzat per utilitzar la convenció nf-core per a fulls de mostres)
    sayHello(ch_samplesheet)

    // converteix la salutació a majúscules
    convertToUpper(sayHello.out)

    // recull totes les salutacions en un fitxer
    collectGreetings(convertToUpper.out.collect(), params.batch)

    // genera art ASCII de les salutacions amb cowpy
    cowpy(collectGreetings.out.outfile, params.character)

Això crea un mapa de metadades simple on l'id s'estableix al nom del nostre lot (que serà test quan s'utilitzi el perfil de test).

3.2. Crear un canal amb tuples de metadades

A continuació, transformeu el canal de fitxers en un canal de tuples que continguin metadades i fitxers:

core-hello/workflows/hello.nf
    // emet una salutació (actualitzat per utilitzar la convenció nf-core per a fulls de mostres)
    sayHello(ch_samplesheet)

    // converteix la salutació a majúscules
    convertToUpper(sayHello.out)

    // crea un mapa de metadades amb el nom del lot com a ID
    def cat_meta = [ id: params.batch ]

    // crea un canal amb metadades i fitxers en format tupla
    ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) }

    // genera art ASCII de les salutacions amb cowpy
    cowpy(collectGreetings.out.outfile, params.character)
core-hello/workflows/hello.nf
    // emet una salutació (actualitzat per utilitzar la convenció nf-core per a fulls de mostres)
    sayHello(ch_samplesheet)

    // converteix la salutació a majúscules
    convertToUpper(sayHello.out)

    // crea un mapa de metadades amb el nom del lot com a ID
    def cat_meta = [ id: params.batch ]

    // genera art ASCII de les salutacions amb cowpy
    cowpy(collectGreetings.out.outfile, params.character)

La línia que hem afegit aconsegueix dues coses:

  • .collect() recull tots els fitxers de la sortida de convertToUpper en una sola llista
  • .map { files -> tuple(cat_meta, files) } crea una tupla de [metadades, fitxers] en el format que FIND_CONCATENATE espera

Això és tot el que necessitem fer per configurar la tupla d'entrada per a FIND_CONCATENATE.

3.3. Cridar el mòdul FIND_CONCATENATE

Ara cridem FIND_CONCATENATE sobre el canal acabat de crear:

core-hello/workflows/hello.nf
    // emet una salutació (actualitzat per utilitzar la convenció nf-core per a fulls de mostres)
    sayHello(ch_samplesheet)

    // converteix la salutació a majúscules
    convertToUpper(sayHello.out)

    // crea un mapa de metadades amb el nom del lot com a ID
    def cat_meta = [ id: params.batch ]

    // crea un canal amb metadades i fitxers en format tupla
    ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) }

    // concatena les salutacions
    FIND_CONCATENATE(ch_for_cat)

    // genera art ASCII de les salutacions amb cowpy
    cowpy(collectGreetings.out.outfile, params.character)
core-hello/workflows/hello.nf
    // emet una salutació (actualitzat per utilitzar la convenció nf-core per a fulls de mostres)
    sayHello(ch_samplesheet)

    // converteix la salutació a majúscules
    convertToUpper(sayHello.out)

    // crea un mapa de metadades amb el nom del lot com a ID
    def cat_meta = [ id: params.batch ]

    // crea un canal amb metadades i fitxers en format tupla
    ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) }

    // genera art ASCII de les salutacions amb cowpy
    cowpy(collectGreetings.out.outfile, params.character)

Això completa la part més complicada d'aquesta substitució, però encara no hem acabat del tot: encara hem d'actualitzar com passem la sortida concatenada al procés cowpy.

3.4. Extreure el fitxer de sortida de la tupla per a cowpy

Anteriorment, el procés collectGreetings només produïa un fitxer que podíem passar directament a cowpy. No obstant això, el procés FIND_CONCATENATE produeix una tupla que inclou el metamap a més del fitxer de sortida.

Com que cowpy encara no accepta tuples de metadades (ho arreglarem a la següent part del curs), hem d'extreure el fitxer de sortida de la tupla produïda per FIND_CONCATENATE abans de passar-lo a cowpy:

core-hello/workflows/hello.nf
    // emet una salutació (actualitzat per utilitzar la convenció nf-core per a fulls de mostres)
    sayHello(ch_samplesheet)

    // converteix la salutació a majúscules
    convertToUpper(sayHello.out)

    // crea un mapa de metadades amb el nom del lot com a ID
    def cat_meta = [ id: params.batch ]

    // crea un canal amb metadades i fitxers en format tupla
    ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) }

    // concatena les salutacions
    FIND_CONCATENATE(ch_for_cat)

    // extreu el fitxer de la tupla ja que cowpy encara no utilitza metadades
    ch_for_cowpy = FIND_CONCATENATE.out.file_out.map{ meta, file -> file }

    // genera art ASCII de les salutacions amb cowpy
    cowpy(ch_for_cowpy, params.character)
core-hello/workflows/hello.nf
    // emet una salutació (actualitzat per utilitzar la convenció nf-core per a fulls de mostres)
    sayHello(ch_samplesheet)

    // converteix la salutació a majúscules
    convertToUpper(sayHello.out)

    // crea un mapa de metadades amb el nom del lot com a ID
    def cat_meta = [ id: params.batch ]

    // crea un canal amb metadades i fitxers en format tupla
    ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) }

    // concatena les salutacions
    FIND_CONCATENATE(ch_for_cat)

    // genera art ASCII de les salutacions amb cowpy
    cowpy(collectGreetings.out.outfile, params.character)

L'operació .map { meta, file -> file } extreu el fitxer de la tupla [metadades, fitxer] produïda per FIND_CONCATENATE en un nou canal, ch_for_cowpy.

Llavors només cal passar ch_for_cowpy a cowpy en lloc de collectGreetings.out.outfile en aquesta última línia.

Info

A la següent part del curs, actualitzarem cowpy per treballar directament amb tuples de metadades, així que aquest pas d'extracció ja no serà necessari.

3.5. Provar el workflow

Provem que el workflow funciona amb el mòdul find/concatenate acabat d'integrar:

nextflow run . --outdir core-hello-results -profile test,docker

Això hauria d'executar-se raonablement ràpid.

Sortida de la comanda
 N E X T F L O W   ~  version 26.04.4

Launching `./main.nf` [cheesy_bhabha] revision: d6bbba9521

Input/output options
  input                     : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv
  outdir                    : core-hello-results

Institutional config options
  config_profile_name       : Test profile
  config_profile_description: Minimal test dataset to check pipeline function

Generic options
  validate_params           : false
  trace_report_suffix       : 2026-06-23_16-55-02

Core Nextflow options
  runName                   : cheesy_bhabha
  containerEngine           : docker
  launchDir                 : /workspaces/training/hello-nf-core/core-hello
  workDir                   : /workspaces/training/hello-nf-core/core-hello/work
  projectDir                : /workspaces/training/hello-nf-core/core-hello
  userName                  : root
  profile                   : test,docker
  configFiles               : /workspaces/training/hello-nf-core/core-hello/nextflow.config

!! Only displaying parameters that differ from the pipeline defaults !!
------------------------------------------------------
executor >  local (8)
[bf/aa86d7] CORE_HELLO:HELLO:sayHello (3)            | 3 of 3 ✔
[0a/df448e] CORE_HELLO:HELLO:convertToUpper (3)      | 3 of 3 ✔
[82/ded72f] CORE_HELLO:HELLO:FIND_CONCATENATE (test) | 1 of 1 ✔
[9d/0130bf] CORE_HELLO:HELLO:cowpy                   | 1 of 1 ✔
-[core/hello] Pipeline completed successfully-

Observeu que FIND_CONCATENATE ara apareix a la llista d'execució de processos en lloc de collectGreetings.

I això és tot! Ara estem utilitzant un mòdul robust mantingut per la comunitat en lloc de codi personalitzat de qualitat prototip per a aquest pas del pipeline.

Conclusió

Ara sabeu com:

  • Trobar i instal·lar mòduls nf-core
  • Avaluar els requisits d'un mòdul nf-core
  • Crear un mapa de metadades simple per utilitzar amb un mòdul nf-core
  • Integrar un mòdul nf-core al vostre workflow

Què segueix?

Aprendre a adaptar els vostres mòduls locals per seguir les convencions nf-core. També us mostrarem com crear nous mòduls nf-core a partir d'una plantilla utilitzant les eines nf-core.