Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ repos:
hooks:
- id: nextflow-lint
files: '\.nf$|nextflow\.config$'
# nf-core component tests are nf-core/modules' own; some include modules this pipeline does not install
# (subworkflows/nf-core/deepvariant/tests includes deepvariant/rundeepvariant)
exclude: "^(modules|subworkflows)/nf-core/.*/tests/"
args: ["-output", "json"]
- repo: local
hooks:
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
| `fibertools-rs` | 0.8.1 | 0.13.1 | **Fiber-seq BAMs now carry nucleosomes, MSPs and FIREs in the MolecularAnnotation tags `Ma` (`nuc`, `msp` and `fire` intervals) and `Aq` (their qualities)** instead of `ns`/`nl`/`as`/`al`/`aq`; downstream tools reading the old tags need `ft convert-tags` or an update |
| `wakhan` | 0.4.3 | 0.4.4 | 0.5.0 changes the output directory layout and has no biocontainer yet |

- [#213](https://github.com/IntGenomicsLab/lrsomatic/pull/213) - Updated the small variant callers. **Germline and somatic calls change** with the new models (@ljwharbers).

| Tool | Old | New | Notes |
| ------------- | ----- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clair3` | 1.2.0 | 2.0.3 | Clair3 v2 runs on PyTorch and **cannot read the v1 TensorFlow models** the pipeline downloaded from ONT's CDN. Models bundled with the image (HKU's and ONT's recent R10.4.1 SUP/HAC ones, `hifi_revio`) are now used from the image with no download; other models are fetched as PyTorch directories from HKU (ONT's Rerio catalogue for `r9`/`r10` names) by the new `CLAIR3_MODEL` step, which replaces `WGET`/`UNTAR`. The GPU image is `hkubal/clair3:v2.0.2_gpu`, the newest published |
| `clairs` | 0.4.4 | 0.5.1 | Bundles Clair3 2.0.3 for its germline step |
| `deepvariant` | 1.9.0 | 1.10.0 | nf-core update; `make_examples` now takes its flags from the model (`--checkpoint`): the ONT model is 199 wide with the new fuzzy channel, and both models call easy sites with the small model |
| `deepsomatic` | 1.7.0 | 1.10.0 | `make_examples_somatic` now takes its flags from the model (`--checkpoint`) instead of a hard-coded channel list and pileup width; the paired PacBio model is 147 wide with 9 channels. The small model is kept off explicitly (`--nocall_small_model_examples`), because the module does not pass its calls on |

## v1.1.0 - [2026-04-28]

### `Added`
Expand Down
36 changes: 10 additions & 26 deletions conf/modules.config
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,10 @@ process {
]
}

// DeepVariant 1.10 checkpoints carry their make_examples flags in model.example_info.json, read via
// --checkpoint: the ONT model is 199 wide with the new fuzzy channel, and both enable the small model
withName: '.*DEEPVARIANT_MAKEEXAMPLES' {
ext.args = {
meta.platform == 'pb'
? '--channel_list "BASE_CHANNELS,haplotype,base_6ma" --alt_aligned_pileup "diff_channels" --pileup_image_width "147"'
: '--channel_list "BASE_CHANNELS,haplotype" --alt_aligned_pileup "diff_channels" --pileup_image_width "99"'
}
ext.args = { "--checkpoint '/opt/models/${meta.platform == 'pb' ? 'pacbio' : 'ont_r104'}'" }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No PR-CI coverage for the DeepVariant/DeepSomatic changes. PR CI only runs tests tagged small, and only tests/default.nf.test has that tag. It runs with germline_var_keep = 'clair' and somatic_var_keep = 'clair', and its snapshot has no DEEPVARIANT_*/DEEPSOMATIC_* entries. That leaves several changes without CI coverage: the 1.10 image bump, the new --checkpoint-driven make_examples flags here and at L208, the rebuilt DeepVariant patches (including the ${meta.id}_germline prefix), and the new gzi/with_phasing subworkflow arguments. Only the extended tests (deep_only, consensus, union, chm13) exercise them. Please run the Slurm test array and link the results before merge.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ran the Slurm array on fc0e823 (this head, with #212 merged in) on Mindwell, -profile debug,test,apptainer --update-snapshot, job 11645738. All seven pass: default, clair_only, consensus, deep_only, union, chm13 and the tumour-only subworkflow test. git status was clean afterwards, so no snapshot moved with the review changes.

The DeepVariant/DeepSomatic outputs hold real calls, not empty files (records / PASS):

sample DV germline DS somatic
sample1 18529 / 11465 9094 / 6
sample2 7499 / 4377 39297 / 0
sample3 20753 / 12879 14429 / 208

The deep_only and union counts are identical. The few somatic PASS calls are expected on the small chr subsets.

The real-data C8 comparison found a bcftools 1.24 problem in #212 (see the PR description and #212). It's fixed and resubmitted as Slurm 11645745. I'll post the caller comparison here when it finishes.

publishDir = [
enabled: false
]
Expand Down Expand Up @@ -204,12 +202,12 @@ process {
]
}

// DeepSomatic 1.10 checkpoints carry their make_examples flags (channels, pileup width, thresholds) in
// model.example_info.json, which make_examples_somatic reads when given --checkpoint; the paired PacBio
// model is 147 wide and 9 channels, so hard-coded flags would no longer match call_variants.
// The small model stays off: the module does not collect its calls, so a checkpoint enabling it would drop them
withName: '.*DEEPSOMATIC_MAKEEXAMPLES' {
ext.args = {
meta.paired_data
? '--channel_list "BASE_CHANNELS,haplotype" --alt_aligned_pileup "diff_channels" --pileup_image_width "99"'
: '--channel_list "BASE_CHANNELS,haplotype,allele_frequency" --alt_aligned_pileup "diff_channels" --pileup_image_width "99"'
}
ext.args = { "--checkpoint '/opt/models/deepsomatic/${meta.platform == 'pb' ? 'pacbio' : 'ont'}${meta.paired_data ? '' : '_tumor_only'}' --nocall_small_model_examples" }
publishDir = [
enabled: false
]
Expand All @@ -231,15 +229,7 @@ process {
}

withName: '.*DEEPSOMATIC_CALLVARIANTS' {
ext.args = {
meta.platform == 'pb'
? (meta.paired_data
? "--checkpoint '/opt/models/deepsomatic/pacbio'"
: "--checkpoint '/opt/models/deepsomatic/pacbio_tumor_only'" )
: (meta.paired_data
? "--checkpoint '/opt/models/deepsomatic/ont'"
: "--checkpoint '/opt/models/deepsomatic/ont_tumor_only'")
}
ext.args = { "--checkpoint '/opt/models/deepsomatic/${meta.platform == 'pb' ? 'pacbio' : 'ont'}${meta.paired_data ? '' : '_tumor_only'}'" }
publishDir = [
enabled : false
]
Expand Down Expand Up @@ -646,7 +636,7 @@ process {
]
}

withName : '.*:WGET' {
withName : '.*:CLAIR3_MODEL' {
ext.args = {
[
"--no-check-certificate"
Expand All @@ -656,12 +646,6 @@ process {
]
}

withName : '.*:UNTAR' {
publishDir = [
enabled: false
]
}

withName : '.*:WGET_(REVEL|EVE)' {
publishDir = [
enabled: false
Expand Down
22 changes: 11 additions & 11 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ sample1,tumour3.bam,,pb,male,n

### Full Description of Samplesheet Columns

| Column | Description |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sample` | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. Spaces in sample names are automatically converted to underscores (`_`). |
| `bam_tumor` | Full path to BAM file for the tumor. File must end in `.bam`. |
| `bam_normal` | Full path to BAM file for the tumor. File must end in `.bam`. |
| `platform` | A string specifying the platform used for sequencing, can be either `pb` for PacBio sequencing data or `ont` for Oxford Nanopore sequencing data |
| `sex` | A string specifying the biological sex of the sample, can either be `m` or `f` |
| `fiber` | A string specifying if the sample has been subjected to Fiber-seq. Can either be `y` or `n` |
| `clair3_model` | A string describing which model is to be used for Clair3's small variant calling (_optional_) |
| `clairSTO_model` | A string describing which model is to be used for ClairS-TO's small variant calling (_optional_) |
| `clairS_model` | A string describing which model is to be used for ClairS's small variant calling (_optional_) |
| Column | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sample` | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. Spaces in sample names are automatically converted to underscores (`_`). |
| `bam_tumor` | Full path to BAM file for the tumor. File must end in `.bam`. |
| `bam_normal` | Full path to BAM file for the tumor. File must end in `.bam`. |
| `platform` | A string specifying the platform used for sequencing, can be either `pb` for PacBio sequencing data or `ont` for Oxford Nanopore sequencing data |
| `sex` | A string specifying the biological sex of the sample, can either be `m` or `f` |
| `fiber` | A string specifying if the sample has been subjected to Fiber-seq. Can either be `y` or `n` |
| `clair3_model` | A Clair3 model name (_optional_). Clair3 v2 only reads PyTorch models: names bundled with Clair3 (e.g. `r1041_e82_400bps_sup_v500`, `hifi_revio`) are used from the image, other ONT names are downloaded from [HKU's PyTorch conversion of Rerio](https://www.bio8.cs.hku.hk/clair3/clair3_models_rerio_pytorch/) |
| `clairSTO_model` | A string describing which model is to be used for ClairS-TO's small variant calling (_optional_) |
| `clairS_model` | A string describing which model is to be used for ClairS's small variant calling (_optional_) |

An [example samplesheet](../assets/samplesheet.csv) has been provided with the pipeline.

Expand Down
13 changes: 4 additions & 9 deletions modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,19 @@
},
"deepvariant/callvariants": {
"branch": "master",
"git_sha": "f2b138ee1d91f67d31c187317d7e83e429bf0309",
"git_sha": "4a4ccce52d5a280b0b136ff3ac841607debed92b",
"installed_by": ["deepvariant"],
"patch": "modules/nf-core/deepvariant/callvariants/deepvariant-callvariants.diff"
},
"deepvariant/makeexamples": {
"branch": "master",
"git_sha": "f2b138ee1d91f67d31c187317d7e83e429bf0309",
"git_sha": "4a4ccce52d5a280b0b136ff3ac841607debed92b",
"installed_by": ["deepvariant"],
"patch": "modules/nf-core/deepvariant/makeexamples/deepvariant-makeexamples.diff"
},
"deepvariant/postprocessvariants": {
"branch": "master",
"git_sha": "f2b138ee1d91f67d31c187317d7e83e429bf0309",
"git_sha": "4a4ccce52d5a280b0b136ff3ac841607debed92b",
"installed_by": ["deepvariant"],
"patch": "modules/nf-core/deepvariant/postprocessvariants/deepvariant-postprocessvariants.diff"
},
Expand Down Expand Up @@ -202,11 +202,6 @@
"installed_by": ["modules"],
"patch": "modules/nf-core/severus/severus.diff"
},
"untar": {
"branch": "master",
"git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120",
"installed_by": ["modules"]
},
"unzip": {
"branch": "master",
"git_sha": "1c43a7e22f04cf19c9f9d3de7e7e5a3addd9382a",
Expand All @@ -233,7 +228,7 @@
},
"deepvariant": {
"branch": "master",
"git_sha": "f2b138ee1d91f67d31c187317d7e83e429bf0309",
"git_sha": "6ef220fd9252b42fb3c50348bbdbcb6246730686",
"installed_by": ["subworkflows"],
"patch": "subworkflows/nf-core/deepvariant/deepvariant.diff"
},
Expand Down
2 changes: 1 addition & 1 deletion modules/local/clair3/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ channels:
- conda-forge
- bioconda
dependencies:
- "bioconda::clair3=1.0.10"
- "bioconda::clair3=2.0.3"
15 changes: 11 additions & 4 deletions modules/local/clair3/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ process CLAIR3 {
label "${params.use_gpu ? 'process_gpu_very_high' : 'process_very_high'}"

conda "${moduleDir}/environment.yml"
container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
(params.use_gpu ? 'docker://hkubal/clair3-gpu:v1.2.0' : 'https://depot.galaxyproject.org/singularity/clair3:1.2.0--py310h779eee5_0') :
(params.use_gpu ? 'docker.io/hkubal/clair3-gpu:v1.2.0' : 'quay.io/biocontainers/clair3:1.2.0--py310h779eee5_0') }"
// No GPU image was published for 2.0.3; 2.0.2 differs only by the --gender option, which is not used here
container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ?
(params.use_gpu ? 'docker://docker.io/hkubal/clair3:v2.0.2_gpu' : 'https://depot.galaxyproject.org/singularity/clair3:2.0.3--py311hbc58adc_0') :
(params.use_gpu ? 'docker.io/hkubal/clair3:v2.0.2_gpu' : 'quay.io/biocontainers/clair3:2.0.3--py311hbc58adc_0') }"

input:
tuple val(meta) , path(bam), path(bai), path(model), val(platform)
Expand All @@ -26,16 +27,22 @@ process CLAIR3 {
def args = task.ext.args ?: ''
prefix = task.ext.prefix ?: "${meta.id}"
def use_gpu = task.ext.use_gpu as boolean
// An empty model input means the model is bundled with the image: models/ next to run_clair3.sh
// in the biocontainer, /opt/models in the HKU Docker image
def model_path = model ? "${model}" : "\${CLAIR3_MODELS}/${meta.clair3_model}"

"""
${use_gpu ? 'export CUDA_VISIBLE_DEVICES=${CUDA_VISIBLE_DEVICES:-0}' : ':'}
CLAIR3_MODELS=\$(dirname \$(command -v run_clair3.sh))/models
[ -d "\${CLAIR3_MODELS}" ] || CLAIR3_MODELS=/opt/models

run_clair3.sh \\
--bam_fn=${bam} \\
--ref_fn=${reference} \\
--threads=${task.cpus} \\
--output=. \\
--platform=${platform} \\
--model=${model} \\
--model_path=${model_path} \\
--sample_name=${prefix} \\
${use_gpu ? '--use_gpu --device=cuda:0' : ''} \\
${args}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,5 @@ channels:
- conda-forge
- bioconda
dependencies:
- conda-forge::coreutils=9.5
- conda-forge::grep=3.11
- conda-forge::gzip=1.13
- conda-forge::lbzip2=2.5
- conda-forge::sed=4.8
- conda-forge::tar=1.34
# renovate: datasource=conda depName=conda-forge/wget
- conda-forge::wget=1.21.4
35 changes: 35 additions & 0 deletions modules/local/clair3_model/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
process CLAIR3_MODEL {
tag "${meta.id}"
label 'process_single'

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/3b/3b54fa9135194c72a18d00db6b399c03248103f87e43ca75e4b50d61179994b3/data'
: 'community.wave.seqera.io/library/wget:1.21.4--8b0fcde81c17be5e'}"

input:
tuple val(meta), val(url)

output:
tuple val(meta), path("${meta.id}", type: 'dir'), emit: model
tuple val("${task.process}"), val('wget'), eval('wget --version | head -1 | cut -d " " -f 3'), emit: versions_wget, topic: versions

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

script:
def args = task.ext.args ?: ''
// Clair3 v2 models are directories holding two PyTorch checkpoints, served unpacked
"""
mkdir ${meta.id}
for checkpoint in pileup.pt full_alignment.pt; do
wget ${args} -O ${meta.id}/\$checkpoint ${url}/\$checkpoint
done
"""

stub:
"""
mkdir ${meta.id}
touch ${meta.id}/pileup.pt ${meta.id}/full_alignment.pt
"""
}
Loading
Loading