diff --git a/.github/actions/nf-test/action.yml b/.github/actions/nf-test/action.yml index bf44d96..8bf659f 100644 --- a/.github/actions/nf-test/action.yml +++ b/.github/actions/nf-test/action.yml @@ -54,6 +54,40 @@ runs: conda-solver: libmamba conda-remove-defaults: true + - name: Check if disk cleanup is needed + id: disk-cleanup-check + shell: bash + env: + NFT_WORKDIR: ${{ env.NFT_WORKDIR }} + run: | + nf-test test \ + --profile=+${{ inputs.profile }} \ + $(if [ -n "${{ inputs.tags }}" ]; then echo "--tag ${{ inputs.tags }}"; fi) \ + --ci \ + --changed-since HEAD^ \ + --verbose \ + --shard ${{ inputs.shard }}/${{ inputs.total_shards }} \ + --dry-run \ + &> nf-test.log + + if grep -q 'full - stub' nf-test.log; then + echo "cleanup=YES" >> $GITHUB_OUTPUT + else + echo "cleanup=NO" >> $GITHUB_OUTPUT + fi + + - name: Disk space cleanup + if: steps.disk-cleanup-check.outputs.cleanup == 'YES' + uses: jlumbroso/free-disk-space@v1.3.1 + with: + tool-cache: false + android: true + dotnet: false + haskell: false + large-packages: false + docker-images: false + swap-storage: false + - name: Run nf-test shell: bash env: diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 450da3a..c3890ea 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -11,11 +11,11 @@ jobs: test: runs-on: ubuntu-latest steps: - # PRs to the nf-core repo main/master branch are only ok if coming from the nf-core repo `dev` or any `patch` branches + # PRs to the nf-core repo main/master branch are only ok if coming from the nf-core repo `dev` or any `patch` or `fix` branches - name: Check PRs if: github.repository == 'Plant-Food-Research-Open/assemblyqc' run: | - { [[ ${{ github.event.pull_request.head.repo.full_name }} == Plant-Food-Research-Open/assemblyqc ]] && [[ $GITHUB_HEAD_REF == "dev" ]]; } || [[ $GITHUB_HEAD_REF == "patch" ]] + { [[ ${{ github.event.pull_request.head.repo.full_name }} == Plant-Food-Research-Open/assemblyqc ]] && [[ $GITHUB_HEAD_REF == "dev" ]]; } || [[ "${GITHUB_HEAD_REF%%/*}" == "patch" ]] || [[ "${GITHUB_HEAD_REF%%/*}" == "fix" ]] # If the above check failed, post a comment on the PR explaining the failure # NOTE - this doesn't currently work if the PR is coming from a fork, due to limitations in GitHub actions secrets diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index d43797d..e6e9bc2 100644 --- a/.github/workflows/linting_comment.yml +++ b/.github/workflows/linting_comment.yml @@ -21,7 +21,7 @@ jobs: run: echo "pr_number=$(cat linting-logs/PR_number.txt)" >> $GITHUB_OUTPUT - name: Post PR comment - uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2 + uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ steps.pr_number.outputs.pr_number }} diff --git a/.nf-core.yml b/.nf-core.yml index b12594c..dab1ae0 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -48,4 +48,4 @@ template: - igenomes - multiqc - fastqc - version: 3.0.0 + version: 3.0.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9832ebf..d650d6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v3.0.1 - [14-Oct-2025] + +### `Added` + +1. Added disk cleanup to nf-test GitHub CI action to avoid the runner running out of disk space for `full - stub` runs +2. Added hic.bam file speedup by skipping name sort. + +### `Fixed` + +1. Fixed an issue in Synteny workflow which caused a pipeline crash when Syri failed for one of the synteny combinations [#315](https://github.com/Plant-Food-Research-Open/assemblyqc/issues/315) +2. Fixed an issue which cause parameter validation to fail for `hic_map_combinations` when `hic` parameter was set to `null` [#317](https://github.com/Plant-Food-Research-Open/assemblyqc/issues/317) + +### `Dependencies` + +1. Nextflow!>=24.10.5 +2. nf-schema@2.4.2 + ## v3.0.0 - [22-Sep-2025] ### `Added` diff --git a/CITATION.cff b/CITATION.cff index 007244e..e8602fe 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -25,7 +25,7 @@ authors: - family-names: "Deng" given-names: "Cecilia" title: "AssemblyQC: A Nextflow pipeline for reproducible reporting of assembly quality" -version: 3.0.0 +version: 3.0.1 date-released: 2024-07-30 url: "https://github.com/Plant-Food-Research-Open/assemblyqc" doi: 10.1093/bioinformatics/btae477 diff --git a/conf/modules.config b/conf/modules.config index e5eb9d6..cce9020 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -358,7 +358,7 @@ process { withName: '.*:FQ2HIC:FASTQ_BWA_MEM_SAMBLASTER:BWA_MEM' { ext.prefix = { "${meta.id}.on.${meta.ref_id}.bwa.mem" } ext.args = '-5SP' - ext.args2 = '-n' + // ext.args2 = '-n' } withName: '.*:FQ2HIC:FASTQ_BWA_MEM_SAMBLASTER:SAMBLASTER' { diff --git a/docs/output.md b/docs/output.md index 52ee0aa..38febcb 100644 --- a/docs/output.md +++ b/docs/output.md @@ -183,7 +183,7 @@ Kraken 2 [assigns taxonomic labels](https://ccb.jhu.edu/software/kraken2/) to se - `*_1_fastqc.html/*_2_fastqc.html`: FastQC html report for the reads passed by FASTP. - `*_1_fastqc.zip/*_2_fastqc.zip`: FastQC stats for the reads passed by FASTP. - `hicqc` - - `*_qc_report.pdf`: HiC QC report for reads mapped to an assembly. + - `*_qc_report.pdf`: HiC QC report for 5% of the HiC reads mapped to an assembly. - `*.hic`: The HiC contact map stored as a multi-resolution `.hic` file. - `*.assembly`: Assembly file created when the `hic_assembly_mode` is `true` - `*.bed`: The bed file listing the names of the contigs on the `assembly` super-scaffold when `hic_assembly_mode` is `true` diff --git a/modules/local/samtools_subsample_sort.nf b/modules/local/samtools_subsample_sort.nf new file mode 100644 index 0000000..9e1d690 --- /dev/null +++ b/modules/local/samtools_subsample_sort.nf @@ -0,0 +1,48 @@ +process SAMTOOLS_SUBSAMPLE_SORT { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : + 'biocontainers/samtools:1.21--h50ea8bc_0' }" + + input: + tuple val(meta), path(bam) + val(sample_fraction) // Fraction of reads to sample (e.g., 0.05 for 5%) + + output: + tuple val(meta), path("*.subsampled.sorted.bam"), emit: bam + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def fraction = sample_fraction ?: 0.05 + + """ + # Subsample reads and sort by name in one go + # Format for -s is SEED.FRACTION (e.g., 42.05 for 5% with seed 42) + samtools view -@ ${task.cpus} -s ${fraction} -b ${bam} \\ + | samtools sort -n -@ ${task.cpus} ${args} -o ${prefix}.subsampled.sorted.bam - + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.subsampled.sorted.bam + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') + END_VERSIONS + """ +} diff --git a/nextflow.config b/nextflow.config index 7fee3d5..0b3d586 100644 --- a/nextflow.config +++ b/nextflow.config @@ -329,7 +329,7 @@ manifest { mainScript = 'main.nf' defaultBranch = 'main' nextflowVersion = '!>=24.10.5' - version = '3.0.0' + version = '3.0.1' doi = 'https://doi.org/10.1093/bioinformatics/btae477' } diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 62453cb..1c55c2e 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -21,8 +21,8 @@ { "@id": "./", "@type": "Dataset", - "creativeWorkStatus": "InProgress", - "datePublished": "2025-09-22T00:29:39+00:00", + "creativeWorkStatus": "Stable", + "datePublished": "2025-10-12T21:50:53+00:00", "description": "# plant-food-research-open/assemblyqc\n\n[![GitHub Actions CI Status](https://github.com/plant-food-research-open/assemblyqc/actions/workflows/nf-test.yml/badge.svg)](https://github.com/plant-food-research-open/assemblyqc/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/plant-food-research-open/assemblyqc/actions/workflows/linting.yml/badge.svg)](https://github.com/plant-food-research-open/assemblyqc/actions/workflows/linting.yml)\n[![Cite Article](http://img.shields.io/badge/DOI-10.1093/bioinformatics/btae477-1073c8?labelColor=000000)](https://doi.org/10.1093/bioinformatics/btae477)\n\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n\n[![run with conda \u274c](http://img.shields.io/badge/run%20with-conda%20\u274c-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/plant-food-research-open/assemblyqc)\n\n## Introduction\n\n**plant-food-research-open/assemblyqc** is a [Nextflow](https://www.nextflow.io/docs/latest/index.html) pipeline which evaluates assembly quality with multiple QC tools and presents the results in a unified html report. The tools are shown in the [Pipeline Flowchart](#pipeline-flowchart) and their references are listed in [CITATIONS.md](./CITATIONS.md). The pipeline includes skip flags to disable execution of various tools.\n\n## Pipeline Flowchart\n\n

\n\n- `Assembly`\n - [fa-lint](https://github.com/GallVp/fa-lint) + [SeqKit rmdup](https://github.com/shenwei356/seqkit): FASTA validation\n - [assemblathon_stats](https://github.com/PlantandFoodResearch/assemblathon2-analysis/blob/a93cba25d847434f7eadc04e63b58c567c46a56d/assemblathon_stats.pl), [gfastats](https://github.com/vgl-hub/gfastats): Assembly statistics\n - [NCBI FCS-adaptor](https://github.com/ncbi/fcs): Adaptor contamination pass/fail\n - [NCBI FCS-GX](https://github.com/ncbi/fcs): Foreign organism contamination pass/fail\n - [tidk](https://github.com/tolkit/telomeric-identifier): Telomere repeat identification\n - [BUSCO](https://gitlab.com/ezlab/busco): Gene-space completeness estimation\n - [LAI](https://github.com/oushujun/LTR_retriever/blob/master/LAI): Continuity of repetitive sequences\n - [Kraken 2](https://github.com/DerrickWood/kraken2), [Krona](https://github.com/marbl/Krona): Taxonomy classification\n - `Alignment and visualisation of HiC data`\n - [sra-tools](https://github.com/ncbi/sra-tools): HiC data download from SRA or use of local FASTQ files\n - [fastp](https://github.com/OpenGene/fastp), [FastQC](https://github.com/s-andrews/FastQC): Read QC and trimming\n - [SeqKit sort](https://github.com/shenwei356/seqkit): Alphanumeric sorting of FASTA by sequence ID\n - [HapHiC refsort](https://github.com/zengxiaofei/HapHiC): Reference-based sorting of FASTA\n - [bwa-mem](https://github.com/lh3/bwa): HiC read alignment\n - [samblaster](https://github.com/GregoryFaust/samblaster): Duplicate marking\n - [hic_qc](https://github.com/phasegenomics/hic_qc): HiC read and alignment statistics\n - [YaHS juicer pre](https://github.com/c-zhou/yahs): BAM to juicer conversion\n - [hictk load/zoomify](https://github.com/paulsengroup/hictk): `.hic` file creation\n - [juicebox.js](https://github.com/igvteam/juicebox.js): HiC contact map visualisation\n - `K-mer completeness, consensus quality and phasing assessment`\n - [sra-tools](https://github.com/ncbi/sra-tools): Assembly, maternal and paternal data download from SRA or use of local FASTQ files\n - [Merqury hapmers](https://github.com/marbl/merqury/blob/master/trio/hapmers.sh): Hapmer generation if parental data is available\n - [Merqury](https://github.com/marbl/merqury): Completeness, consensus quality and phasing assessment\n - `Synteny analysis`\n - [MUMmer](https://github.com/mummer4/mummer) \u2192 [Circos](http://circos.ca/documentation/) + [dotplot](https://plotly.com): One-to-all and all-to-all synteny analysis at the contig level\n - [Minimap2](https://github.com/lh3/minimap2) \u2192 [Syri](https://github.com/schneebergerlab/syri)/[Plotsr](https://github.com/schneebergerlab/plotsr): One-to-one synteny analysis at the chromosome level\n - `Mapback profile from alignment of long-read data, GC content and variant detection`\n - [Winnowmap](https://github.com/marbl/Winnowmap): Align long-read data\n - [paftools sam2paf](https://github.com/lh3/minimap2): Convert SAM to PAF\n - [T2T-Polish pafToCovClippedWig](https://github.com/arangrhie/T2T-Polish): Convert PAF to coverage Wig\n - [bedtools nuc](https://bedtools.readthedocs.io/en/latest/): Compute GC content\n - [Clair3](https://github.com/HKU-BAL/Clair3): Variant detection\n- `Annotation`\n - [GenomeTools gt gff3validator](https://genometools.org/tools/gt_gff3validator.html) + [FASTA/GFF correspondence](subworkflows/gallvp/gff3_gt_gff3_gff3validator_stat/main.nf): GFF3 validation\n - [GenomeTools gt stat](https://genometools.org/tools/gt_stat.html): Annotation statistics\n - [GffRead](https://github.com/gpertea/gffread), [BUSCO](https://gitlab.com/ezlab/busco): Gene-space completeness estimation in annotation proteins\n - [OrthoFinder](https://github.com/davidemms/OrthoFinder): Phylogenetic orthology inference for comparative genomics\n\n## Usage\n\nRefer to [usage](./docs/usage.md), [parameters](./docs/parameters.md) and [output](./docs/output.md) documents for details.\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nPrepare an `assemblysheet.csv` file with following columns representing target assemblies and associated meta-data.\n\n- `tag:` A unique tag which represents the target assembly throughout the pipeline and in the final report\n- `fasta:` FASTA file\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run plant-food-research-open/assemblyqc \\\n -revision \\\n -profile \\\n --input assemblysheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\n### Plant&Food Users\n\nDownload the pipeline to your `/workspace/$USER` folder. Change the parameters defined in the [pfr/params.json](./pfr/params.json) file. Submit the pipeline to SLURM for execution.\n\n```bash\nsbatch ./pfr_assemblyqc\n```\n\n## Credits\n\nplant-food-research-open/assemblyqc was originally written by Usman Rashid ([@gallvp](https://github.com/gallvp)) and Ken Smith ([@hzlnutspread](https://github.com/hzlnutspread)).\n\nRoss Crowhurst ([@rosscrowhurst](https://github.com/rosscrowhurst)), Chen Wu ([@christinawu2008](https://github.com/christinawu2008)) and Marcus Davy ([@mdavy86](https://github.com/mdavy86)) generously contributed their QC scripts.\n\nMahesh Binzer-Panchal ([@mahesh-panchal](https://github.com/mahesh-panchal)) and Simon Pearce ([@SPPearce](https://github.com/SPPearce)) helped port the pipeline modules and sub-workflows to [nf-core](https://nf-co.re) schema.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- [Cecilia Deng](https://github.com/CeciliaDeng)\n- [Ignacio Carvajal](https://github.com/ignacio3437)\n- [Jason Shiller](https://github.com/jasonshiller)\n- [Sarah Bailey](https://github.com/SarahBailey1998)\n- [Susan Thomson](https://github.com/cflsjt)\n- [Ting-Hsuan Chen](https://github.com/ting-hsuan-chen)\n\nThe pipeline uses nf-core modules contributed by following authors:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\n## Citations\n\nIf you use plant-food-research-open/assemblyqc for your analysis, please cite it as:\n\n> **AssemblyQC: A Nextflow pipeline for reproducible reporting of assembly quality.**\n>\n> Usman Rashid, Chen Wu, Jason Shiller, Ken Smith, Ross Crowhurst, Marcus Davy, Ting-Hsuan Chen, Ignacio Carvajal, Sarah Bailey, Susan Thomson & Cecilia H Deng.\n>\n> _Bioinformatics_. 2024 July 30. doi: [10.1093/bioinformatics/btae477](https://doi.org/10.1093/bioinformatics/btae477).\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nThis pipeline uses code and infrastructure developed and maintained by the [nf-core](https://nf-co.re) community, reused here under the [MIT license](https://github.com/nf-core/tools/blob/main/LICENSE).\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { @@ -102,7 +102,7 @@ }, "mentions": [ { - "@id": "#6068a637-d0e8-4615-a5c9-68701748950b" + "@id": "#a2a83118-1b86-43f1-804f-730e839d2bc5" } ], "name": "plant-food-research-open/assemblyqc" @@ -131,14 +131,17 @@ ], "creator": [ { - "@id": "#usman@smme.edu.pk" + "@id": "#hrakws@aklppf31.pfr.co.nz" }, { - "@id": "#hrakws@aklppf31.pfr.co.nz" + "@id": "#usman@smme.edu.pk" } ], - "dateCreated": "", - "dateModified": "2025-09-22T12:29:39Z", + "dateCreated": [ + "", + "2025-09-24T09:25:59Z" + ], + "dateModified": "2025-10-13T10:50:53Z", "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", "keywords": [ "nf-core", @@ -149,10 +152,10 @@ ], "maintainer": [ { - "@id": "#usman@smme.edu.pk" + "@id": "#hrakws@aklppf31.pfr.co.nz" }, { - "@id": "#hrakws@aklppf31.pfr.co.nz" + "@id": "#usman@smme.edu.pk" } ], "name": [ @@ -166,10 +169,10 @@ }, "url": [ "https://github.com/plant-food-research-open/assemblyqc", - "https://nf-co.re/plant-food-research-open/assemblyqc/dev/" + "https://nf-co.re/plant-food-research-open/assemblyqc/3.0.1/" ], "version": [ - "3.0.0" + "3.0.1" ] }, { @@ -185,11 +188,11 @@ "version": "!>=24.10.5" }, { - "@id": "#6068a637-d0e8-4615-a5c9-68701748950b", + "@id": "#a2a83118-1b86-43f1-804f-730e839d2bc5", "@type": "TestSuite", "instance": [ { - "@id": "#233e21c6-dec3-4d79-95be-2c71b303aed2" + "@id": "#4723b4a1-7aaf-425a-80ac-00f54c0f4f20" } ], "mainEntity": { @@ -198,7 +201,7 @@ "name": "Test suite for plant-food-research-open/assemblyqc" }, { - "@id": "#233e21c6-dec3-4d79-95be-2c71b303aed2", + "@id": "#4723b4a1-7aaf-425a-80ac-00f54c0f4f20", "@type": "TestInstance", "name": "GitHub Actions workflow for testing plant-food-research-open/assemblyqc", "resource": "repos/plant-food-research-open/assemblyqc/actions/workflows/nf-test.yml", @@ -331,17 +334,17 @@ "name": "nf-core", "url": "https://nf-co.re/" }, - { - "@id": "#usman@smme.edu.pk", - "@type": "Person", - "email": "usman@smme.edu.pk", - "name": "Usman Rashid" - }, { "@id": "#hrakws@aklppf31.pfr.co.nz", "@type": "Person", "email": "hrakws@aklppf31.pfr.co.nz", "name": "Ken Smith" + }, + { + "@id": "#usman@smme.edu.pk", + "@type": "Person", + "email": "usman@smme.edu.pk", + "name": "Usman Rashid" } ] } \ No newline at end of file diff --git a/subworkflows/gallvp/fastq_bwa_mem_samblaster/tests/nextflow.config b/subworkflows/gallvp/fastq_bwa_mem_samblaster/tests/nextflow.config index 7583034..b796c80 100644 --- a/subworkflows/gallvp/fastq_bwa_mem_samblaster/tests/nextflow.config +++ b/subworkflows/gallvp/fastq_bwa_mem_samblaster/tests/nextflow.config @@ -2,7 +2,7 @@ process { withName: BWA_MEM { ext.prefix = { "${meta.id}.on.${meta.ref_id}.bwa.mem" } ext.args = '-5SP' - ext.args2 = '-n' + // ext.args2 = '-n' } withName: SAMBLASTER { diff --git a/subworkflows/local/fasta_synteny.nf b/subworkflows/local/fasta_synteny.nf index eee94f8..56c4181 100644 --- a/subworkflows/local/fasta_synteny.nf +++ b/subworkflows/local/fasta_synteny.nf @@ -341,30 +341,7 @@ workflow FASTA_SYNTENY { ] } | groupTuple - | map { meta, syri, fastas -> - def fasta_list = fastas.flatten() - def syri_tags = syri.collect { it.name.replace('syri.out', '').split(/\.on\./).toList() }.flatten().unique() - def proposed_order = plotsr_assembly_order ? plotsr_assembly_order.tokenize(' ') : syri_tags.sort(false) { it.toUpperCase() } - - def available_tags = [] - proposed_order.each { tag -> if ( tag in syri_tags ) available_tags << tag } - - def ordered_fa = [] - available_tags.each { tag -> ordered_fa << ( fasta_list.find { it.baseName == "${tag}.plotsr" } ) } - - def ordered_syri_tags = [] - available_tags.eachWithIndex { tag, index -> if ( index > 0 ) { ordered_syri_tags << "${tag}.on.${available_tags[index-1]}" } } - - def ordered_syri = [] - ordered_syri_tags.each { tag -> ordered_syri << ( syri.find { it.baseName == "${tag}syri" } ) } - - [ - meta, - ordered_syri, - ordered_fa, - "#file\tname\n" + ordered_fa.collect { it.baseName.replace('.plotsr', '') }.join('\n') - ] - } + | map { meta, syri, fastas -> packageSyriOutputsForPlotSR ( meta, syri, fastas, plotsr_assembly_order ) } PLOTSR( ch_plotsr_inputs.map { meta, syri, _fastas, _txt -> [ meta, syri ] }, @@ -430,3 +407,55 @@ def extractBundleTag(filePath) { error "Error: Failed to parse the sequence tag from file name: ${filePath.getName()}" } } + +def packageSyriOutputsForPlotSR(meta, syri, fastas, plotsr_assembly_order) { + def fasta_list = fastas.flatten() + + // Iteration 1: Find available Syri tags from Syri outputs and order Syri.out files by their tags alphabetically or + // in accordance with the order listed in `plotsr_assembly_order` + def syri_tags = syri.collect { it.name.replace('syri.out', '').split(/\.on\./).toList() }.flatten().unique() + def proposed_order = plotsr_assembly_order ? plotsr_assembly_order.tokenize(' ') : syri_tags.sort(false) { it.toUpperCase() } + + def available_tags = [] + proposed_order.each { tag -> if ( tag in syri_tags ) available_tags << tag } + + if ( proposed_order.size() != available_tags.size() ) { + log.warn ( + "Plotsr combinations involving ${proposed_order - available_tags} will be skipped" + + " as Syri failed to find synteny for their combinations." + ) + } + + def ordered_syri_tags = [] + available_tags.eachWithIndex { tag, index -> if ( index > 0 ) { ordered_syri_tags << "${tag}.on.${available_tags[index-1]}" } } + + def ordered_syri = [] + ordered_syri_tags.each { tag -> ordered_syri << ( syri.find { it.baseName == "${tag}syri" } ) } + def first_null_tag_idx = ordered_syri.findIndexOf { it == null } + + // Remove all Syri files for combinations at and after the first null as Plotsr cannot handle skipped combinations + if ( first_null_tag_idx >= 0 ) { + ordered_syri = ordered_syri[0.. if ( tag in syri_tags ) available_tags << tag } + + def ordered_fa = [] + available_tags.each { tag -> ordered_fa << ( fasta_list.find { it.baseName == "${tag}.plotsr" } ) } + + [ + meta, + ordered_syri, + ordered_fa, + "#file\tname\n" + ordered_fa.collect { it.baseName.replace('.plotsr', '') }.join('\n') + ] +} diff --git a/subworkflows/local/fq2hic.nf b/subworkflows/local/fq2hic.nf index 145a648..5994b04 100644 --- a/subworkflows/local/fq2hic.nf +++ b/subworkflows/local/fq2hic.nf @@ -1,6 +1,7 @@ include { FASTQ_FASTQC_UMITOOLS_FASTP } from '../nf-core/fastq_fastqc_umitools_fastp/main' include { FASTQ_BWA_MEM_SAMBLASTER } from '../gallvp/fastq_bwa_mem_samblaster/main' +include { SAMTOOLS_SUBSAMPLE_SORT } from '../../modules/local/samtools_subsample_sort.nf' include { HICQC } from '../../modules/gallvp/hicqc' include { FASTA_SEQKIT_REFSORT } from '../gallvp/fasta_seqkit_refsort/main' @@ -52,7 +53,7 @@ workflow FQ2HIC { ch_versions = ch_versions.mix(FASTA_SEQKIT_REFSORT.out.versions) // SUBWORKFLOW: FASTQ_BWA_MEM_SAMBLASTER - val_sort_bam = true + val_sort_bam = false FASTQ_BWA_MEM_SAMBLASTER( ch_trim_reads, ch_sorted_ref.map { meta2, fa -> [ meta2, fa, [] ] }, @@ -62,8 +63,17 @@ workflow FQ2HIC { ch_bam = FASTQ_BWA_MEM_SAMBLASTER.out.bam ch_versions = ch_versions.mix(FASTQ_BWA_MEM_SAMBLASTER.out.versions) + // MODULE: SAMTOOLS_SUBSAMPLE_SORT + SAMTOOLS_SUBSAMPLE_SORT ( + ch_bam, + 0.05 // Sample 5% of reads + ) + + ch_subsampled_sorted_bam = SAMTOOLS_SUBSAMPLE_SORT.out.bam + ch_versions = ch_versions.mix(SAMTOOLS_SUBSAMPLE_SORT.out.versions) + // MODULE: HICQC - ch_bam_and_ref = ch_bam + ch_sub_bam_and_ref = ch_subsampled_sorted_bam | map { meta, bam -> [ meta.ref_id, meta, bam ] } | join( ch_sorted_ref.map { meta2, fa -> [ meta2.id, fa ] } @@ -72,12 +82,22 @@ workflow FQ2HIC { [ [ id: "${meta.id}.on.${meta.ref_id}", ref_id: meta.ref_id ], bam, fa ] } - HICQC ( ch_bam_and_ref.map { meta3, bam, _fa -> [ meta3, bam ] } ) + HICQC ( ch_sub_bam_and_ref.map { meta3, bam, _fa -> [ meta3, bam ] } ) ch_hicqc_pdf = HICQC.out.pdf ch_versions = ch_versions.mix(HICQC.out.versions) // SUBWORKFLOW: BAM_FASTA_YAHS_JUICER_PRE_HICTK_LOAD + + ch_bam_and_ref = ch_bam + | map { meta, bam -> [ meta.ref_id, meta, bam ] } + | join( + ch_sorted_ref.map { meta2, fa -> [ meta2.id, fa ] } + ) + | map { _ref_id, meta, bam, fa -> + [ [ id: "${meta.id}.on.${meta.ref_id}", ref_id: meta.ref_id ], bam, fa ] + } + BAM_FASTA_YAHS_JUICER_PRE_HICTK_LOAD ( ch_bam_and_ref.map { meta3, bam, _fa -> [ meta3, bam ] }, ch_sorted_ref, diff --git a/subworkflows/local/utils_nfcore_assemblyqc_pipeline/main.nf b/subworkflows/local/utils_nfcore_assemblyqc_pipeline/main.nf index 97feb4c..924a31b 100644 --- a/subworkflows/local/utils_nfcore_assemblyqc_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_assemblyqc_pipeline/main.nf @@ -77,7 +77,12 @@ workflow PIPELINE_INITIALISATION { ch_input_validated = ch_input | map { row -> row[0] } | collect - | map { tags -> validateInputTags( tags, params.hic_map_combinations ) } + | map { tags -> + validateInputTags( + tags, + params.hic ? params.hic_map_combinations : null + ) + } | combine ( ch_input.map { row -> [ row ] } ) | map { _result, row -> row } diff --git a/tests/hic/main.nf.test.snap b/tests/hic/main.nf.test.snap index 966c4ce..05188ac 100644 --- a/tests/hic/main.nf.test.snap +++ b/tests/hic/main.nf.test.snap @@ -63,7 +63,7 @@ "pigz": "2.3.4" }, "Workflow": { - "plant-food-research-open/assemblyqc": "v3.0.0" + "plant-food-research-open/assemblyqc": "v3.0.1" }, "YAHS_JUICERPRE": { "yahs": "1.2.2" @@ -169,7 +169,7 @@ "pigz": "2.3.4" }, "Workflow": { - "plant-food-research-open/assemblyqc": "v3.0.0" + "plant-food-research-open/assemblyqc": "v3.0.1" }, "YAHS_JUICERPRE": { "yahs": "1.2.2" diff --git a/tests/invalid/main.nf.test.snap b/tests/invalid/main.nf.test.snap index e67c83d..c13e9a3 100644 --- a/tests/invalid/main.nf.test.snap +++ b/tests/invalid/main.nf.test.snap @@ -35,7 +35,7 @@ "pigz": "2.3.4" }, "Workflow": { - "plant-food-research-open/assemblyqc": "v3.0.0" + "plant-food-research-open/assemblyqc": "v3.0.1" } }, "stable paths": [ diff --git a/tests/mapback/main.nf.test.snap b/tests/mapback/main.nf.test.snap index 72e7425..e84f286 100644 --- a/tests/mapback/main.nf.test.snap +++ b/tests/mapback/main.nf.test.snap @@ -51,7 +51,7 @@ "samtools": "1.16.1" }, "Workflow": { - "plant-food-research-open/assemblyqc": "v3.0.0" + "plant-food-research-open/assemblyqc": "v3.0.1" } }, "stable paths": [ diff --git a/tests/minimal/main.nf.test.snap b/tests/minimal/main.nf.test.snap index 89d0603..49c6cc8 100644 --- a/tests/minimal/main.nf.test.snap +++ b/tests/minimal/main.nf.test.snap @@ -35,7 +35,7 @@ "pigz": "2.3.4" }, "Workflow": { - "plant-food-research-open/assemblyqc": "v3.0.0" + "plant-food-research-open/assemblyqc": "v3.0.1" } }, "stable paths": [ diff --git a/tests/noltr/main.nf.test.snap b/tests/noltr/main.nf.test.snap index f05ed52..cf151f1 100644 --- a/tests/noltr/main.nf.test.snap +++ b/tests/noltr/main.nf.test.snap @@ -50,7 +50,7 @@ "seqkit": "v2.9.0" }, "Workflow": { - "plant-food-research-open/assemblyqc": "v3.0.0" + "plant-food-research-open/assemblyqc": "v3.0.1" } }, "stable paths": [ diff --git a/tests/orthofinder/main.nf.test.snap b/tests/orthofinder/main.nf.test.snap index 07d799d..83c8ef2 100644 --- a/tests/orthofinder/main.nf.test.snap +++ b/tests/orthofinder/main.nf.test.snap @@ -41,7 +41,7 @@ "pigz": "2.3.4" }, "Workflow": { - "plant-food-research-open/assemblyqc": "v3.0.0" + "plant-food-research-open/assemblyqc": "v3.0.1" } }, "stable paths": [ diff --git a/tests/stub/main.nf.test.snap b/tests/stub/main.nf.test.snap index 5be653f..e5aa4ab 100644 --- a/tests/stub/main.nf.test.snap +++ b/tests/stub/main.nf.test.snap @@ -228,7 +228,7 @@ "untar": 1.34 }, "Workflow": { - "plant-food-research-open/assemblyqc": "v3.0.0" + "plant-food-research-open/assemblyqc": "v3.0.1" }, "YAHS_JUICERPRE": { "yahs": "1.2.2" diff --git a/tests/synteny/packageSyriOutputsForPlotSR.nf.test b/tests/synteny/packageSyriOutputsForPlotSR.nf.test new file mode 100644 index 0000000..e2ffa55 --- /dev/null +++ b/tests/synteny/packageSyriOutputsForPlotSR.nf.test @@ -0,0 +1,130 @@ +nextflow_function { + + name "packageSyriOutputsForPlotSR" + script "../../subworkflows/local/fasta_synteny.nf" + function "packageSyriOutputsForPlotSR" + + test("FI1 - JAD - TT_2021a") { + when { + function { + """ + input[0] = [ id: 'plotsr' ] + input[1] = [ file('JAD.on.FI1syri.out') ] + input[2] = [ + [ file('JAD.plotsr.fasta'), file('FI1.plotsr.fasta') ] + ] + input[3] = 'FI1 JAD TT_2021a' + """ + } + } + + then { + assert function.success + assert function.result + assert snapshot ( + function.result[0], + function.result[1].collect { file(it).name }, + function.result[2].collect { file(it).name }, + function.result[3], + ).match() + } + } + + test("FI1 - JAD - TT_2021a - null") { + when { + function { + """ + input[0] = [ id: 'plotsr' ] + input[1] = [ file('JAD.on.FI1syri.out') ] + input[2] = [ + [ file('JAD.plotsr.fasta'), file('FI1.plotsr.fasta') ] + ] + input[3] = null + """ + } + } + + then { + assert function.success + assert function.result + assert snapshot ( + function.result[0], + function.result[1].collect { file(it).name }, + function.result[2].collect { file(it).name }, + function.result[3], + ).match() + } + } + + test("gddh13_v1p1 - FujiA - FujiB - PbDS - PcKFL") { + when { + function { + """ + input[0] = [ id: 'plotsr' ] + input[1] = [ + file('FujiA.on.gddh13_v1p1syri.out'), file('FujiB.on.FujiAsyri.out'), file('PcKFL.on.PbDSsyri.out') + ] + input[2] = [ + [ + file('FujiA.plotsr.fasta'), file('gddh13_v1p1.plotsr.fasta') + ], + [ + file('FujiB.plotsr.fasta'), file('FujiA.plotsr.fasta') + ], + [ + file('PcKFL.plotsr.fasta'), file('PbDS.plotsr.fasta') + ] + ] + input[3] = 'gddh13_v1p1 FujiA FujiB PbDS PcKFL' + """ + } + } + + then { + assert function.success + assert function.result + assert snapshot ( + function.result[0], + function.result[1].collect { file(it).name }, + function.result[2].collect { file(it).name }, + function.result[3], + ).match() + } + } + + test("gddh13_v1p1 - FujiA - FujiB - PbDS - PcKFL - null") { + when { + function { + """ + input[0] = [ id: 'plotsr' ] + input[1] = [ + file('FujiA.on.gddh13_v1p1syri.out'), file('FujiB.on.FujiAsyri.out'), file('PcKFL.on.PbDSsyri.out') + ] + input[2] = [ + [ + file('FujiA.plotsr.fasta'), file('gddh13_v1p1.plotsr.fasta') + ], + [ + file('FujiB.plotsr.fasta'), file('FujiA.plotsr.fasta') + ], + [ + file('PcKFL.plotsr.fasta'), file('PbDS.plotsr.fasta') + ] + ] + input[3] = null + """ + } + } + + then { + assert function.success + assert function.result + assert snapshot ( + function.result[0], + function.result[1].collect { file(it).name }, + function.result[2].collect { file(it).name }, + function.result[3], + ).match() + } + } +} diff --git a/tests/synteny/packageSyriOutputsForPlotSR.nf.test.snap b/tests/synteny/packageSyriOutputsForPlotSR.nf.test.snap new file mode 100644 index 0000000..62c3893 --- /dev/null +++ b/tests/synteny/packageSyriOutputsForPlotSR.nf.test.snap @@ -0,0 +1,84 @@ +{ + "gddh13_v1p1 - FujiA - FujiB - PbDS - PcKFL - null": { + "content": [ + { + "id": "plotsr" + }, + [ + "FujiB.on.FujiAsyri.out" + ], + [ + "FujiA.plotsr.fasta", + "FujiB.plotsr.fasta" + ], + "#file\tname\nFujiA\nFujiB" + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2025-10-17T11:51:25.665918" + }, + "FI1 - JAD - TT_2021a - null": { + "content": [ + { + "id": "plotsr" + }, + [ + "JAD.on.FI1syri.out" + ], + [ + "FI1.plotsr.fasta", + "JAD.plotsr.fasta" + ], + "#file\tname\nFI1\nJAD" + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2025-10-17T12:07:02.170384" + }, + "gddh13_v1p1 - FujiA - FujiB - PbDS - PcKFL": { + "content": [ + { + "id": "plotsr" + }, + [ + "FujiA.on.gddh13_v1p1syri.out", + "FujiB.on.FujiAsyri.out" + ], + [ + "gddh13_v1p1.plotsr.fasta", + "FujiA.plotsr.fasta", + "FujiB.plotsr.fasta" + ], + "#file\tname\ngddh13_v1p1\nFujiA\nFujiB" + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2025-10-17T11:51:22.18351" + }, + "FI1 - JAD - TT_2021a": { + "content": [ + { + "id": "plotsr" + }, + [ + "JAD.on.FI1syri.out" + ], + [ + "FI1.plotsr.fasta", + "JAD.plotsr.fasta" + ], + "#file\tname\nFI1\nJAD" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.8" + }, + "timestamp": "2025-10-13T11:51:10.498346" + } +} \ No newline at end of file diff --git a/tests/tiny/main.nf.test.snap b/tests/tiny/main.nf.test.snap index 404bb90..074b588 100644 --- a/tests/tiny/main.nf.test.snap +++ b/tests/tiny/main.nf.test.snap @@ -29,7 +29,7 @@ "pigz": "2.3.4" }, "Workflow": { - "plant-food-research-open/assemblyqc": "v3.0.0" + "plant-food-research-open/assemblyqc": "v3.0.1" } }, "stable paths": [