Skip to content

Commit

Permalink
chunk documentation to reduce readme weight. Add example from Anthony
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexVCaron committed Dec 11, 2024
1 parent f71ac99 commit 6db6a88
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 66 deletions.
81 changes: 18 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,63 +34,25 @@ development in **neuroimaging** and produces better research outcomes for all !

Well, it depends on what you want to do. If you want to :

- Learn about the content of `nf-neuro`, go to the [discovery](#discovering-nf-neuro) section.
- Use **modules** and **subworkflows** from `nf-neuro`, go to the
[prototyping](#prototyping-using-components-from-nf-neuro) section.
- Fully **publish** your pipeline and **brand** it with `nf-neuro`, go to the
[porting prototypes](#porting-prototypes-to-nf--ready-pipelines) section.
- Contribute new **modules** and **subworkflows** to the `nf-neuro` **library**, go to the
- **Learn about the modules and subworkflows** in `nf-neuro`, go to the [discovery](#discovering-nf-neuro) section.
- **Create a new pipeline quickly**, using **modules** and **subworkflows** from `nf-neuro`, go to the
[prototyping](./docs/PROTOTYPING.md#basic-prototype-pipeline-creation) section.
- **Create or publish a production pipeline** branded with `nf-neuro`, go to the
[porting prototypes](./docs/PRODUCTION.md#porting-prototypes-to-nf--ready-pipelines) section.
- **Contribute new modules and subworkflows** to `nf-neuro`, go to the
[contribution](#contributing-to-the-nf-neuro-project) section.

---

- [WHY ? `nf-neuro`](#why--nf-neuro)
- [Pipeline creation with `nf-neuro`](#pipeline-creation-with-nf-neuro)
- [Prototyping using components from `nf-neuro`](#prototyping-using-components-from-nf-neuro)
- [Environment setup](#environment-setup)
- [Dependencies](#dependencies-)
- [Configuration](#configuration-)
- [Using components from `nf-neuro`](#using-components-from-nf-neuro)
- [Using the information from the `info` command](#using-the-information-from-the-info-command)
- [Porting prototypes to `nf-` ready pipelines](#porting-prototypes-to-nf--ready-pipelines)
- [Developing with `nf-neuro`](#developing-with-nf-neuro)
- [Manual configuration](#manual-configuration)
- [Dependencies](#dependencies)
- [Python environment](#python-environment)
- [Loading the project's environment](#loading-the-projects-environment)
- [Global environment](#global-environment)
- [Working with VS Code](#working-with-vs-code)
- [Configuration via the `devcontainer`](#configuration-via-the-devcontainer)
- [Contributing to the `nf-neuro` project](#contributing-to-the-nf-neuro-project)
- [Adding a new module to nf-neuro](./docs/MODULE.md#adding-a-new-module-to-nf-neuro)
- [Generate the template](./docs/MODULE.md#generate-the-template)
- [Edit the template](./docs/MODULE.md#edit-the-template)
- [Edit `main.nf`](./docs/MODULE.md#edit-mainnf)
- [Edit `environment.yml`](./docs/MODULE.md#edit-environmentyml)
- [Edit `meta.yml`](./docs/MODULE.md#edit-metayml)
- [Create test cases](./docs/MODULE.md#create-test-cases)
- [Edit `tests/main.nf.test`](./docs/MODULE.md#edit-testsmainnftest)
- [Edit `tests/nextflow.config`](./docs/MODULE.md#edit-testsnextflowconfig)
- [Generate tests snapshots](./docs/MODULE.md#generate-tests-snapshots)
- [Request for more test resources](./docs/MODULE.md#request-for-more-test-resources)
- [Lint your code](./docs/MODULE.md#lint-your-code)
- [Submit your PR](./docs/MODULE.md#submit-your-pr)
- [Defining optional input parameters](./docs/MODULE.md#defining-optional-input-parameters)
- [Test data infrastructure](./docs/MODULE.md#test-data-infrastructure)
- [Adding a new subworkflow to nf-neuro](./docs/SUBWORKFLOWS.md#adding-a-new-subworkflow-to-nf-neuro)
- [Generate the template](./docs/SUBWORKFLOWS.md#generate-the-template)
- [Edit the template](./docs/SUBWORKFLOWS.md#edit-the-template)
- [Edit `main.nf`](./docs/SUBWORKFLOWS.md#edit-mainnf)
- [Define your subworkflow inputs](./docs/SUBWORKFLOWS.md#define-your-subworkflow-inputs)
- [Fill the `main:` section](./docs/SUBWORKFLOWS.md#fill-the-main-section)
- [Define your Workflow outputs](./docs/SUBWORKFLOWS.md#define-your-workflow-outputs)
- [Edit `meta.yml`](./docs/SUBWORKFLOWS.md#edit-metayml)
- [Create test cases](./docs/SUBWORKFLOWS.md#create-test-cases)
- [Lint your code](./docs/SUBWORKFLOWS.md#lint-your-code)
- [Submit your PR](./docs/SUBWORKFLOWS.md#submit-your-pr)
- [Running tests](#running-tests)
- [Configuring Docker for easy usage](#configuring-docker-for-easy-usage)
- [Installing Prettier and editorconfig](#installing-prettier-and-editorconfig)
* [Discovering `nf-neuro`](#discovering-nf-neuro)
* [Getting info on components from `nf-neuro`](#getting-info-on-components-from-nf-neuro)
* [Using the information from the `info` command](#using-the-information-from-the-info-command)
* [Pipeline creation with `nf-neuro`](#pipeline-creation-with-nf-neuro)
* [Prototyping using components from `nf-neuro`](#prototyping-using-components-from-nf-neuro)
* [Porting prototypes to `nf-` ready pipelines](#porting-prototypes-to-nf--ready-pipelines)
* [Contributing to the `nf-neuro` project](#contributing-to-the-nf-neuro-project)
* [Running tests](#running-tests)


---

Expand Down Expand Up @@ -221,19 +183,12 @@ PREPROC_T1.out.mask_final.view() // [ [ [id: "sub-1"], "sub-1_t1_mask_cro
PREPROC_T1.out.versions.first().view() // [ "versions.yml" ]
```

# Pipeline creation with `nf-neuro`

# Prototyping using components from `nf-neuro`

> [!IMPORTANT]
> First, follow the [prototyping guide](./docs/environment/PROTOTYPING.md) to setup your
> `development environment` or check if your current one meets the requirements.
## Here we can put what Anthony wrote !

## [Prototyping using components from `nf-neuro`](./docs/PROTOTYPING.md)

# Porting prototypes to `nf-` ready pipelines
## [Porting prototypes to `nf-` ready pipelines](./docs/PRODUCTION.md)

**SECTION TO COME**

# Contributing to the `nf-neuro` project

Expand Down
3 changes: 3 additions & 0 deletions docs/PRODUCTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Porting prototypes to `nf-` ready pipelines

**SECTION TO COME**
166 changes: 166 additions & 0 deletions docs/PROTOTYPING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Prototyping using components from `nf-neuro`

> [!IMPORTANT]
> First, follow the [prototyping guide](./docs/environment/PROTOTYPING.md) to setup your
> `development environment` or check if your current one meets the requirements.
* [Prototyping using components from `nf-neuro`](#prototyping-using-components-from-nf-neuro)
* [Basic prototype pipeline creation](#basic-prototype-pipeline-creation)
* [`main.nf`](#mainnf)
* [`main.nf` example](#mainnf-example)
* [`nextflow.config`](#nextflowconfig)


## Basic prototype pipeline creation

To create a prototype pipeline (for personal use or testing), you will need to create a couple of files in addition to the `nf-neuro` modules/subworkflows. First, create those files at the root of your pipeline:
```
nextflow.config
main.nf
```
The `nextflow.config` file will contain your parameters for your pipeline execution that can be supplied as arguments when calling the pipeline (ex: `nextflow run main.nf --argument1 true`). The `main.nf` file will contain your pipeline. Let's take a look at this one first.

### `main.nf`

As mentioned above, this file will be your main pipeline execution file, containing all the modules/subworkflows you want to run, and the channel definition between them. This is also where you will fetch your input files. This can be done using a workflow definition, here is an example for a basic usage:

```nextflow
workflow get_data {
main:
if ( !params.input ) {
log.info "You must provide an input folder containing all images using:"
log.info " --input=/path/to/[input_folder] Input folder containing multiple subjects for tracking"
log.info ""
log.info " [Input]"
log.info " ├-- S1"
log.info " | ├-- *dwi.nii.gz"
log.info " | ├-- *dwi.bval"
log.info " | ├-- *dwi.bvec"
log.info " | ├-- *revb0.nii.gz"
log.info " | └-- *t1.nii.gz"
log.info " └-- S2"
log.info " ├-- *dwi.nii.gz"
log.info " ├-- *bval"
log.info " ├-- *bvec"
log.info " ├-- *revb0.nii.gz"
log.info " └-- *t1.nii.gz"
error "Please resubmit your command with the previous file structure."
}
input = file(params.input)
// ** Loading all files. ** //
dwi_channel = Channel.fromFilePairs("$input/**/*dwi.{nii.gz,bval,bvec}", size: 3, flat: true)
{ it.parent.name }
.map{ sid, bvals, bvecs, dwi -> tuple(meta.id: sid, dwi, bvals, bvecs) } // Reordering the inputs.
rev_channel = Channel.fromFilePairs("$input/**/*revb0.nii.gz", size: 1, flat: true)
{ it.parent.name }
.map{ sid, rev -> tuple(meta.id: sid, rev) }
t1_channel = Channel.fromFilePairs("$input/**/*t1.nii.gz", size: 1, flat: true)
{ it.parent.name }
.map{ sid, t1 -> tuple(meta.id: sid, t1) }
emit:
dwi = dwi_channel
rev = rev_channel
t1 = t1_channel
}
// ** Now call your input workflow to fetch your files ** //
data = get_data()
data.dwi.view() // Contains your DWI data: [meta, [dwi, bval, bvec]]
data.rev.view() // Contains your reverse B0 data: [meta, [rev]]
data.t1.view() // Contains your anatomical data (T1 in this case): [meta, [t1]]
```

Now, you can install the modules you want to include in your pipeline. Let's import the `denoising/nlmeans` module for T1 denoising. To do so, simply install it using the `nf-core modules install` command.
```bash
nf-core modules install denoising/nlmeans
```
To use it in your pipeline, you need to import it at the top of your `main.nf` file. You can do it using the `include { YOUR_NAME } from ../path/main.nf` statement. Then, you can add it to your pipeline and feed your inputs to it! To have a look at which files are required to run the module, use the `nf-core modules info <your/module>` command. A complete example (e.g., fetching the inputs, importing the module, and supplying the inputs to the modules) can be seen below:
#### `main.nf` example
```nextflow
include { DENOISING_NLMEANS } from './modules/nf-neuro/denoising/nlmeans/main.nf'
workflow get_data {
main:
if ( !params.input ) {
log.info "You must provide an input folder containing all images using:"
log.info " --input=/path/to/[input_folder] Input folder containing multiple subjects for tracking"
log.info ""
log.info " [Input]"
log.info " ├-- S1"
log.info " | ├-- *dwi.nii.gz"
log.info " | ├-- *dwi.bval"
log.info " | ├-- *dwi.bvec"
log.info " | ├-- *revb0.nii.gz"
log.info " | └-- *t1.nii.gz"
log.info " └-- S2"
log.info " ├-- *dwi.nii.gz"
log.info " ├-- *bval"
log.info " ├-- *bvec"
log.info " ├-- *revb0.nii.gz"
log.info " └-- *t1.nii.gz"
error "Please resubmit your command with the previous file structure."
}
input = file(params.input)
// ** Loading all files. ** //
dwi_channel = Channel.fromFilePairs("$input/**/*dwi.{nii.gz,bval,bvec}", size: 3, flat: true)
{ it.parent.name }
.map{ sid, bvals, bvecs, dwi -> tuple(meta.id: sid, dwi, bvals, bvecs) } // Reordering the inputs.
rev_channel = Channel.fromFilePairs("$input/**/*revb0.nii.gz", size: 1, flat: true)
{ it.parent.name }
anat_channel = Channel.fromFilePairs("$input/**/*t1.nii.gz", size: 1, flat: true)
{ it.parent.name }
emit: // Those three lines below define your named output, use those labels to select which file you want.
dwi = dwi_channel
rev = rev_channel
anat = anat_channel
}
inputs = get_data()
// ** Create the input channel for nlmeans. Note that it also can take a mask as input, but it is not required, replacing it by an empty list here. ** //
ch_denoising = inputs.t1
.map{ it + [[]] } // This add one empty list to the channel, since we do not have a mask.
// ** Run DENOISING_NLMEANS ** //
DENOISING_NLMEANS( ch_denoising )
// ** You can then reuse the outputs and supply them to another module/subworkflow! ** //
ch_nextmodule = DENOISING_NLMEANS.out.image
.join(ch_another_file)
NEXT_MODULE( ch_nextmodule )
```

### `nextflow.config`

You now have a working `main.nf` file, but you did not specified any parameters to your pipeline yet. Let's do this using the `nextflow.config` file. First, you will want to define your publish directory options (where your files will be outputted). You can add those lines to the beginning of your `nextflow.config`:
```nextflow
process {
publishDir = {"${params.output_dir}/$meta.id/${task.process.replaceAll(':', '-')}"}
}
```

Once this is done, you might want to supply parameters for some of your modules that could be modified when calling the pipeline, you can add them under the `params` flag. To know which parameters are accepted in your modules, refer to the `main.nf` of the specific `nf-neuro` module. `denoising/nlmeans` takes 1 possible parameter: `number_of_coils`. By defining it as below, we will be able to modify its value during the pipeline call using `--number_of_coils 1`.
```nextflow
params{
input = false // This will be used to supply your input directory, using --input folder/
// ** Denoising nlmeans parameters ** //
number_of_coils = 1
}
```
The last step is to bind your parameters to the specific module they are meant for. This can be done by explicitly stating the modules, and attaching the parameters to the appropriate `task.ext`. To do this, add those lines for each of your modules in your `nextflow.config`:
```nextflow
withName: 'DENOISING_NLMEANS' {
ext.number_of_coils = params.number_of_coils
}
```

That's it! Your `nextflow.config` should look something like this:
```
process {
publishDir = {"${params.output_dir}/$sid/${task.process.replaceAll(':', '-')}"}
}
params{
input = false // This will be used to supply your input directory, using --input folder/
// ** Denoising nlmeans parameters ** //
number_of_coils = 1
}
withName: 'DENOISING_NLMEANS' {
ext.number_of_coils = params.number_of_coils
}
```

Once your pipeline is built, or when you want to test it, run `nextflow run main.nf --input <folder> --param1 true --param2 4 ...`.
8 changes: 8 additions & 0 deletions docs/environment/DEVCONTAINER.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
your development. They provide `pre-installed` environments for you to start programming
new `pipelines` or `nf-neuro components`.

* [Using `nf-neuro` development containers](#using-nf-neuro-development-containers)
* [Requirements](#requirements)
* [Configuring Docker for easy usage](#configuring-docker-for-easy-usage)
* [Prototyping environment](#prototyping-environment)
* [Production environment](#production-environment)
* [Development environment](#development-environment)


## Requirements

- [VS Code](https://code.visualstudio.com) &geq; 1.95
Expand Down
10 changes: 10 additions & 0 deletions docs/environment/DEVOPS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

The `nf-neuro` project requires some specific tools to be installed on your system so that the development environment runs correctly. You can [install them manually](#manual-configuration), but if you desire to streamline the process and start coding faster, we highly recommend using the [VS Code development container](./docs/DEVCONTAINER.md#development-environment) to get fully configured in a matter of minutes.

* [Developing within `nf-neuro`](#developing-within-nf-neuro)
* [Manual configuration](#manual-configuration)
* [Dependencies](#dependencies)
* [Python environment](#python-environment)
* [Loading the project's environment](#loading-the-projects-environment)
* [Global environment](#global-environment)
* [Working with VS Code](#working-with-vs-code)
* [Installing Prettier and editorconfig](#installing-prettier-and-editorconfig)


## Manual configuration

### Dependencies
Expand Down
11 changes: 8 additions & 3 deletions docs/environment/PROTOTYPING.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Prototyping environment setup
# Prototyping environment setup

> [!NOTE]
> `Nextflow` chose [VS Code](https://code.visualstudio.com) as its main development IDE (with good reasons), give
Expand All @@ -10,7 +10,12 @@
> and support your development through `VS Code`. To setup yourself, refer to [this section](./docs/DEVCONTAINER.md)
> and skip the whole environment setup.
### Dependencies :
* [Prototyping environment setup](#prototyping-environment-setup)
* [Dependencies](#dependencies-)
* [Configuration](#configuration-)


## Dependencies

- Python &geq; 3.8, < 3.13
- Docker &geq; 24 (we recommend using [Docker Desktop](https://www.docker.com/products/docker-desktop))
Expand All @@ -30,7 +35,7 @@
> runtime version (named `jdk<inner version>_1<runtime version>.jdk`) and use the
> following : `/Library/Java/JavaVirtualMachines/jdk<inner version>_1<runtime version>.jdk/Contents/Home`.
### Configuration :
## Configuration

Install `nf-core` in your `python` environment (we recommend using a `virtual environment`) :

Expand Down

0 comments on commit 6db6a88

Please sign in to comment.