Skip to content

fix(modkit): patched modkit 0.6.4 for PacBio 5mC+5hmC reads, 5mC-CpG pileup defaults and --modkit_phased option - #188

Merged
AmberVerhasselt merged 14 commits into
devfrom
fix/modkit-pacbio-container
Sep 14, 2026
Merged

AmberVerhasselt merged 14 commits into
devfrom
fix/modkit-pacbio-container

Conversation

@ljwharbers

@ljwharbers ljwharbers commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Description

Recent PacBio HiFi BAMs (Jasmine >= 26.1.3) carry independent 5mC (C+m?) and 5hmC (C+h?) probabilities. At roughly 2 CpGs per read they sum above 1, and stock modkit 0.4.3-0.6.4 rejects the whole read (conflict-explicit-prob-greater-than-one), which cost 32-65 % of reads in modkit pileup (nanoporetech/modkit#612). Two further 0.6.1+ pileup bugs made --cpg pileups on those files return 0 rows. The fix lives on ljwharbers/modkit@pacbio-conflict-fix (commits 697de7b and 6e0afa2) and is proposed upstream in nanoporetech/modkit#720.

Until a modkit release includes it, MODKIT_PILEUP runs a patched image built from that branch by this workflow: ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-6e0afa2 under Docker, and the native SIF oras://ghcr.io/ljwharbers/modkit-sif:0.6.4-pacbiofix-6e0afa2 under Singularity/Apptainer (unless task.ext.singularity_pull_docker_container is set, which falls back to the Docker image). The image is linux/amd64 only, so the arm64 profile is not supported for this step. Conda is not supported either: the module drops its conda directive and stops with an error under -profile conda/mamba (use --skip_modkit there), because environment.yml would install stock ont-modkit 0.6.1 and silently reintroduce the bug this PR fixes.

The second fork commit (6e0afa2, 2026-09-04) fixes modkit's general pileup workers, which modkit selects for PacBio BAMs with 6mA calls (opposite-strand T-a. sub-tags): they ignored the --phased partition (empty _hp1/_hp2) and did not apply --modified-bases as a row filter (an h row next to every m row). Both now behave like the optimized workers that ONT data uses.

New pileup options

A full-size run of the container swap alone produced 30-45 GB bedMethyl files per sample, because modkit pileup ran with no arguments (every modification code, every sequence context). This PR therefore also adds:

  • --modkit_args (string, default --cpg --modified-bases 5mC): arguments passed to modkit pileup via ext.args. The value replaces the default rather than extending it. The default restricts output to 5mC calls at CpG sites, per strand. To get the unfiltered pileup use --modkit_args='' (the = form) or an empty modkit_args entry in a params file: --modkit_args '' becomes true, which nf-schema rejects as a boolean on Nextflow 25.10 and which arrives as the string 'true' on Nextflow 26, where conf/modules.config discards it. Note that --modified-bases only filters the output after the conflict check: on PacBio data, positions where P(5mC)+P(5hmC) > 1 are still dropped (about 1.5 % of CpG calls on h-carrying reads) and non-conflicting 5hmC calls are counted in N_other. Resolving those positions (adjust-mods --ignore h, or an --ignore flag on plain pileup in the fork) is a follow-up.
  • --modkit_phased (boolean, default false): adds --phased and switches the pileup input from the unphased merged BAM to PHASING_HAPLOTYPING.out.tumor_normal_hapbams_ch, the Longphase-haplotagged BAM (HP tag) that nothing consumed before. modkit then writes <sample>_hp1.bed.gz, <sample>_hp2.bed.gz and <sample>_combined.bed.gz; the nf-core module already handles the directory output, so no module change was needed. The MODKIT_PILEUP call moved below the phasing subworkflow so it can pick either input.

Changes:

  • modules/nf-core/modkit/pileup/main.nf: container swapped, with a comment saying when to revert to the biocontainer; conda directive removed and a conda/mamba guard added in the script block.
  • modules/nf-core/modkit/pileup/tests/main.nf.test: inputs fixed for the four-channel module (the fasta/fai split predates this PR) so the test can run.
  • modules/nf-core/modkit/pileup/tests/main.nf.test.snap: regenerated from a real run of the patched image (10/10 pass): versions 0.6.4, bedMethyl md5s follow the binary.
  • modules/nf-core/modkit/pileup/modkit-pileup.diff: patch refreshed so it carries the container change, the conda guard and the test changes next to the existing fasta/fai input split.
  • nextflow.config, nextflow_schema.json: modkit_args, modkit_phased in a new "Modkit options" group.
  • conf/modules.config: ext.args for MODKIT_PILEUP.
  • workflows/lrsomatic.nf: pileup input selection, call moved after PHASING_HAPLOTYPING.
  • docs/usage.md, docs/output.md, CHANGELOG.md.

Verification

Container (chr20 subset of an affected PacBio BAM, Apptainer build of the same commit): adjust-mods --ignore h writes 2,687 records (stock: 1,035), pileup --cpg gives 21,957 CpG positions (stock: 0).

Full-size pipeline run of the container swap (3 tumor-only samples: old PacBio, new PacBio, ONT; CHM13; 121/121 tasks OK in 5h12m) produced 30-45 GB unfiltered pileups per sample, which motivated the new defaults.

nextflow run -preview with -profile test,singularity succeeds with modkit_phased on and off; the DAG shows MODKIT_PILEUP fed by LONGPHASE_HAPLOTAG + SAMTOOLS_INDEX in phased mode and by the merged alignment BAM otherwise. pre-commit and nf-core pipelines lint (schema/config keys) pass.

Module test (nf-test test modules/nf-core/modkit/pileup/tests/main.nf.test, Apptainer on Mindwell, 2026-09-14): 10/10 pass with the patched image and the snapshot was re-recorded from that run; under -profile conda every case stops with MODKIT_PILEUP does not support Conda. -preview with --modkit_args '' fails validation on Nextflow 25.10.4 (--modkit_args (true): Value is [boolean] but should be [string]) and passes on 26.04 with modkit_args: true; --modkit_args='' passes on both with an empty value.

Real-data -resume reruns (same 3 samples and work dir as above; the three MODKIT_PILEUP tasks re-ran, ~30 min each for the phased run with the 6e0afa2 image on 2026-09-04):

Sample Unfiltered (before) --cpg --modified-bases 5mC phased _hp1 / _hp2 / _combined rows (image 697de7b) phased _hp1 / _hp2 / _combined rows (image 6e0afa2)
BL1_ont 45 GB 1.0 GB, m rows only 53.7 M / 54.9 M / 66.2 M 53.7 M / 54.9 M / 66.2 M (unchanged)
DLBCL16_oldpb 39 GB 852 MB 0 / 0 / 64.0 M 49.3 M / 51.1 M / 64.0 M
FL11_newpb 30 GB 1.6 GB 0 / 0 / 127.1 M (h + m rows) 51.0 M / 52.2 M / 63.5 M (m rows only)

With the 6e0afa2 image every file of every sample contains only m rows, and the PacBio haplotype files are populated (the haplotagged PacBio BAMs carry HP/PS on 68-78 % of reads). The unphased default-mode rerun with the same image gives single files of 63.5 M (FL11, was 127.1 M with h rows) / 64.0 M (DLBCL16) / 66.2 M (BL1) m rows. Logs show producing phased output, parsed 1 base modification(s) ... counted as 'N_other', and for PacBio using general workers plus (FL11) dropped 11166779 position(s) where the base modification probabilities summed to more than 1.0. On a chr20 subset of FL11, hp1 + hp2 coverage never exceeds the combined coverage at any position and _combined is identical to the unphased run.

nf-test (--profile=+singularity, all five pipeline tests): 4 pass; clair_only fails on one snapshot entry, the md5 of sample4_tumor.bam (the two-replicate samtools merge output), which is unrelated to this PR since the test profile skips modkit. That md5 looks order-dependent and could be excluded via tests/.nftignore in a follow-up.

Note: the pipeline test profile sets skip_modkit = true, so CI does not exercise this process. The download_pipeline job resolves the new container string, which requires the ghcr package to be public.

PR checklist

  • This comment contains a description of changes (with reason).
  • If you've fixed a bug or added code that should be tested, add tests! (module test fixed and re-recorded; no methylation-tagged test data in the pipeline test profile)
  • Make sure your code lints (nf-core pipelines lint).
  • Ensure the test suite passes (nextflow run . -profile test,docker --outdir <OUTDIR>).
  • Check for unexpected warnings in debug mode (nextflow run . -profile debug,test,docker --outdir <OUTDIR>).
  • CHANGELOG.md is updated.

🤖 Generated with Claude Code

… with 5mC+5hmC > 1

Stock modkit 0.4.3-0.6.4 rejects every read whose per-base 5mC and 5hmC
probabilities sum above 1, which happens at ~2 CpGs per read in recent
PacBio HiFi BAMs (Jasmine >= 26.1.3) and cost 32-65 % of reads in pileup
(nanoporetech/modkit#612). Two further 0.6.1+ pileup bugs made --cpg
pileups on those files return 0 rows.

MODKIT_PILEUP now uses ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-697de7b,
built from ljwharbers/modkit@pacbio-conflict-fix (proposed upstream in
nanoporetech/modkit#720), until a modkit release includes the fix. The
module patch is refreshed to carry the container change alongside the
existing fasta/fai input split, and the module snapshot version string
follows the binary (0.6.4).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 2, 2026 14:18
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

nf-core pipelines lint overall result: Passed ✅ ⚠️

Posted for pipeline commit 272d1f8

+| ✅ 208 tests passed       |+
#| ❔  22 tests were ignored |#
!| ❗  39 tests had warnings |!
Details

❗ Test warnings:

  • nextflow_config - Config manifest.version should end in dev: 1.1.0
  • pipeline_todos - TODO string in lint_log.txt: Named file extensions MUST be emitted for ALL output channels
  • pipeline_todos - TODO string in lint_log.txt: List additional required output channels/values here
  • pipeline_todos - TODO string in lint_log.txt: Named file extensions MUST be emitted for ALL output channels
  • pipeline_todos - TODO string in lint_log.txt: List additional required output channels/values here
  • pipeline_todos - TODO string in lint_log.txt: Named file extensions MUST be emitted for ALL output channels
  • pipeline_todos - TODO string in lint_log.txt: List additional required output channels/values here
  • pipeline_todos - TODO string in lint_log.txt: Named file extensions MUST be emitted for ALL output channels
  • pipeline_todos - TODO string in lint_log.txt: List additional required output channels/values here
  • pipeline_todos - TODO string in lint_log.txt: Named file extensions MUST be emitted for ALL output channels
  • pipeline_todos - TODO string in lint_log.txt: List additional required output channels/values here
  • pipeline_todos - TODO string in lint_log.txt: Named file extensions MUST be emitted for ALL output channels
  • pipeline_todos - TODO string in lint_log.txt: List additional required output channels/values here
  • pipeline_todos - TODO string in lint_log.txt: Named file extensions MUST be emitted for ALL output channels
  • pipeline_todos - TODO string in lint_log.txt: List additional required output channels/values here
  • pipeline_todos - TODO string in lint_log.txt: Named file extensions MUST be emitted for ALL output channels
  • pipeline_todos - TODO string in lint_log.txt: List additional required output channels/values here
  • pipeline_todos - TODO string in README.md: Include a figure that guides the user through the major workflow steps. Many nf-core
  • pipeline_todos - TODO string in nextflow.config: Specify your pipeline's command line flags
  • pipeline_todos - TODO string in nextflow.config: Update the field with the details of the contributors to your pipeline. New with Nextflow version 24.10.0
  • pipeline_todos - TODO string in nextflow.config: Specify any additional parameters here
  • pipeline_todos - TODO string in CONTRIBUTING.md: Add any pipeline specific contribution guidelines here, such as coding styles, procedures, checklists etc.
  • pipeline_todos - TODO string in base.config: Check the defaults for all processes
  • pipeline_todos - TODO string in base.config: Customise requirements for specific processes.
  • pipeline_todos - TODO string in meta.yml: #Add a description of the module and list keywords
  • pipeline_todos - TODO string in methods_description_template.yml: #Update the HTML below to your preferred methods description, e.g. add publication citation for this pipeline
  • schema_description - Ungrouped param in schema: skip_modkit
  • schema_description - No description provided in schema for parameter: generate_gvcf
  • schema_description - No description provided in schema for parameter: autocorrelation
  • schema_description - No description provided in schema for parameter: vep_custom
  • schema_description - No description provided in schema for parameter: vep_custom_tbi
  • schema_description - No description provided in schema for parameter: severus_minsupport
  • schema_description - No description provided in schema for parameter: wakhan_chroms
  • local_component_structure - deepsomatic.nf in subworkflows/local should be moved to a SUBWORKFLOW_NAME/main.nf structure
  • local_component_structure - prepare_reference_files.nf in subworkflows/local should be moved to a SUBWORKFLOW_NAME/main.nf structure
  • local_component_structure - small_variant_consensus.nf in subworkflows/local should be moved to a SUBWORKFLOW_NAME/main.nf structure
  • local_component_structure - prepare_annotation.nf in subworkflows/local should be moved to a SUBWORKFLOW_NAME/main.nf structure
  • local_component_structure - prepare_signatures.nf in subworkflows/local should be moved to a SUBWORKFLOW_NAME/main.nf structure
  • local_component_structure - phasing_haplotyping.nf in subworkflows/local should be moved to a SUBWORKFLOW_NAME/main.nf structure

❔ Tests ignored:

  • files_exist - File is ignored: CODE_OF_CONDUCT.md
  • files_exist - File is ignored: assets/nf-core-lrsomatic_logo_light.png
  • files_exist - File is ignored: docs/images/nf-core-lrsomatic_logo_light.png
  • files_exist - File is ignored: docs/images/nf-core-lrsomatic_logo_dark.png
  • files_exist - File is ignored: .github/ISSUE_TEMPLATE/config.yml
  • files_exist - File is ignored: .github/workflows/awstest.yml
  • files_exist - File is ignored: .github/workflows/awsfulltest.yml
  • files_exist - File is ignored: .github/CONTRIBUTING.md
  • nextflow_config - Config variable ignored: manifest.name
  • nextflow_config - Config variable ignored: manifest.homePage
  • files_unchanged - File ignored due to lint config: .gitattributes
  • files_unchanged - File ignored due to lint config: CODE_OF_CONDUCT.md
  • files_unchanged - File ignored due to lint config: .github/ISSUE_TEMPLATE/bug_report.yml
  • files_unchanged - File ignored due to lint config: .github/PULL_REQUEST_TEMPLATE.md
  • files_unchanged - File ignored due to lint config: .github/workflows/branch.yml
  • files_unchanged - File ignored due to lint config: .github/workflows/linting.yml
  • files_unchanged - File ignored due to lint config: assets/email_template.txt
  • files_unchanged - File ignored due to lint config: assets/nf-core-lrsomatic_logo_light.png
  • files_unchanged - File ignored due to lint config: docs/images/nf-core-lrsomatic_logo_light.png
  • files_unchanged - File ignored due to lint config: docs/images/nf-core-lrsomatic_logo_dark.png
  • files_unchanged - File ignored due to lint config: docs/README.md
  • actions_awstest - 'awstest.yml' workflow not found: /home/runner/work/lrsomatic/lrsomatic/.github/workflows/awstest.yml

✅ Tests passed:

Run details

  • nf-core/tools version 4.1.0
  • Run at 2026-09-14 12:36:37

Copilot AI left a comment

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.

🟡 Changes recommended

The module still declares a conda environment pinned to ont-modkit=0.6.1, so -profile conda/mamba would not use the patched container and would undermine the PR’s intended PacBio fix unless explicitly blocked or updated.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates the nf-core modkit/pileup module to use a patched Modkit 0.6.4 container image that avoids dropping PacBio HiFi reads where independent 5mC+5hmC probabilities can sum > 1, and aligns the module test snapshot with the reported Modkit version.

Changes:

  • Swap MODKIT_PILEUP to a patched ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-697de7b container image (with inline rationale + revert note).
  • Refresh the module patch (modkit-pileup.diff) to include the container update.
  • Update nf-test snapshots to expect Modkit 0.6.4 in the versions channel.
File summaries
File Description
modules/nf-core/modkit/pileup/main.nf Switches process container to patched Modkit image and documents why/when to revert.
modules/nf-core/modkit/pileup/modkit-pileup.diff Regenerated module patch to capture the container change (and snapshot update).
modules/nf-core/modkit/pileup/tests/main.nf.test.snap Updates expected Modkit version string to 0.6.4.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread modules/nf-core/modkit/pileup/main.nf Outdated
Copilot AI review requested due to automatic review settings September 2, 2026 14:23

Copilot AI left a comment

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.

🟡 Changes recommended

The module’s conda path still pins ont-modkit=0.6.1 (so the fix is not applied for conda/non-container runs) and the new hard-coded ghcr.io/... container string can break Singularity/Apptainer usage without an explicit docker:// handling.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

modules/nf-core/modkit/pileup/main.nf:9

  • The module still declares a conda environment that pins ont-modkit=0.6.1 (modules/nf-core/modkit/pileup/environment.yml:7). That means runs using conda (or with containers disabled) will still hit the PacBio-read drop/empty --cpg behavior this PR is addressing.

To make the fix complete and avoid divergent behavior across execution modes, either update the conda environment to a version that includes the fix (if/when available) or consider removing/guarding conda support for this module and documenting that containers are required for the PacBio fix.

    conda "${moduleDir}/environment.yml"
    // Patched modkit 0.6.4 (ljwharbers/modkit@697de7b, nanoporetech/modkit#720): stock 0.4.3-0.6.4
    // drops 32-65 % of reads from recent PacBio HiFi BAMs whose 5mC+5hmC probabilities sum above 1
    // (nanoporetech/modkit#612). Return to the nf-core biocontainer once a release includes the fix.
    container 'ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-697de7b'
  • Files reviewed: 4/4 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread modules/nf-core/modkit/pileup/main.nf Outdated
Comment thread CHANGELOG.md Outdated
ljwharbers and others added 2 commits September 3, 2026 13:22
…d modkit_phased options

MODKIT_PILEUP ran with no arguments, so it emitted every modification code in
every sequence context: 30-45 GB bedMethyl per sample on full-size runs.
params.modkit_args now feeds ext.args and defaults to 5mC at CpG sites.

params.modkit_phased adds --phased and switches the pileup input from the
unphased merged BAM to PHASING_HAPLOTYPING.out.tumor_normal_hapbams_ch, the
Longphase-haplotagged BAM (HP tag) that nothing consumed until now. The
MODKIT_PILEUP call moves below the phasing subworkflow so it can pick either
input; meta.id and meta.type are present on both channels. modkit writes
<prefix>_hp1/_hp2/_combined.bed.gz into the output directory and the nf-core
module already moves those out, so no module change is needed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 3, 2026 11:22
@ljwharbers ljwharbers changed the title fix(modkit): run a patched modkit 0.6.4 that keeps PacBio reads with 5mC+5hmC > 1 fix(modkit): patched modkit 0.6.4 for PacBio 5mC+5hmC reads, 5mC-CpG pileup defaults and --modkit_phased option Sep 3, 2026

Copilot AI left a comment

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.

🟡 Changes recommended

The modkit execution path is inconsistent across profiles (conda still pins 0.6.1) and the updated user-facing docs/schema contain statements that conflict with the patched-modkit behavior described in this PR.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

modules/nf-core/modkit/pileup/main.nf:9

  • MODKIT_PILEUP now hard-codes a patched modkit 0.6.4 container, but the process still declares a conda env via environment.yml, which currently pins ont-modkit=0.6.1. That means runs using conda (or where container use is disabled) will silently fall back to the unfixed version and still drop affected PacBio reads; it also makes the module's reported version dependent on execution profile.
    conda "${moduleDir}/environment.yml"
    // Patched modkit 0.6.4 (ljwharbers/modkit@697de7b, nanoporetech/modkit#720): stock 0.4.3-0.6.4
    // drops 32-65 % of reads from recent PacBio HiFi BAMs whose 5mC+5hmC probabilities sum above 1
    // (nanoporetech/modkit#612). Return to the nf-core biocontainer once a release includes the fix.
    container 'ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-697de7b'
  • Files reviewed: 10/10 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread nextflow.config
Comment thread docs/usage.md Outdated
Comment thread nextflow_schema.json Outdated
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 3, 2026 12:51

Copilot AI left a comment

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.

🔵 Needs a closer look

The MODKIT_PILEUP container change may break Singularity/Apptainer usage because it no longer follows the repo’s established container-selection pattern for non-OCI Singularity runs.

Review details

Suppressed comments (1)

modules/nf-core/modkit/pileup/main.nf:7

  • MODKIT_PILEUP now hard-codes a GHCR container tag without a docker:// prefix or any Singularity/Apptainer handling. In this codebase most modules avoid relying on OCI auto-pull in the singularity profile (e.g. by using https://depot.galaxyproject.org/singularity/...), so this change risks breaking -profile singularity runs if the environment expects SIF/URL images rather than pulling from a Docker registry.
    conda "${moduleDir}/environment.yml"
    // Patched modkit 0.6.4 (nanoporetech/modkit#720) that keeps PacBio reads with 5mC+5hmC > 1; revert to the biocontainer once released
    container 'ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-697de7b'
  • Files reviewed: 10/10 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

)

Full-size reruns showed that modkit's general pileup workers, used whenever a
BAM carries opposite-strand modification calls such as PacBio 6mA, ignore the
HP partition (empty _hp1/_hp2 files) and still emit h rows under
--modified-bases 5mC. ONT output is as expected.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 4, 2026 09:20
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

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.

🟡 Changes recommended

The modkit container reference is likely to break Singularity/Apptainer runs without explicit OCI pull handling, and the usage docs section header is now misleading.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

docs/usage.md:138

  • This section is titled "Skipping options", but it now includes --modkit_args and --modkit_phased, which are not skip flags. This makes the docs misleading when scanning for skip-related parameters.
  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread modules/nf-core/modkit/pileup/main.nf Outdated
Copilot AI review requested due to automatic review settings September 4, 2026 09:24

Copilot AI left a comment

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.

🔵 Needs a closer look

The Modkit module change can cause profile-dependent behavior (conda env still pins 0.6.1) and needs small config/module adjustments to avoid inconsistent phased argument handling and container resolution issues.

Review details

Suppressed comments (3)

Previously missed (1) — in code that hasn't changed since the last review.

conf/modules.config:334

  • modkit_args is described as “additional arguments”, but --phased is also appended automatically when modkit_phased is true and the workflow switches inputs based on that boolean. If a user includes --phased inside modkit_args, it can (a) get duplicated and/or (b) produce confusing behavior if modkit_phased is false (phased args on unphased BAM). Stripping --phased from modkit_args here prevents that inconsistency and reserves phasing control for modkit_phased.

modules/nf-core/modkit/pileup/main.nf:7

  • MODKIT_PILEUP now hardcodes a patched 0.6.4 container, but the module still defines a conda env (environment.yml) that pins ont-modkit=0.6.1. Running with -profile conda/mamba would therefore execute an older modkit and miss the PacBio fixes (and the version in the module test snapshots). Consider updating the conda env to match the intended version/behavior or explicitly documenting/disabling conda for this module so execution profiles don’t silently diverge.
    conda "${moduleDir}/environment.yml"
    // Patched modkit 0.6.4 (nanoporetech/modkit#720) that keeps PacBio reads with 5mC+5hmC > 1; revert to the biocontainer once released
    container 'ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-697de7b'

modules/nf-core/modkit/pileup/main.nf:7

  • The module’s container directive no longer follows the repo’s standard engine-aware pattern, and for Singularity/Apptainer it may be safer to use an explicit docker:// reference (many environments rely on OCI pulls). Using an engine-conditional container string keeps behavior consistent with other modules and reduces profile-specific container resolution issues.
    // Patched modkit 0.6.4 (nanoporetech/modkit#720) that keeps PacBio reads with 5mC+5hmC > 1; revert to the biocontainer once released
    container 'ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-697de7b'
  • Files reviewed: 10/10 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

… on PacBio)

The new image includes the fix for modkit's general pileup workers, which
are used for PacBio BAMs with 6mA calls: `--phased` now fills `_hp1`/`_hp2`
and `--modified-bases 5mC` no longer emits an `h` row next to every `m`
row. The "Known limitation" note for `--modkit_phased` is therefore removed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 4, 2026 10:07
Resolves the CHANGELOG and docs/usage.md conflicts from the nf-core template
4.1.0 merge (#183): kept both sides' changelog entries, and re-inserted the
--modkit_args / --modkit_phased rows into dev's reflowed skip-options table.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 8, 2026 13:55

Copilot AI left a comment

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.

🟡 Changes recommended

The MODKIT_PILEUP container selection should respect task.ext.singularity_pull_docker_container (and the changelog should reflect the actual Singularity/Apptainer image URI) to avoid breaking established container-pull behavior and to keep documentation accurate.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

modules/nf-core/modkit/pileup/main.nf:9

  • The MODKIT_PILEUP container selection ignores task.ext.singularity_pull_docker_container. In this repo other modules (e.g. MOSDEPTH) use that flag to allow Singularity/Apptainer to pull the OCI image instead of requiring a native SIF/ORAS source; as written, users who set the flag will still be forced onto the ORAS SIF image, which can break environments without ORAS support.
    // Patched modkit 0.6.4 (nanoporetech/modkit#720) that keeps PacBio reads with 5mC+5hmC > 1 and honours --phased/--modified-bases in the general workers; revert to the biocontainer once released
    container "${workflow.containerEngine == 'singularity' || workflow.containerEngine == 'apptainer'
        ? 'oras://ghcr.io/ljwharbers/modkit-sif:0.6.4-pacbiofix-6e0afa2'
        : 'ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-6e0afa2'}"
  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread CHANGELOG.md Outdated
@ljwharbers
ljwharbers marked this pull request as ready for review September 8, 2026 15:48
Resolves CHANGELOG.md (keep #190 and #188 Added entries) and
docs/usage.md (skipping-options table gains --skip_signatures from dev
next to the --modkit_args / --modkit_phased rows from this branch).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 9, 2026 10:36

Copilot AI left a comment

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.

🟡 Changes recommended

The MODKIT_PILEUP container selection deviates from established container-handling conventions (not honoring task.ext.singularity_pull_docker_container), which can cause avoidable execution/configuration issues for Singularity/Apptainer users.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

modules/nf-core/modkit/pileup/main.nf:9

  • The MODKIT_PILEUP container selection no longer follows the repository’s standard pattern of honoring task.ext.singularity_pull_docker_container, which can prevent users running -profile singularity/apptainer from opting to pull the OCI image (and keeps this module inconsistent with other modules’ container handling).
    // Patched modkit 0.6.4 (nanoporetech/modkit#720) that keeps PacBio reads with 5mC+5hmC > 1 and honours --phased/--modified-bases in the general workers; revert to the biocontainer once released
    container "${workflow.containerEngine == 'singularity' || workflow.containerEngine == 'apptainer'
        ? 'oras://ghcr.io/ljwharbers/modkit-sif:0.6.4-pacbiofix-6e0afa2'
        : 'ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-6e0afa2'}"
  • Files reviewed: 10/10 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread workflows/lrsomatic.nf
Comment thread docs/usage.md
Comment thread docs/usage.md Outdated
| `--skip_m6a` | A boolean to skip `fibertools_m6a`, used if you have m6a calls but would still like nucleosome positions for PacBio data (ONT data is required to have m6a calls). Default = `false` |
| `--skip_nanoplot` | A boolean to skip NanoPlot QC on aligned and unaligned BAM files. Default = `false` |
| `--skip_normalfiber` | A boolean to skip fibertools processing for the normal sample. Default = `false` |
| `--skip_modcall` | A boolean to skip modkit methylation calling. Default = `false` |

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.

Adjust --skip_modcall so it's clearer to what it points (modified calls being used in phasing) instead of modkit methylation calling. It's confusing with skip-modkit what is what

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.

Reworded in 613dfdd, in both docs/usage.md and nextflow_schema.json: "Skip Longphase modcall, the 5mC base-modification calling whose VCF is used as extra evidence during phasing. Unrelated to the modkit pileup (see --skip_modkit)."

@AmberVerhasselt

Copy link
Copy Markdown
Contributor

Reviewed assisted by Claude.

The container fix itself looks right, and the size problem it solves is real. Three things I'd want addressed before merge, plus a few smaller ones.

1. -profile conda silently reintroduces the bug this PR fixes

modules/nf-core/modkit/pileup/environment.yml is still ont-modkit=0.6.1 while the container moves to the patched 0.6.4. Under conda you get exactly the behaviour being fixed — PacBio reads with 5mC+5hmC > 1 dropped, empty --cpg pileups, --phased ignored in the general workers so _hp1/_hp2 come out empty — and a plausible-looking bedMethyl file still appears, so it fails quietly. Conda is in the nf-test matrix for PRs into main.

SIGPROFILER_ASSIGNMENT (#190) hit the same situation and dropped the conda directive with a comment explaining why. Suggest doing the same here, or documenting the limitation in docs/usage.md if the directive has to stay.

2. The new default changes output content for existing users

--cpg --modified-bases 5mC is the right call for 30–45 GB per sample, but it means 5hmC (ONT) and 6mA disappear from the bedMethyl for anyone who never sets modkit_args. Given the pipeline treats m6A as a first-class signal (meta.fiber, fibertools predictm6a, --skip_m6a), fiber-seq samples lose it from the modkit output entirely.

Two small asks:

  • Split the changelog entry — container fix under Fixed, new pileup defaults under Changed, with an explicit note that reruns produce different bedMethyl content and that --modkit_args '' restores the old behaviour.
  • nextflow_schema.json and docs/usage.md both describe modkit_args as "additional" arguments, but it replaces the default. Someone adding --combine-strands silently loses --cpg. Worth rewording, or splitting into a base + extra-args pair.

Optionally, making the default conditional on platform / meta.fiber in conf/modules.config would avoid the fiber-seq case altogether.

3. Nothing exercises either change

conf/test.config sets skip_modkit = true, and nf-test.config ignores modules/nf-core/**/tests/* — so neither the container swap nor the new --modkit_phased wiring is covered by any test.

The 0.6.10.6.4 update in modules/nf-core/modkit/pileup/tests/main.nf.test.snap can't have come from a run: the test supplies input[0..2] while the patched module declares four input channels (the fasta/fai split, which predates this PR), so it can't execute. Either fix the test (input[3] = [[:],[]], split fasta/fai) so the snapshot asserts something, or leave the snapshot alone. A pipeline-level nf-test with skip_modkit = false and modkit_phased = true on the smallest fixture would cover the new path.

Smaller points

  • The container ternary drops !task.ext.singularity_pull_docker_container, which both the nf-core default and SIGPROFILER_ASSIGNMENT keep. That's the escape hatch for sites where an oras:// pull is blocked by a proxy — cheap to restore.
  • .github/workflows/download_pipeline.yml runs nf-core pipelines download --container-system singularity on PRs into main. Worth confirming it resolves oras://ghcr.io/... before cutting the release rather than during it. (Add mutational signature analysis (SigProfilerMatrixGenerator + SigProfilerAssignment, CHM13-aware) #190 introduced the same pattern, so if that has already passed a dev→main PR, this is settled.)
  • Provenance: a personal ghcr.io/ljwharbers namespace is a single point of failure for a published pipeline — an IntGenomicsLab-owned package would outlive any one account. Separately, modkit ships under ONT's public licence, which restricts use to ONT-generated data; redistributing a patched build whose purpose is PacBio support is probably worth a look before release.
  • With --modkit_phased, the pileup now depends on LONGPHASE_HAPLOTAG. Any sample dropped by the joins in subworkflows/local/phasing_haplotyping.nf gets no methylation output at all, where today it would still get one. A sentence in docs/usage.md would cover it.
  • docs/output.md promises sample_hp1/_hp2/_combined.bed.gz — worth confirming against a real run that the patched build names them that way (stock modkit uses _1/_2), and mentioning the untagged-reads file if one is produced. The publishDir glob is *.bed.gz so whatever appears is published; only the docs can be wrong here.

Checked and fine

Both ghcr packages are public and pull anonymously (the -sif tag is a genuine 42 MB SIF layer, so the oras:// URI is well formed); nothing in the pipeline consumes MODKIT_PILEUP.out, so the phased file names break no downstream process; schema defaults match nextflow.config; and moving the MODKIT_PILEUP call below PHASING_HAPLOTYPING doesn't delay it in unphased mode, since Nextflow is dataflow rather than statement-ordered.

…#188)

- Restore the `!task.ext.singularity_pull_docker_container` escape hatch in the
  MODKIT_PILEUP container ternary (nf-core default and SIGPROFILER_ASSIGNMENT keep
  it), so sites where an oras:// pull is blocked can fall back to the Docker image.
  Module patch refreshed to match; the module comment now names the fork source.
- Split the changelog: the container fix stays under Fixed and names both image
  URIs; the new `--cpg --modified-bases 5mC` default moves to Changed, with a note
  that reruns produce different bedMethyl content and how to restore the old output.
- `modkit_args` docs/schema now say the value replaces the default rather than
  extending it. `--modkit_args ''` (and a bare `--modkit_args`) reach the config as
  the flag value `true`, which would have been passed to modkit verbatim; the
  ext.args closure now treats that as "no arguments" so the documented escape works.
- `skip_modcall` description clarified: it skips Longphase modcall (phasing
  evidence), not the modkit pileup.
- `modkit_phased` docs note the dependency on small-variant calling, phasing and
  haplotagging; `modkit_args`/`modkit_phased` moved out of the "Skipping options"
  table into a "Modkit options" section; output docs state there is no separate
  file for untagged reads.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 14, 2026 10:17
@ljwharbers

Copy link
Copy Markdown
Collaborator Author

Follow-up on the smaller points, in 613dfdd:

  • singularity_pull_docker_container escape hatch: restored, the ternary now has the same shape as SIGPROFILER_ASSIGNMENT. nextflow inspect -profile test,singularity resolves oras://ghcr.io/ljwharbers/modkit-sif:0.6.4-pacbiofix-6e0afa2 by default and ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-6e0afa2 with ext.singularity_pull_docker_container = true. Module patch refreshed to match.
  • download_pipeline.yml: it only runs on PRs into main and on manual dispatch, and Add mutational signature analysis (SigProfilerMatrixGenerator + SigProfilerAssignment, CHM13-aware) #190 has not been through a dev→main PR yet, so the oras:// pattern is untested there. nf-core tools 4.1.0 (the version pinned in .nf-core.yml) handles it explicitly in pipelines download (singularity.py: address = container if container.startswith("oras://") else f"docker://{container}"). I dispatched the workflow against this branch to settle it: https://github.com/IntGenomicsLab/lrsomatic/actions/runs/34832522203. For context, that workflow has been red since 2026-05-28 at the "Install dependencies" step (pip install of the pinned nf-core version), independent of any container.
  • Provenance / licence: modkit ships under the Oxford Nanopore Technologies PLC. Public License 1.0. It grants use, modification and distribution "either on an unmodified basis, with Modifications, or as part of a Larger Work" solely for Research Purposes (§2.1), and requires an executable form to come with a pointer to its source (§3.2). It does not restrict use to ONT-generated data. The fork branch is public and linked from the module comment and the changelog, so the distribution terms are met; the research-only restriction applies to pipeline users exactly as it already did with the stock biocontainer. Moving the packages to an IntGenomicsLab namespace is a separate org decision, happy to do that before the release if we want it.
  • Phased pileup depends on haplotagging: documented in the modkit_phased schema description and in docs/usage.md.
  • File names: confirmed on the real phased run (three samples): exactly <id>_hp1.bed.gz, <id>_hp2.bed.gz and <id>_combined.bed.gz, nothing else. There is no untagged-reads file with --phased (that is --partition-tag behaviour); untagged reads only contribute to _combined. docs/output.md now says so.

The two small asks under point 2:

  • Changelog split: the container fix stays under Fixed and now names both image URIs; the new default is under Changed with a note that reruns give different bedMethyl content and how to restore the old output.
  • modkit_args: schema and usage docs now say the value replaces the default, with an example of adding a flag. While checking the escape I found that --modkit_args '' (and a bare --modkit_args) reach the config as the flag value true, which the old closure would have passed to modkit verbatim. conf/modules.config now treats that as "no arguments"; verified with a stub process: default → --cpg --modified-bases 5mC, --modkit_args '' → empty, --modkit_args '' --modkit_phased--phased.

Also moved modkit_args/modkit_phased out of the "Skipping options" table into a "Modkit options" section, and reworded --skip_modcall per the inline comment.

Copilot AI left a comment

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.

🟡 Changes recommended

Unresolved Conda compatibility, arm64 image support, and CI coverage issues remain.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

modules/nf-core/modkit/pileup/main.nf:9

  • This process still declares conda "${moduleDir}/environment.yml", whose environment pins stock ont-modkit=0.6.1 (modules/nf-core/modkit/pileup/environment.yml:7). With the repository's conda/mamba profiles, Nextflow therefore uses that binary instead of this patched image, so the PacBio conflict fix and the phased/general-worker fixes are absent (and the updated module snapshot will report 0.6.1). Please provide a patched Conda environment or make this process explicitly image-only and document the supported profile.

workflows/lrsomatic.nf:671

  • The pipeline nf-tests all use conf/test.config, which sets skip_modkit = true, so neither this unphased input selection nor the new modkit_phased haplotagged-channel path is exercised in CI. A regression in this conditional routing could therefore leave the full pipeline suite green; please add a lightweight preview/assertion or fixture covering both parameter values.
        ch_modkit_input = params.modkit_phased
            ? PHASING_HAPLOTYPING.out.tumor_normal_hapbams_ch
            : ch_index_minimap
        // ch_modkit_input: [meta, bam, bai]  -- BAM to pile up; meta.type selects the publish directory
        MODKIT_PILEUP(ch_modkit_input, ch_fasta, ch_fai, [[:],[]])
  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread modules/nf-core/modkit/pileup/main.nf
Resolves the CHANGELOG conflict by keeping both the #188 Fixed entry and the #181 entries.
Copilot AI review requested due to automatic review settings September 14, 2026 10:37

Copilot AI left a comment

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.

🟡 Changes recommended

Container compatibility and workflow/argument test coverage issues remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (3)

conf/modules.config:338

  • This new parameter-to-ext.args composition is not covered by the current tests: conf/test.config skips modkit, while the module tests set params.module_args directly and bypass params.modkit_args. Add assertions for the default, empty, and phased combinations so the documented CLI behavior is verified in CI.
        ext.args = {
                [
                    // Nextflow turns `--modkit_args ''` (and a bare `--modkit_args`) into the flag value `true`; treat that as "no arguments"
                    (params.modkit_args == null || params.modkit_args in [true, 'true']) ? '' : params.modkit_args,
                    params.modkit_phased ? '--phased' : ''
                ].join(' ').trim()

modules/nf-core/modkit/pileup/main.nf:9

  • The referenced container workflow publishes only linux/amd64, while this repository exposes an arm64 profile. That profile will select this tag without a native arm64 image/SIF, so MODKIT_PILEUP cannot run natively on arm64. Add an arm64 build/tag or explicitly guard and document this process as unsupported on arm64.
        ? 'oras://ghcr.io/ljwharbers/modkit-sif:0.6.4-pacbiofix-6e0afa2'
        : 'ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-6e0afa2'}"

workflows/lrsomatic.nf:673

  • The pipeline test profile sets skip_modkit=true, so CI never exercises this new channel selection, especially the haplotagged [meta, bam, bai] input when modkit_phased is enabled. Add a small workflow test/stub or another automated assertion for both phased modes; otherwise a channel-shape regression here can pass the existing pipeline tests.
        ch_modkit_input = params.modkit_phased
            ? PHASING_HAPLOTYPING.out.tumor_normal_hapbams_ch
            : ch_index_minimap
        // ch_modkit_input: [meta, bam, bai]  -- BAM to pile up; meta.type selects the publish directory
        MODKIT_PILEUP(ch_modkit_input, ch_fasta, ch_fai, [[:],[]])
  • Files reviewed: 10/10 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread modules/nf-core/modkit/pileup/main.nf
Comment thread modules/nf-core/modkit/pileup/main.nf
@ljwharbers

Copy link
Copy Markdown
Collaborator Author

Result of the download_pipeline dispatch on this branch (https://github.com/IntGenomicsLab/lrsomatic/actions/runs/34832522203):

  • nf-core pipelines download --container-system singularity succeeded, including the oras:// images: ghcr.io-ljwharbers-modkit-sif-0.6.4-pacbiofix-6e0afa2.img and ghcr.io-ljwharbers-sigprofiler-sif-1.3.6-chm13-28a9ce8.img both landed in the cache (30 containers found via nextflow inspect). So the oras:// question is settled: nf-core tools 4.1.0 resolves it.

  • The job then went red in the two "Run the downloaded pipeline" steps for reasons unrelated to this PR:

    • -stub: CRAMINO_PRE stub fails with Missing output file(s) *.arrow (the stub only touches the .txt). Pre-existing stub bug in the cramino module.
    • real run: PREPARE_REFERENCE_FILES:WGET (hifi) exit status 4 after ~47 min, the known HKU Clair3 model download flake.

    Neither step ran MODKIT_PILEUP (skip_modkit = true in the test profile). Worth fixing the cramino stub separately so this workflow can go green before the release.

Also merged origin/dev into the branch (c5abae3) to resolve the CHANGELOG conflict from #181; the PR is mergeable again.

@AmberVerhasselt

Copy link
Copy Markdown
Contributor

Thanks — the smaller points all look right, and the --modkit_argstrue catch in conf/modules.config is a good find. I tested the new --modkit_args '' escape: it doesn't work.

The documented --modkit_args '' escape aborts the run

Your premise is correct, but the guard in conf/modules.config never runs: validateParameters() sees the boolean first and kills the pipeline.

Minimal repro — the modkit_options group lifted verbatim from this PR's nextflow_schema.json, the same plugins { id 'nf-schema@2.5.1' } and validation {} block as nextflow.config, and the ext.args closure body from 613dfdd. Nextflow 25.10.4 (also reproduced on the same launcher without a pinned NXF_VER):

invocation params.modkit_args result
(default) String --cpg --modified-bases 5mC ext.args = --cpg --modified-bases 5mC
--modkit_args '' Boolean true run aborts
--modkit_args (bare) Boolean true run aborts
--modkit_args='' String `` ext.args = (empty)
--modkit_args ' ' String `` ext.args = (empty)
-params-file with "modkit_args": "" String `` ext.args = (empty)
--modkit_args '' --validate_params false Boolean true ✅ guard converts it to empty

The failure:

ERROR ~ Validation of pipeline parameters failed!
The following invalid input values have been detected:

* --modkit_args (true): Value is [boolean] but should be [string]

So the escape hatch now documented in docs/usage.md, nextflow_schema.json and the changelog fails from the CLI in the form it's written, and the in [true, 'true'] guard is only reachable with --validate_params false.

Two forms do work and are worth documenting instead: --modkit_args='' (the equals form keeps it a string) or --modkit_args ' ' — Nextflow trims the space to an empty string, and .trim() in the closure makes it a no-op either way. A -params-file entry works too. Keeping the boolean guard is still sensible as a backstop.

…rking --modkit_args escape (#188)

Review follow-up for PR #188.

- MODKIT_PILEUP: drop the conda directive and stop with an error under
  -profile conda/mamba (deepvariant/sigprofiler pattern). environment.yml
  would install stock ont-modkit 0.6.1, which silently reintroduces the
  PacBio read drop this PR fixes. Verified: the module test under
  -profile conda fails with the new message.
- modules/nf-core/modkit/pileup/tests: the test passed three inputs to a
  four-input patched module (fasta/fai split), so it could not run and the
  0.6.1 -> 0.6.4 snapshot edit had no run behind it. Inputs fixed for all
  ten cases; snapshot regenerated from a real run of the patched image on
  Mindwell (10/10 pass, versions 0.6.4, bedMethyl md5s follow the binary).
  Module patch refreshed (a trailing newline was added to the snapshot so
  the last hunk reverse-applies).
- --modkit_args '' does not work from the CLI: Nextflow turns it into
  `true`, which nf-schema rejects as a boolean on Nextflow 25.10.4 and which
  arrives as the string 'true' on Nextflow 26 (verified with -preview on
  both). Docs, schema and changelog now say --modkit_args='' or a params
  file entry; the modules.config guard stays as a backstop.
- docs/usage.md and CHANGELOG.md: the image is linux/amd64 only and conda
  and the arm64 profile are unsupported for this step (--skip_modkit);
  N_other note copied from the schema into the usage table.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 14, 2026 12:34
@ljwharbers

Copy link
Copy Markdown
Collaborator Author

Thanks, confirmed and fixed in 272d1f8, together with the two points from this morning that were still open.

--modkit_args '': reproduced with -preview. On Nextflow 25.10.4 the value arrives as the Boolean true and validation aborts exactly as you show; on Nextflow 26.04 the same flag arrives as the string 'true', passes type: string, and only the conf/modules.config backstop turns it into no arguments (that is where my stub-process check ran, hence the wrong conclusion). --modkit_args='' passes on both versions with an empty value, so docs/usage.md, nextflow_schema.json and the changelog now document the = form (or an empty modkit_args entry in a params file) and say why the quoted form fails; the guard stays as a backstop with a corrected comment.

Conda (point 1): the module now drops the conda directive and stops in the script block under -profile conda/mamba with MODKIT_PILEUP does not support Conda ... Use Docker / Singularity / Apptainer, or --skip_modkit, the deepvariant/sigprofiler pattern. Verified by running the module test with --profile conda: all cases fail with that message. docs/usage.md and the changelog say conda and the arm64 profile (the image is linux/amd64 only) are unsupported for this step.

Module test (point 3): you were right, the test could not have run. All ten cases now pass the four-channel inputs ([meta, fasta], [meta, fai], bed as input[3]), and the snapshot was re-recorded from a real run of the patched image on Mindwell (Apptainer, 10/10 pass): versions read 0.6.4 and the bedMethyl md5s changed with the binary (test.bed.gz f973de34 -> 1ec20749, the phased _hp1/_hp2/_combined files likewise; the stub cases keep the empty-file md5). The module patch was refreshed and nf-core modules lint modkit/pileup is back to its three pre-existing findings (registry prefix, oras:// scheme, meta.yml inputs). The pipeline test profile still skips modkit, since none of the pipeline test BAMs carry MM/ML tags.

Fiber-seq default (your optional point): left as is for now. The m6A signal for fiber-seq samples comes from the fibertools steps, and the pileup default is a size/scope choice that --modkit_args can widen per run; a platform- or meta.fiber-aware default is a reasonable follow-up if we want the bedMethyl to carry m6A as well.

Copilot AI left a comment

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.

🟡 Changes recommended

The Conda test guard blocks the required module-test matrix, and regression coverage plus container documentation reconciliation remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (2)

conf/modules.config:339

  • This new parameter wiring is not exercised by the pipeline tests: conf/test.config:60 sets skip_modkit = true, and the module tests replace ext.args with params.module_args in modules/nf-core/modkit/pileup/tests/nextflow.config, so neither the default/empty modkit_args handling nor the modkit_phased channel selection is verified. Please add a stub or preview-level regression test covering the default, custom/empty arguments, and phased input/output path.
        ext.args = {
                [
                    // Nextflow turns `--modkit_args ''` (and a bare `--modkit_args`) into `true`: a boolean that nf-schema rejects on
                    // Nextflow 25, the string 'true' on Nextflow 26. The documented form is `--modkit_args=''`; this backstop treats `true` as "no arguments"
                    (params.modkit_args == null || params.modkit_args in [true, 'true']) ? '' : params.modkit_args,
                    params.modkit_phased ? '--phased' : ''
                ].join(' ').trim()

workflows/lrsomatic.nf:673

  • Could you add a pipeline-level stub/preview test for both values of modkit_phased (and the default/custom modkit_args)? The pipeline tests load conf/test.config with skip_modkit = true, while the module tests inject params.module_args directly, so neither this channel selection nor the conf/modules.config argument-building closure is exercised. A regression could therefore send the wrong BAM or omit/duplicate --phased while all current tests still pass.
        ch_modkit_input = params.modkit_phased
            ? PHASING_HAPLOTYPING.out.tumor_normal_hapbams_ch
            : ch_index_minimap
        // ch_modkit_input: [meta, bam, bai]  -- BAM to pile up; meta.type selects the publish directory
        MODKIT_PILEUP(ch_modkit_input, ch_fasta, ch_fai, [[:],[]])
  • Files reviewed: 11/11 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment on lines +27 to +29
// Exit if running this module with -profile conda / -profile mamba
if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) {
error "MODKIT_PILEUP does not support Conda: the PacBio fixes only exist in the patched container. Use Docker / Singularity / Apptainer, or --skip_modkit."
Comment on lines +8 to +10
container "${(workflow.containerEngine == 'singularity' || workflow.containerEngine == 'apptainer') && !task.ext.singularity_pull_docker_container
? 'oras://ghcr.io/ljwharbers/modkit-sif:0.6.4-pacbiofix-6e0afa2'
: 'ghcr.io/ljwharbers/modkit:0.6.4-pacbiofix-6e0afa2'}"
@AmberVerhasselt
AmberVerhasselt merged commit e5deb7c into dev Sep 14, 2026
9 checks passed
@AmberVerhasselt
AmberVerhasselt deleted the fix/modkit-pacbio-container branch September 14, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants