Skip to content

Part 1: Run nf-core/demo

In this first part of the Hello nf-core training course, we show you how to find and try out an nf-core pipeline, understand how the code is organized, and recognize how it differs from plain Nextflow code as shown in Hello Nextflow.

We are going to use a pipeline called nf-core/demo that is maintained by the nf-core project as part of its inventory of pipelines for demonstrating code structure and tool operations.

Make sure you are in the hello-nf-core/ directory as instructed in the Orientation.


1. Find and retrieve the nf-core/demo pipeline

Let's start by locating the nf-core/demo pipeline on the project website at nf-co.re, which centralizes all information such as: general documentation and help articles, documentation for each of the pipelines, blog posts, event announcements and so forth.

1.1. Find the pipeline on the website

In your web browser, go to https://nf-co.re/pipelines/ and type demo in the search bar.

search results

Click on the pipeline name, demo, to access the pipeline details page.

Each released pipeline has a dedicated page that includes the following documentation sections:

  • Introduction: An introduction and overview of the pipeline
  • Usage: Descriptions of how to execute the pipeline
  • Parameters: Grouped pipeline parameters with descriptions
  • Output: Descriptions and examples of the expected output files
  • Results: Example output files generated from the full test dataset
  • Releases & Statistics: Pipeline version history and statistics

Whenever you are considering adopting a new pipeline, you should read the pipeline documentation carefully first to understand what it does and how it should be configured before attempting to run it.

Have a look now and see if you can find out:

  • which tools the pipeline will run (Check the tab: Introduction)
  • which inputs and parameters the pipeline accepts or requires (Check the tab: Parameters)
  • what are the outputs produced by the pipeline (Check the tab: Output)

The Introduction tab provides an overview of the pipeline, including a visual representation (called a subway map) and a list of tools that are run as part of the pipeline.

pipeline subway map

  1. Read QC (FASTQC)
  2. Adapter and quality trimming (SEQTK_TRIM)
  3. Present QC for raw reads (MULTIQC)

The documentation also provides an example input file (see below) and an example command line.

nextflow run nf-core/demo \
 -profile <docker/singularity/.../institute> \
 --input samplesheet.csv \
 --outdir <OUTDIR>

You'll notice that the example command does NOT specify a workflow file, just the reference to the pipeline repository, nf-core/demo.

When invoked this way, Nextflow will assume that the code is organized in a certain way. Let's retrieve the code so we can examine this structure.

1.2. Retrieve the pipeline code

Once we've determined the pipeline appears to be suitable for our purposes, we're going to want to try it out. Fortunately Nextflow makes it easy to retrieve pipeline from correctly-formatted repositories without having to download anything manually.

Return to your terminal and run the following:

nextflow pull nf-core/demo

Nextflow will pull the pipeline code, meaning it will download the full repository to your local drive.

Output
Checking nf-core/demo ...
 downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master]

To be clear, you can do this with any Nextflow pipeline that is appropriately set up in GitHub, not just nf-core pipelines. However nf-core is the largest open-source collection of Nextflow pipelines.

You can get Nextflow to give you a list of what pipelines you have retrieved in this way:

nextflow list
Output
nf-core/demo

You'll notice that the files are not in your current work directory. By default, they are saved to $NXF_HOME/assets.

tree -L 2 $NXF_HOME/assets/
Output
/workspaces/.nextflow/assets/
└── nf-core
    └── demo

Note

The full path may differ on your system if you're not using our training environment.

The location of the downloaded source code is intentionally 'out of the way' on the principle that these pipelines should be used more like libraries than code that you would directly interact with.

However, for the purposes of this training, we'd like to be able to poke around and see what's in there. So to make that easier, let's create a symbolic link to that location from our current working directory.

ln -s $NXF_HOME/assets pipelines

This creates a shortcut that makes it easier to explore the code we just downloaded.

tree -L2 pipelines
pipelines
└── nf-core
    └── demo

Now we can more easily peek into the source code as needed.

But first, let's try running your first nf-core pipeline!

Takeaway

You now know how to find a pipeline via the nf-core website and retrieve a local copy of the source code.

What's next?

Learn how to try out an nf-core pipeline with minimal effort.


2. Run the pipeline with the provided test profile

Conveniently, every nf-core pipeline comes with a test profile. This is a minimal set of configuration settings for the pipeline to run using a small test dataset hosted in the nf-core/test-datasets repository. It's a great way to quickly try out a pipeline at small scale.

The test profile for nf-core/demo is shown below:

conf/test.config
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Nextflow config file for running minimal tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Defines input files and everything required to run a fast and simple pipeline test.

    Use as follows:
        nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR>

----------------------------------------------------------------------------------------
*/

process {
    resourceLimits = [
        cpus: 4,
        memory: '15.GB',
        time: '1.h'
    ]
}

params {
    config_profile_name        = 'Test profile'
    config_profile_description = 'Minimal test dataset to check pipeline function'

    // Input data
    input  = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv'

}

This tells us that the nf-core/demo test profile already specifies the input parameter, so you don't have to provide any input yourself. However, the outdir parameter is not included in the test profile, so you have to add it to the execution command using the --outdir flag.

Here, we're also going to specify -profile docker, which by nf-core convention enables the use of Docker containers.

Let's try it!

nextflow run nf-core/demo -profile docker,test --outdir demo-results

Here's the console output from the pipeline:

Output
 N E X T F L O W   ~  version 24.10.0

Launching `https://github.com/nf-core/demo` [maniac_jones] DSL2 - revision: 04060b4644 [master]


------------------------------------------------------
                                        ,--./,-.
        ___     __   __   __   ___     /,-._.--~'
  |\ | |__  __ /  ` /  \ |__) |__         }  {
  | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                        `._,._,'
  nf-core/demo 1.0.1
------------------------------------------------------
Input/output options
  input                     : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv
  outdir                    : results

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

Core Nextflow options
  revision                  : master
  runName                   : maniac_jones
  containerEngine           : docker
  launchDir                 : /workspaces/training/side-quests/nf-core/nf-core-demo
  workDir                   : /workspaces/training/side-quests/nf-core/nf-core-demo/work
  projectDir                : /workspaces/.nextflow/assets/nf-core/demo
  userName                  : gitpod
  profile                   : docker,test
  configFiles               :

!! Only displaying parameters that differ from the pipeline defaults !!
------------------------------------------------------* The pipeline
  https://doi.org/10.5281/zenodo.12192442

* The nf-core framework
    https://doi.org/10.1038/s41587-020-0439-x

* Software dependencies
    https://github.com/nf-core/demo/blob/master/CITATIONS.md

executor >  local (7)
[3c/a00024] NFC…_DEMO:DEMO:FASTQC (SAMPLE2_PE) | 3 of 3 ✔
[94/d1d602] NFC…O:DEMO:SEQTK_TRIM (SAMPLE2_PE) | 3 of 3 ✔
[ab/460670] NFCORE_DEMO:DEMO:MULTIQC           | 1 of 1 ✔
-[nf-core/demo] Pipeline completed successfully-
Completed at: 05-Mar-2025 09:46:21
Duration    : 1m 54s
CPU hours   : (a few seconds)
Succeeded   : 7

You see that there is more console output than when you run a basic Netxflow pipeline. There's a header that includes a summary of the pipeline's version, inputs and outputs, and a few elements of configuration.

Moving on to the execution output, let's have a look at the lines that tell us what processes were run:

Output (subset)
[3c/a00024] NFC…_DEMO:DEMO:FASTQC (SAMPLE2_PE) | 3 of 3 ✔
[94/d1d602] NFC…O:DEMO:SEQTK_TRIM (SAMPLE2_PE) | 3 of 3 ✔
[ab/460670] NFCORE_DEMO:DEMO:MULTIQC           | 1 of 1 ✔

This tells us that three processes were run, corresponding to the three tools shown in the pipeline documentation page on the nf-core website: FASTQC, SEQTK_TRIM and MULTIQC.

Note

The full process names as shown here, such as NFCORE_DEMO:DEMO:MULTIQC, are longer than what you may have seen in the introductory Hello Nextflow material. These includes the names of their parent workflows and reflect the modularity of the pipeline code. We will go into more detail about that shortly.

Finally, let's have a look at the demo-results directory produced by the pipeline.

tree demo-results
Output
demo-results/
├── fastqc
│   ├── SAMPLE1_PE
│   ├── SAMPLE2_PE
│   └── SAMPLE3_SE
├── fq
│   ├── SAMPLE1_PE
│   ├── SAMPLE2_PE
│   └── SAMPLE3_SE
├── multiqc
│   ├── multiqc_data
│   ├── multiqc_plots
│   └── multiqc_report.html
└── pipeline_info
    ├── execution_report_2025-03-05_09-44-26.html
    ├── execution_timeline_2025-03-05_09-44-26.html
    ├── execution_trace_2025-03-05_09-44-26.txt
    ├── nf_core_pipeline_software_mqc_versions.yml
    ├── params_2025-03-05_09-44-29.json
    └── pipeline_dag_2025-03-05_09-44-26.html

If you're curious about the specifics what that all means, check out the nf-core/demo pipeline documentation page.

At this stage, what's important to observe is that the results are organized by module, and there is additionally a directory called pipeline_info containing various timestamped reports about the pipeline execution. This is standard for nf-core pipelines.

Congratulations! You have just run your first nf-core pipeline.

Takeaway

You know how to run an nf-core pipeline using its built-in test profile.

What's next?

Learn how the pipeline code is organized.


3. Examine the pipeline code structure

The nf-core project enforces strong guidelines for how pipelines are structured, and how the code is organized, configured and documented.

Let's have a look at how the pipeline code is organized in the nf-core/demo repository (using the pipelines symlink we created earlier). You can either use tree or use the file explorer in your IDE.

tree -L 1 pipelines/nf-core/demo
Output (top-level only)
pipelines/nf-core/demo
├── assets
├── CHANGELOG.md
├── CITATIONS.md
├── CODE_OF_CONDUCT.md
├── conf
├── docs
├── LICENSE
├── main.nf
├── modules
├── modules.json
├── nextflow_schema.json
├── nextflow.config
├── README.md
├── subworkflows
├── tower.yml
└── workflows

There's a lot going on in there, so we'll tackle this in stages. We're going to look at the following categories:

  1. Pipeline code components

  2. main script in main.nf

  3. modular components in workflows, subworkflows and modules

  4. Configuration, parameters and inputs

  5. Documentation and other stuff

Let's start with the code proper, though note that for now, we're going to focus on how everything is organized, without looking at the actual code just yet.

3.1. Pipeline code components

The pipeline code organization follows a modular structure that is designed to maximize code reuse.

Note

We won't go over the actual code for how these modular components are connected, because there is some additional complexity associated with the use of subworkflows that can be confusing, and understanding that is not necessary at this stage of the training. For now, we're going to focus on the logic of this modular organization.

3.1.1. Overall organization and main.nf script

At the top level, there is the main.nf script, which is the entrypoint Nextflow starts from when we execute nextflow run nf-core/demo. That means when you run nextflow run nf-core/demo to run the pipeline, Nextflow automatically finds and executes the main.nf script, and everything else will flow from there.

In practice, the main.nf script calls the actual workflow of interest, stored inside the workflows folder, called demo.nf. It also calls a few 'housekeeping' subworkflows that we're going to ignore for now.

tree pipelines/nf-core/demo/workflows
Output
pipelines/nf-core/demo/workflows
└── demo.nf

The demo.nf workflow itself calls out to various script components, namely, modules and subworkflows, stored in the corresponding modules and subworkflows folders.

  • Module: A wrapper around a single process.
  • Subworkflow: A mini workflow that calls two or more modules and is designed to be called by another workflow.

Here's an overview of the nested structure of a workflow composed of subworkflows and modules:

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1daXPiSFx1MDAxMv3ev4LwbsTuRjQ1dVx1MDAxZlx1MDAxMzGxga9u2/hq397ZcGBcdTAwMTAgc1x1MDAxYVx1MDAwNMaenf++WbKNhFx1MDAwZVx1MDAxYaaFW+5cdTAwMTl5po1VXHUwMDEyKlXVy3yZlZX124dCYc177DtrP1x1MDAxN9acSbXSdmuDysPaR3t+7Fxmhm6vXHUwMDBiRdT/e9hcdTAwMWJccqr+lU3P61x1MDAwZn/+6adOZdByvH67UnXQ2Fx1MDAxZI4q7aE3qrk9VO11fnI9pzP8t/33oNJxfun3OjVvgIKHXHUwMDE0nZrr9Vx1MDAwNs/PctpOx+l6Q/j2/8DfhcJv/r+h2lxynKpX6Tbajn+DX1x1MDAxNFRQXHUwMDEwXHUwMDE2PXvQ6/qVlZwxQ1x1MDAwNZ6Wu8NNeJrn1KCwXHUwMDBlNXaCXHUwMDEye2ptb6+4M3DqXHUwMDBm95eTp9pee3x4t31xXHUwMDFjPLTuttsn3mP7uSEq1eZoXHUwMDEwqtLQXHUwMDFi9FrOhVvzmlBOXCLnp/dccnvQXHUwMDA2wV2D3qjR7DrD4cw9vX6l6nqP9lx1MDAxY1x1MDAwZar/3Fx1MDAwNj9cdTAwMTeCM1x1MDAxM/iLK4k0plhpylx1MDAxNVY4aFx1MDAwZf9+JVx1MDAxMFWKcaZEpEpcdTAwMWK9NvRcdTAwMDFU6W/YP4JK3VaqrVx1MDAwNtSsW5te41xyKt1hvzKAnlxurnt4eVnKXHQyWFJuXlx1MDAwZTW9pOm4jaZcdTAwMDfXMMJcdTAwMTAnmFxiSUNcdTAwMTVx/L7QnGJjOFx1MDAwZW6zT+/v1PxB8d+gXHUwMDAzXHUwMDA2MJx27Fx1MDAxZN1Ru1x1MDAxZG7Dbu2lXHJfXHUwMDA3TzB82MuZ34PXs9dvRYddeOiFxkTpQFx1MDAxNFuH11x1MDAwZmp/m8nOI4xcdTAwMGUxXHT6b2acVlx1MDAwNoPew9q05PeXT0H9R/1a5Xn0XHUwMDExxSjR3FxiQ6Welrfdbiv6cu1etVx1MDAxNVxm2Fx1MDAwZqE3WVx1MDAwZSdMyjScQK8oSSVcdTAwMTF6YaSss+bu7uSAnu+c7nfPWodnm/dXn/OOXHUwMDE0QTnSJDT87G2UKkS4Xik+iJaIMWGYekFcYk/AXHUwMDA3RVx1MDAwMGBcdTAwMThcdTAwMTQqXHUwMDA2XHUwMDBmXHUwMDAy91x1MDAxM0olMznEx/at4IdPVaVcdTAwMWb3iyebzc55+ea8mVx1MDAxOT6gd7R4XHUwMDEzfCgm0vBBXHJhWPNcdTAwMTCAvlx1MDAwNo+Dp55cdTAwMTmba4edXfHuZnnc41x1MDAwZu7kPcDD+Fx1MDAxYSSKXHUwMDExhlx1MDAwNWJE+yN4lShcdTAwMDFV5T/8+ZuwjKNEccQ15lK/XCIphlx1MDAxNcox51x1MDAxYzOWQ6zc4cejo+H4/Hqflies7D7d9o/OXHUwMDE3w8rHed+7e/ip3qtsTL7Uh3J4dj64XHUwMDFj8JNhPjHoOVx1MDAxMy9cdH5cXKo0+Fx1MDAxMUIkXHUwMDAxTanpwvhjZvdTd8c0XHUwMDBlr8v1dq/Sli192so9/rRGlOBcdTAwMTmM+XdSg4DdhUGZNfQkQ9DEhnGs6Sz8p8hLYG1GUVx1MDAwM1x1MDAxNDtcdTAwMDPWNlOQXHUwMDBi9Vx1MDAwM1RVc8GpWGroXHUwMDA379zreifuk6898MzZ7UrHbT/OXGZcdTAwMTJcdTAwMWZcdTAwMTNQwZ1uf+RcdTAwMDW49c+X2m7D4mOt7dRngeO5YE5Ni71ePyitwnMqbtdcdTAwMTnEW703cFx1MDAxYm630j5NeSa8o/P5tc9cdFxu9fptZejYUl9Sz8X4c0MngJxcdTAwMTCFo6dfUc5cdTAwMTRcdTAwMTGK4iVAPr/rc1xuckkx4vCinFx1MDAwYk1gjM1cIl1cdTAwMDBP9LXbXG61LFx1MDAwMkmKpcBcdTAwMDL0LVx1MDAxNlx0TFSCPSlVXCJcdTAwMTHVxIBcdTAwMDWHRVCSoXKlX1euWaqpUFx1MDAwYldcdTAwMDbeututud3GbMVeXFxcdTAwMTM7XHUwMDBi6Fx1MDAxNFx1MDAxZt3Vka0lRsA+oIeZptq2NXxcYl3VqPTtu1wi4PPWXHUwMDE0jr2z0619vS74eo9cXFx1MDAxZV2etXH3lIxcXH7JXHUwMDFi/WJyXVxiSHNcdTAwMDbWnZHWXHUwMDA3oIiK1UUjXHUwMDAxwLT9XHUwMDFkq0y7MvQ2ep2O60FbXHUwMDFm9dyuXHUwMDE3bVO/8UpcdTAwMTbwTadcdTAwMTLrcHiZcFlUMvTtN86K+OBTIUCO/8f0838/Jl6dNrDtXHUwMDExXGbp4Fs+hH8vS1eY5NGzU7pcIpXBmPIl/E7zuzOnkkxIgrT1+kTsaUaQXFy5qYDBaFx1MDAwN8LCp5RlIcJcIiVIXqBT75SwzLVcdTAwMDG+wbZYkFxiXHUwMDA15tiqidD+4eZZeeuGvC1cdTAwMTWKP3WlZEhqXHUwMDEyPTt1OFx1MDAwMPqYMpwvTobmd39ORYgkXG5peE9cdFx1MDAwNp40OlwiSKRcdTAwMDKmxFx1MDAxNVx1MDAxNVxcMsaVYJF6Zei/RtDaQlx1MDAxYcWsp1xcUJXgv6ZcbimoKKGESatmSFx1MDAwMIep60FcdTAwMThcZkac+TOyo4VcdTAwMTlJXHUwMDEx6Fx1MDAxMWZcdTAwMTiMR2FcdFx1MDAxMFx1MDAwNn2hTJyUXHUwMDEwjICsXHUwMDEwKCR+51Pzx5jSfE/cLGtT1nMktVx1MDAxMMJQYG0kqVLAlFx1MDAwNCVKcVx1MDAxMIpG8HfNmNKHvV9cdTAwMWFcdTAwMWLwS3InXz4mXGI+aNs0wceJXHUwMDA244LjxT2tW5PzVkNcdTAwMGVPas7goXG1qYa312acd7mnXGJHM/bVs5OVXCKu5Oz8WMaCToC8JZLPkLawb1VcdTAwMDJ3lUmGnzHG+odWMkGXXHUwMDEzyVx1MDAxNoVhSknGXHUwMDAwnynLXHUwMDE03Vx0fW2PYqibM1x1MDAwMjSnOnp2XG5o4NwgV1x1MDAxNjeFvPK4KdxaX5euNk6LLTOU97icfzxcdTAwMDdEzYeyxsha/6t02XKJXHUwMDA0nZ3WXHUwMDBm5lx1MDAxMlxymjXMXmEsmFx1MDAwMaVK+V84fj84jne0PV67eElcYs+fXHUwMDAy1alToKCXseFsXHUwMDE5zXyxTs/29OXe5V1ts9ZtlMrDL8Wr3CNZXHSwSFx1MDAxMiZhKFx1MDAxNmCNXGJFtDGcQDvoSJ0ytEYoQVx1MDAxMotgkjPJXHUwMDFhodrS6CDoJrjmXHUwMDA164pYL1xmW4ktssA06HefUGQ4daqB2KGsNWeLqyXRm0zIVu2qWj5pt25qm0dcdTAwMTcl85D3wVxmRlx1MDAxM2JmNrTFV0+MolgkVtZcdTAwMWU6RcCgMoZcbsF8POmEQZygoCT3Rd3KXXT5cXadnK1fXHUwMDFjftnbLlx1MDAxZl68tccr5dFZuL3mKlx1MDAxYUnSXHUwMDE1XHKHPlx1MDAwMHYqXHUwMDE3d301L872zVnTXHUwMDFiV1x1MDAwN3RSudq9/Tw+XHUwMDFk5Vx1MDAxZptcdTAwMDLUOiaKXHUwMDEyYkhYrz76jFohy9yJ4X5QmInUK9ugXHUwMDFi4lx1MDAxYlx0L0E3gZctXHUwMDFjmiaicVx1MDAwMdNcdTAwMTlBzVx1MDAxNWVY5THc5lx1MDAxYsJiPs773tWGhGaqXHUwMDFk073PbE44qJSYaaZcdTAwMTfnevNbOqdcdTAwMTCURCNDMSVcZnNtRCj6+NmGk3ZcdTAwMWWXQ4H27WW+MlxmWmNRSUIwXHUwMDE1VGJcblx1MDAxYTvJpuN2ypjAf1x1MDAxMmOlQzNer1BUQNGlNGQlUMyJcfeH3bzPXHUwMDBlXFyJwJKS0EiS+C6Q0Fx1MDAwNTP+aeDVSoFcdTAwMGXi0C3AluJu3oV8z/NcdTAwMTXTtFI2/lja8DYmpFx1MDAwNFx1MDAwM50l1FxuKkXgXHUwMDEyYYhcdTAwMDDDgFx1MDAxYlx1MDAwNTWMVeo9+Z7njHl7xEZ78H1cdTAwMWbCv5eWe0anm1x1MDAwNVpCI2vNXHUwMDAypH9N7s3XXHUwMDA0eZV7lFwiPzBFUEpccmjvWeohXHUwMDE1XHUwMDEySlEpXHUwMDE4I5KR1c26YVx1MDAxYspcdTAwMGLPoNhO8DFcdTAwMTlcbv1cbks9Q1xy5WCTXHUwMDFi67uKXHUwMDEzXHUwMDEwoItC2jmZXHUwMDFjSj3JtPhDhsSCUm+n1Vx1MDAxYZxsl/bPXHUwMDBlho07tttcdTAwMTD1O/k5LGDCQk1BfaxcdTAwMDeDMeCeXCJo7EJodktDn9tVRCCHXGLVJPb2XHUwMDBiib0y2cBcdTAwMWVcdTAwMTaP7MtcdTAwMDa/brrHm1x1MDAxYjdcdTAwMDdbKbVcdTAwMDLJJzGnWNlONILFKqVcdTAwMTE0XCLQZGK07X6p37nUS1x1MDAxYvL2iFxy9iWFXmpstUmNNCBUMclcdTAwMTVTiy/9md+9OZV5Qlx1MDAxYkRja39cdTAwMDQhMFx1MDAwMrlgq3TUa4yEMKCvMVx1MDAxNiB2XHUwMDE3dIQwsIK1elx1MDAwM0fIdIy9oaHzPdwshyPv7aOrY1x1MDAwZs3CtZLq8dSpJp1cdTAwMTWwXG7a3CxObebrlrzCXFxilODw5IwgxTmZnfjO3JVCOLLOeKZB0erkmbk40oWSxt7wXVdR/EhAf1x04+PfJXiQZ1x1MDAwYvX5K99puilDXHUwMDAw7UAwlsC7ru+sXHUwMDFm1I/G4/3Np/VJ96pyX1x1MDAxYt7kXHUwMDFk75popCSLrFbw5+tcdTAwMDRD0ii62nhcdTAwMWGiKOIkXHUwMDEyMzOzpDc6lzhccqjhSqzIaMnT7Nz8aVx1MDAwMJ6auoFY+mtcdTAwMTRbYkn6J5eUzlx1MDAwZvdr682jc9KWpFpcdTAwMWJcdTAwMWZv5n9cdTAwMDBzsMVVZN2373/kXHUwMDFh8dhq3PxcZmDoPGFccu9cdTAwMWZ+XGKn0S0hU0ev4GBHK0VcdTAwMTaXvp2T9dvGvbOlvId2a7t+sHvxZd3J/eBcdTAwMTVAq5KWgFxijVbOtVx1MDAwNFx1MDAwMlx1MDAxYtlEOd08k1xuiFx1MDAxOTMwQL4r07o6bF7fXHUwMDBmzq5cdTAwMWVb7u35+vX6zoSVXHUwMDFmXHUwMDE2Y1pcdTAwMWbnfe9OqfnIilx1MDAwN6rf22mUTHm3vcU/i/fN4Oh3YXA0W1x1MDAwNpcmPeRcdTAwMWPyxlx0YIpcdTAwMTGyhO6bNMX5lSOv8FHpvrF/+/D0+JnnXnxwiVx1MDAxOE3INlx1MDAwMdRNR+XKKlx1MDAwNFxisyvIJI08aY5cYmGcc2CUIW34XHUwMDAzSZDDPtbOdenz3tOgjid8/7JU2cHvW4Kw71wiQVi2XHUwMDEyJHUqS6tUf4+UlEpDl5jJmj+qcipBXGYmNvWZVFx1MDAxMlx1MDAxYm6znM3SXHUwMDEwXHUwMDAzJqBcXHGcXHUwMDFiXHUwMDA2XHUwMDFhwpSx0yYgRkCYJFx1MDAwNGtyhVx1MDAwNDFcIil+hlx1MDAxM1xytESuJvNZzufs53PewsxcInaqtZDWUSbAWNEmtLg7mLx6bePYWy80azVfhVx1MDAxNmbn0lx1MDAwMF6aacX8+TKSNJdGkTSGvvtF9cX08W2P0MhcdTAwMGW+6UP4d5ZSzcBcdTAwMTAgmC5cdTAwMTGXNF+n5VSqaWOQUdqOXHUwMDFmgU04L9lzXFySQVqI1SZcdMF2ZT9cdTAwMTFEXHUwMDE4SYRdyZLAjlTM9ptcdTAwMDZcIimrezReSbq6nFx1MDAwYrWFxVxiSFx1MDAxMVxy4oExIZlNMCfjc98g04xaIEvIKte1rHg6PGWY2SNcdTAwMThgS4qWVIeNSnc3Mmw014ouXHUwMDFldVxcudSlQWewt77RXFzf69U/uXdcdTAwMWJcdTAwMTWTP9HCkVwigEVtNGZgcFx1MDAwNZD0U8dyUFNKgVx1MDAxNrMrW8BcdTAwMTCa5U9MIMK4llxc49nS7NN5aFx1MDAwNIPAXGKln52hwaPmOXSA90GfKbpyh05+XGab13D9tzVs4k/NwrBJXVx1MDAxZs5TXSMwklx1MDAxOVCQxVx1MDAxZCOTsjgoXHI+be49jMvOo/r8WGtcdTAwMWbf5Vx1MDAwZqWRWWxcdTAwMDKonXXJP6dylohHZ5Yz1/xx5IFsRFG+8eJcdTAwMGahIFFEJlx1MDAwMMytov/RlpPOXFxcdTAwMWR07ZI6NnUpOEnPi1x1MDAwNSNa22jfxXXspWysO3XM67cwPFx1MDAxZkvO9sPWef5nRUCZiZhTk2JcdTAwMGVcdTAwMTbhimdFMIpcdTAwMDW5XHUwMDA0+pP5iVx1MDAwN1x1MDAxM1fxSDvLl9NcdTAwMThaaqRaJkP6n1x1MDAwNsexvrZHuJczos16TmZebjg2XHUwMDAytMDCkD47Kp6w4vihf8xxqcPvr+5v1zfyXHUwMDA36bm0WYHUxIIpsFx1MDAxN5hcdTAwMWY+Oot0MN85x1x1MDAwMlx1MDAwYqNnS/OxxpZiINk209Ffa2zf+Vx1MDAxYdtUXHUwMDFmmsLpkaBUMkGWsHPnTyznXHUwMDA2sPGJXHUwMDAxsOgppjanMKez6Vlsglx1MDAwNSjANlx1MDAxMt9cdTAwMDBcdTAwMDXCK4Qo0loyXGYmXHUwMDBiiFxuXHUwMDA2XHUwMDA2a0JOeyptzCq36Vx1MDAxY5jCWoSSybzybImBVVx1MDAxOJJL/bxynv3N81x1MDAwN9ZjXHUwMDBmMo9oTJk0VmGpuLPNIFxykpRcdTAwMTJcdTAwMGWXaMrF+15okj7u7Fx1MDAxMVx1MDAxZnFLcoW5YX2EsVRcdTAwMDNeUkJcdTAwMTVcdTAwMTZLREbVxzfN3tNcdTAwMTa/ccTT6enN7VW/Va7kXf5cdTAwMDCbpkj5SzU1iFx1MDAxZkMjeb6ZhlJcdTAwMWNcdTAwMWMyUrNcZjO+WV+CkphcdTAwMTO7opsm7anBJUUvMbQ8sjvNK2UwUFxiOvt7JZOZ3pNcdTAwMTC2ID5dmvpth49KI+fzg7l8vL2phFebxfTltGR+OMRFcyw3eFx1MDAxN+PWpF7eXHUwMDFiXHUwMDFkbDyub2W3yF8pXHUwMDE2Sv/6jVx1MDAxMYppxng403GMuVvpIMVcdTAwMTKutKu7VvduuCnO9i+EOu7ft0j1MPfxtcZIXHUwMDE0yan4XHUwMDFhXHUwMDFkXHUwMDFlW6SR+aZcdTAwMWHKLrqcjeydglx1MDAwZepcdTAwMTXZk+01oVx1MDAwNlBjXG7kPK9JZLNYz/qj2eJcdD1tj+JrJy+pXVNcdTAwMWTjOnVcdTAwMDLLrlx1MDAxN5VSssXhPLrb+3L81Lg/waefhzt1erLZOsx/wI+xQfE0XHUwMDAx0Npa7HilSedBpc8+IOQhJ8hEo+hfXHUwMDAwbaRcdTAwMTCaySys7czxrInJZH36j4bnaE/bI9zHXHUwMDE54ZmkT3RJm5mZmCXs9Fx1MDAxYrbXvthvVndO5K77cLgr2n39mHc8XHUwMDEzgCxKmOniXHUwMDA2RTagydouT6DBwib8ScpxhVx1MDAxOedKUpVX8/svXGLHrybhq6dduyRwU13i6ZEkTGOlxTKRt57cqrfx7lGxcn6yd3HRKp9eXHUwMDFk5nCvurlcdTAwMWVxgFxiQVx1MDAwMlNcdTAwMTmLTPOVs1xyzlx1MDAxNDbxUlRFfv9VQVRKrIghf1wiZ/iPtLzmK46o1JkrrW1cdTAwMTZcdTAwMTa1OEq/tNpcdTAwMTfd1qZcdTAwMTjd6W712Nx2LsmnTykojaBtXHUwMDE2ozRyfsVOKIAqV0ZcdTAwMTElXGaZdUJJKCVcXDHAdHS3t1xiLIljf/44LClWYFx1MDAwN0XM8EDvamRdZEnc2W5cdTAwMDfIJVx1MDAwZTnNf1xiv9Or7slQrf8hNUbT8/ZcdTAwMGJFbFx1MDAxYaIldmM8m5TK2zefalx1MDAxYsfj9vmWdzOpdq5Vzlx1MDAwMUIwRzbPJUAhXHQgWiAsXHUwMDE0N6/b461cZiCEMSTAtlx1MDAxNUyQZJAksFLfXG7moTr/8Iqr06uN2s5cdTAwMTCB1qm7jbdVX2nPXuVcdTAwMWFRQtL9t5ph+FFLXHUwMDA0U5Gnm2LzXHUwMDEzaT86d+Ome3DeLDVKh3lcdTAwMDcoXHUwMDEwOmqMxDxJgymmXHUwMDExZYzGM4BkXHUwMDBlUK5cdTAwMTBhRkuKnzPzJ0RaJIRHXG5cdTAwMTDiXG5o8Z9cdTAwMDeiXq/XLlRcdTAwMDaNkV+3X7v90W3bXHUwMDFkNsGS/LXb85NhXHUwMDE1uvCyb5yGa/laLVx1MDAwNGv5Ldw05OCP5V9cdTAwMDY9YHfQXFzcmau8XHUwMDFkvl9cdTAwMTlvVCpXzvFprblxvPOQlqwrL9hmXHUwMDFj2tVubEI1jNE4OyWI2+1qXGY3NJ/s1O6FjIlSKlx1MDAwM1x1MDAxNZw5PV3t9OXb0NN0L1x1MDAwYvRcdTAwMDdwJrKEl6X5ZXdwW52Ud/e3T+nVXHUwMDExm+zx/iTvXGLRgFx1MDAxMGhuqowwSpnZOEOpKTJcdTAwMDZk/MrtN1x1MDAxMEjIiiPDlNH+tlaLXHUwMDEwVD+1sFwiWVx1MDAxOG/vRftZ3fBd2Gnig1dKTUNb08bW0kmQ6DBcIlx1MDAxN1x1MDAwZlxu7m/cXzijer/V+FwivFx1MDAxMmuIjZPjk7yD067GXHUwMDAx+Fx1MDAxMWxkXHUwMDAyNeVcdTAwMThcdTAwMDExxXT11FT7K981XHUwMDE25nkn7Fx1MDAwNHCGtlwin66dk3b9Olx1MDAwZXnAfnh0VntcdTAwMWRgek5h4Fxme6NB1Vx1MDAwMVwi6IDqXHUwMDFiXHUwMDE0oEugYlxy961p6VJcdTAwMTVaXGLNnM1Fc2rAMEn3XHUwMDA0XHUwMDExuy2B4nyJSKH5rrF8wpkoXGZET0ijeVx1MDAwMpyltFF0xmbr+Eq26G+Fs+HIcE3splx1MDAwN8Rv+Fx1MDAwNEpqXHUwMDEwiYYuTYOHpLGbK6/EYfpNM5VcdTAwMDJcdTAwMTNBQ5Zw9ivv53voXHUwMDBiM+HAdltcdEW5sGshgNTEd3pcdTAwMDaTQCq75W1yXG6PheKT50euzlaIU66lTSdClY31xlx0XHUwMDFiYnNEbfYpKp/zbdD3XHUwMDFkoCxcdTAwMDTSkb3p7FEk8iV14Ne+IFx1MDAxNSj+11x1MDAwNFx1MDAxOFx0vudD+PfyXCLSpDvjqOBMXHUwMDEyvMzmmHPNs3yKSC4wXHUwMDAyziDtnpN2jjtcIiHtbuJSKG73Rmckfbekb5WQwHfsMlIwQZnNj5JotFx1MDAwM3xx4oplQiXnklx1MDAxM1x1MDAxMrxbviRkYONlLyHne4lCXHUwMDAyXHRcdTAwMDQkdLbUdo2M5Dgp35JBXHUwMDE4Otr3y1x1MDAwMvpcYo67K7KVkUCnXHUwMDA1g0rZlH1CXG6s4jKbMFx1MDAwNFUm8D/1R2BC2pT3JCGL3yxcIoupUPFLXHUwMDAzlCwpI1ONQqxTaSQlXHUwMDE0lKmkS0S0bd91xienxL33rkdHXHUwMDFk5/F0t7p1kVwiI3NcdTAwMTTRxlx1MDAxNFx1MDAxMoZLokFgMlx1MDAxYdo27jmyTVx1MDAwM7Z43KWY9e7gWFwiKYyi5mWX4CQpXHUwMDE5N1x1MDAwYrm0u1x1MDAxN7BcZoTjt1x1MDAxOYVB3MaqjcL+oFx1MDAwN4bXsPBcdTAwMWGeUvjt1669oF25ddqFX6fl7d7Dr2vPRc//ul2w3X5+/uyN+m2nMK60/9lxvMq/Plx1MDAxNvpcdTAwMTWv+c86XGKbyr/C9zzPNXzlJnfmXHUwMDE2XHUwMDEwNd3XXHUwMDFiKsNcdTAwMTaCaiN7rvDLL36jXHUwMDE0/ve/2YLwzcPqwO2/Pq/m1O1cdTAwMWPIsPBLcIP/979/LvzjXHUwMDFmL7et+T/+585jsT7qVj1cdTAwMDBx4e/+hUW38Hf/pVxuxZ795IZvgkf+/rbm819dt5KuW8zR8Opp+PCifdYq/f6JXHUwMDA3UJ4qe5BcdTAwMWRu7Vx1MDAwNY9BP66NXedhPS7N/lb3XHUwMDBmO1xy4atcdTAwMWQr3lx1MDAxZJ9l/f7h9/9cdTAwMDNcdTAwMThcdTAwMDLU+CJ9 InputsMODULE_1SUBWORKFLOW_1OutputsMODULE_4MODULE_2MODULE_3WORKFLOWSUBWORKFLOW_1MODULE_2modules.configtool argumentspublishingoutput namesbase.configcompute resourceserror strategiesprocess MODULE_2 { label "process low" input: tuple val(meta), path(fasta) output: tuple val(meta), path(fai) when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' """ my-function $args -i $fasta -o $fai """ }

Not all workflows use subworkflows to organize their modules, but this is a very common pattern that makes it possible to reuse chunks of code across different pipelines in a way that is flexible while minimizing maintenance burden.

Within this structure, modules and subworkflows are further organized into local and nf-core folders. The nf-core folder is for components that have come from the nf-core GitHub repository, while the local folder is for components that have been developed independently. Usually these are operations that very specific to that pipeline.

Let's take a peek into those directories.

3.1.2. Modules

The modules are where the process code lives, as described in Part 4 of the Hello Nextflow training course.

In the nf-core project, modules are organized using a nested structure that refers to toolkit and tool names. The module code file describing the process is always called main.nf, and is accompanied by tests and .yml files.

tree -L 4 pipelines/nf-core/demo/modules
Output
pipelines/nf-core/demo/modules
└── nf-core
    ├── fastqc
    │   ├── environment.yml
    │   ├── main.nf
    │   ├── meta.yml
    │   └── tests
    ├── multiqc
    │   ├── environment.yml
    │   ├── main.nf
    │   ├── meta.yml
    │   └── tests
    └── seqtk
        └── trim
            ├── environment.yml
            ├── main.nf
            ├── meta.yml
            └── tests

Here you see that the fastqc and multiqc modules sit at the top level within the nf-core modules, whereas the trim module sits under the toolkit that it belongs to, seqtk. In this case there are no local modules.

3.1.3. Subworkflows

As noted above, subworkflows function as wrappers that call two or more modules.

In an nf-core pipeline, the subworkflows are divided into local and nf-core directories, and each subworkflow has its own nested directory structure with its own main.nf script.

tree -L 4 pipelines/nf-core/demo/subworkflows
Output
pipelines/nf-core/demo/subworkflows
├── local
│   └── utils_nfcore_demo_pipeline
│       └── main.nf
└── nf-core
    ├── utils_nextflow_pipeline
    │   ├── main.nf
    │   ├── meta.yml
    │   └── tests
    ├── utils_nfcore_pipeline
    │   ├── main.nf
    │   ├── meta.yml
    │   └── tests
    └── utils_nfschema_plugin
        ├── main.nf
        ├── meta.yml
        └── tests

In the case of the nf-core/demo pipeline, the subworkflows involved are all 'utility' or housekeeping subworkflows, as denoted by the utils_ prefix in their names. These subworkflows are what produces the fancy nf-core header in the console output, among other accessory functions.

Other pipelines may also use subworkflows as part of the main workflow of interest.

Note

If you would like to learn how to compose workflows with subworkflows, see the Workflows of Workflows Side Quest (also known as 'the WoW side quest').

3.2. Configuration

The nf-core project applies guidelines for pipeline configuration that aim to build on Nextflow's flexible customization options in a way that provides greater consistency and maintainability across pipelines.

The central configuration file nextflow.config is used to set default values for parameters and other configuration options. The majority of these configuration options are applied by default while others (e.g., software dependency profiles) are included as optional profiles.

There are several additional configuration files that are stored in the conf folder and which can be added to the configuration by default or optionally as profiles:

  • base.config: A 'blank slate' config file, appropriate for general use on most high-performance computing. environments. This defines broad bins of resource usage, for example, which are convenient to apply to modules.
  • modules.config: Additional module directives and arguments.
  • test.config: A profile to run the pipeline with minimal test data, which we used when we ran the demo pipeline in the previous section (code shown there).
  • test_full.config: A profile to run the pipeline with a full-sized test dataset.

At the top level, you can find a README file with summary information, as well as accessory files that summarize project information such as licensing, contribution guidelines, citation and code of conduct.

Detailed pipeline documentation is located in the docs directory. This content is used to generate the web pages on the nf-core website.

In addition to these human-readable documents, there are two JSON files that provide useful machine-readable information describing parameters and input requirements, nextflow_schema.json and assets/schema_input.json.

The nextflow_schema.json is a file used to store information about the pipeline parameters including type, description and help text in a machine readable format. The schema is used for various purposes, including automated parameter validation, help text generation, and interactive parameter form rendering in UI interfaces.

assets/nextflow_schema.json (not showing full file)
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://raw.githubusercontent.com/nf-core/demo/master/nextflow_schema.json",
    "title": "nf-core/demo pipeline parameters",
    "description": "An nf-core demo pipeline",
    "type": "object",
    "$defs": {
        "input_output_options": {
            "title": "Input/output options",
            "type": "object",
            "fa_icon": "fas fa-terminal",
            "description": "Define where the pipeline should find input data and save output data.",
            "required": ["input", "outdir"],
            "properties": {
                "input": {
                    "type": "string",
                    "format": "file-path",
                    "exists": true,
                    "schema": "assets/schema_input.json",
                    "mimetype": "text/csv",
                    "pattern": "^\\S+\\.csv$",
                    "description": "Path to comma-separated file containing information about the samples in the experiment.",
                    "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row. See [usage docs](https://nf-co.re/demo/usage#samplesheet-input).",
                    "fa_icon": "fas fa-file-csv"
                },
                "outdir": {
                    "type": "string",
                    "format": "directory-path",
                    "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.",
                    "fa_icon": "fas fa-folder-open"
                },
                "email": {
                    "type": "string",
                    "description": "Email address for completion summary.",
                    "fa_icon": "fas fa-envelope",
                    "help_text": "Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. If set in your user config file (`~/.nextflow/config`) then you don't need to specify this on the command line for every run.",
                    "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$"
                },
                "multiqc_title": {
                    "type": "string",
                    "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.",
                    "fa_icon": "fas fa-file-signature"
                }
            }
        },
(truncated)

The schema_input.json is a file used to define the input samplesheet structure. Each column can have a type, pattern, description and help text in a machine readable format.

assets/schema_input.json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/nf-core/demo/master/assets/schema_input.json",
  "title": "nf-core/demo pipeline - params.input schema",
  "description": "Schema for the file provided with params.input",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "sample": {
        "type": "string",
        "pattern": "^\\S+$",
        "errorMessage": "Sample name must be provided and cannot contain spaces",
        "meta": ["id"]
      },
      "fastq_1": {
        "type": "string",
        "format": "file-path",
        "exists": true,
        "pattern": "^\\S+\\.f(ast)?q\\.gz$",
        "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'"
      },
      "fastq_2": {
        "type": "string",
        "format": "file-path",
        "exists": true,
        "pattern": "^\\S+\\.f(ast)?q\\.gz$",
        "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'"
      }
    },
    "required": ["sample", "fastq_1"]
  }
}

The schema is used for various purposes, including automated validation, and providing helpful error messages.

An example samplesheet is provided under the assets directory:

assets/samplesheet.csv
1
2
3
sample,fastq_1,fastq_2
SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz
SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz,

Note

The paths in this example samplesheet are not real. For paths to real data files, you should look in the test profiles, which link to data in the nf-core/test-datasets repository.

In general, it's considered good practice to link out to example data rather than include it in the pipeline code repository, unless the example data is of trivial size (as is the case for the `greetings.csv` in the Hello Nextflow training series).

Takeaway

You know what are the main components of an nf-core pipeline and how the code is organized, what are the main elements of configuration, and what are some additional sources of information that can be useful.

What's next?

Take a break! That was a lot. When you're feeling refreshed and ready, move on to the next section to apply what you've learned to write an nf-core compatible pipeline.