Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions modules/nf-core/finaletoolkit/delfi/environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json
channels:
- conda-forge
- bioconda
dependencies:
- "bioconda::finaletoolkit=0.11.1"
46 changes: 46 additions & 0 deletions modules/nf-core/finaletoolkit/delfi/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
process FINALETOOLKIT_DELFI {
tag "${meta.id}"
label 'process_medium'

conda "${moduleDir}/environment.yml"
container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container
? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/34/34f01d128ed135aedc33ddb62fced3911bef6d1a909694291b7184bf83719402/data'
: 'community.wave.seqera.io/library/finaletoolkit:0.11.1--8fe5ba6ec9e2ec95'}"

input:
tuple val(meta), path(bam), path(bai)
tuple val(meta2), path(genome_2bit)
tuple val(meta3), path(chromosome_sizes)
tuple val(meta4), path(bins)

output:
tuple val(meta), path("*.bed"), emit: bed
tuple val("${task.process}"), val('finaletoolkit'), eval("finaletoolkit --version | sed 's/FinaleToolkit //g'"), topic: versions, emit: versions_finaletoolkit

when:
task.ext.when == null || task.ext.when

script:
def args = task.ext.args ?: ''
def prefix = task.ext.prefix ?: "${meta.id}_delfi"
"""
finaletoolkit \\
delfi \\
-w ${task.cpus} \\
${bam} \\
${chromosome_sizes} \\
${genome_2bit} \\
${bins} \\
${args} \\
-o "${prefix}.bed"
"""

stub:
def args = task.ext.args ?: ''
def prefix = task.ext.prefix ?: "${meta.id}_delfi"
"""
echo ${args}

touch ${prefix}.bed
"""
}
111 changes: 111 additions & 0 deletions modules/nf-core/finaletoolkit/delfi/meta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: "finaletoolkit_delfi"
description: |
Calculate the DELFI scores (Cristiano et al., 2019) from a BAM file.
keywords:
- delfi_score
- genomics
- fragmentomics
tools:
- "finaletoolkit":
description: "Extract cfDNA fragmentation features from sequencing data."
homepage: "https://epifluidlab.github.io/FinaleToolkit/"
documentation: "https://epifluidlab.github.io/FinaleToolkit/documentation/index.html"
tool_dev_url: "https://github.com/epifluidlab/FinaleToolkit"
doi: "10.1093/bioadv/vbaf236"
licence:
- "MIT"
identifier: biotools:finaletoolkit
input:
- - meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- bam:
type: file
description: Sorted BAM file
pattern: "*.bam"
ontologies:
- edam: "http://edamontology.org/format_2572"
Comment on lines +24 to +29
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work with cram files?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I'm not sure. I'll check the code directly, but it looks like it wants BAM. I'll investigate.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked and it does, in principle. How should I handle this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cram files require the fasta file to be staged, not the 2bit file, so it could do with another input channel. You can say in the meta that the fasta is only for cram input.
You can still call it bam/bai, just make it clear that it also accepts cram.

Copy link
Copy Markdown
Contributor Author

@lbeltrame lbeltrame May 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I triple checked. While it claims to support CRAM files, the delfi command does not actually support them, because it doesn't pass the required FASTA reference to the input function (see https://github.com/epifluidlab/FinaleToolkit/blob/5431559c7fbe79d9bfaf70054fc064084b7a35eb/src/finaletoolkit/utils/_frag_generator.py#L14 and https://github.com/epifluidlab/FinaleToolkit/blob/5431559c7fbe79d9bfaf70054fc064084b7a35eb/src/finaletoolkit/frag/_delfi.py#L387 for reference)

So I'll stay with BAM for the moment. I'll raise an issue upstream.

EDIT: filed epifluidlab/FinaleToolkit#173

- bai:
type: file
description: BAM file index
pattern: "*.bai"
ontologies:
- edam: "http://edamontology.org/format_3327"
- - meta2:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- genome_2bit:
type: file
description: |
2bit compressed genome file (must be the same as the one used for the
BAM file)
pattern: "*.2bit"
ontologies:
- edam: "http://edamontology.org/format_3009"
- - meta3:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- chromosome_sizes:
type: file
pattern: "*.sizes"
description: |
Two-column file containing the size for each chromosome
ontologies:
- edam: "http://edamontology.org/format_3475"
- - meta4:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- bins:
type: file
description: |
BED containing binned genomic coordinates
pattern: "*.bed"
ontologies:
- edam: "http://edamontology.org/format_3003"
output:
bed:
- - meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- "*.bed":
type: file
pattern: "*.bed"
description: |
BED file containing DELFI scores
ontologies:
- edam: "http://edamontology.org/format_3003"
versions_finaletoolkit:
- - ${task.process}:
type: string
description: The name of the process
- finaletoolkit:
type: string
description: The name of the tool
- "finaletoolkit --version | sed 's/FinaleToolkit //g'":
type: eval
description: The expression to obtain the version of the tool
topics:
versions:
- - ${task.process}:
type: string
description: The name of the process
- finaletoolkit:
type: string
description: The name of the tool
- "finaletoolkit --version | sed 's/FinaleToolkit //g'":
type: eval
description: The expression to obtain the version of the tool
authors:
- "@lbeltrame"
maintainers:
- "@lbeltrame"
94 changes: 94 additions & 0 deletions modules/nf-core/finaletoolkit/delfi/tests/main.nf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
nextflow_process {

name "Test Process FINALETOOLKIT_DELFI"
script "../main.nf"
process "FINALETOOLKIT_DELFI"

tag "modules"
tag "modules_nfcore"
tag "finaletoolkit"
tag "finaletoolkit/delfi"

test("homo_sapiens - bam") {

when {

Comment thread
lbeltrame marked this conversation as resolved.
process {

config "./nextflow.config"

"""
input[0] = [
[ id:'test' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true),
]
input[1] = [
[id: 'genome' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.2bit', checkIfExists: true),
]
input[2] = [
[id: 'sizes' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.sizes', checkIfExists: true),
]
input[3] = [
[id: 'bins' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bins_10kb.bed', checkIfExists: true),
]
"""
}
}

then {
assert process.success
assertAll(
{ assert snapshot(sanitizeOutput(process.out)).match() }
)

}

}

test("homo_sapiens - stub") {

options "-stub"

when {

process {

config "./nextflow.config"

"""
input[0] = [
[ id:'test' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true),
]
input[1] = [
[id: 'genome' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.2bit', checkIfExists: true),
]
input[2] = [
[id: 'sizes' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.sizes', checkIfExists: true),
]
input[3] = [
[id: 'bins' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bins_10kb.bed', checkIfExists: true),
]
"""
}
}

then {
assert process.success
assertAll(
{ assert snapshot(sanitizeOutput(process.out)).match() }
)

}

}

}
54 changes: 54 additions & 0 deletions modules/nf-core/finaletoolkit/delfi/tests/main.nf.test.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"homo_sapiens - stub": {
"content": [
{
"bed": [
[
{
"id": "test"
},
"test_delfi.bed:md5,d41d8cd98f00b204e9800998ecf8427e"
]
],
"versions_finaletoolkit": [
[
"FINALETOOLKIT_DELFI",
"finaletoolkit",
"0.11.1"
]
]
}
],
"meta": {
"nf-test": "0.9.3",
"nextflow": "25.10.4"
},
"timestamp": "2026-05-13T10:11:29.437687922"
},
"homo_sapiens - bam": {
"content": [
{
"bed": [
[
{
"id": "test"
},
"test_delfi.bed:md5,125dc88e57b66bf668a8961c81ede4a8"
]
],
"versions_finaletoolkit": [
[
"FINALETOOLKIT_DELFI",
"finaletoolkit",
"0.11.1"
]
]
}
],
"meta": {
"nf-test": "0.9.3",
"nextflow": "25.10.4"
},
"timestamp": "2026-05-13T10:11:25.9475089"
}
}
9 changes: 9 additions & 0 deletions modules/nf-core/finaletoolkit/delfi/tests/nextflow.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
process {
withName: 'FINALETOOLKIT_DELFI' {
// Chr22 is too small for meaningful data, so remove all filters
// We need 2 workers because otherwise there is a bug (fixed upstream, but without a new version)
// that breaks the program with only one worker
cpus = 2
ext.args = "--no-merge-bins --no-gc-correct --quality-threshold 0"
}
}
Loading