diff --git a/modules/nf-core/popscle/freemuxlet/environment.yml b/modules/nf-core/popscle/freemuxlet/environment.yml new file mode 100644 index 00000000000..c6747a0ae1e --- /dev/null +++ b/modules/nf-core/popscle/freemuxlet/environment.yml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +name: "popscle_freemuxlet" +channels: + - conda-forge + - bioconda + - defaults +dependencies: + - "bioconda::popscle=0.1" diff --git a/modules/nf-core/popscle/freemuxlet/main.nf b/modules/nf-core/popscle/freemuxlet/main.nf new file mode 100644 index 00000000000..d94d36a126f --- /dev/null +++ b/modules/nf-core/popscle/freemuxlet/main.nf @@ -0,0 +1,61 @@ +process POPSCLE_FREEMUXLET { + tag "$meta.id" + label 'process_high' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/popscle:0.1beta--h2c78cec_0' : + 'biocontainers/popscle:0.1beta--h2c78cec_0' }" + + input: + tuple val(meta), path(plp), val(n_sample) + + output: + tuple val(meta), path('*.clust1.samples.gz') , emit: result + tuple val(meta), path('*.clust1.vcf.gz') , emit: vcf + tuple val(meta), path('*.lmix') , emit: lmix + tuple val(meta), path('*.clust0.samples.gz') , emit: singlet_result , optional: true + tuple val(meta), path('*.clust0.vcf.gz') , emit: singlet_vcf , optional: true + 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 VERSION = '0.1' // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + """ + popscle freemuxlet \\ + --plp ${plp}/$prefix \\ + --out $prefix \\ + --nsample $n_sample \\ + $args + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + popscle: $VERSION + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '0.1' // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + + """ + touch ${prefix}.clust1.samples.gz + touch ${prefix}.clust1.vcf.gz + touch ${prefix}.lmix + + if [[ "$args" == *"--aux-files"* ]]; then + touch ${prefix}.clust0.samples.gz + touch ${prefix}.clust0.vcf.gz + fi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + popscle: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/popscle/freemuxlet/meta.yml b/modules/nf-core/popscle/freemuxlet/meta.yml new file mode 100644 index 00000000000..34eaaa59dc9 --- /dev/null +++ b/modules/nf-core/popscle/freemuxlet/meta.yml @@ -0,0 +1,73 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "popscle_freemuxlet" +description: Software to deconvolute sample identity and identify multiplets when multiple samples are pooled by barcoded single cell sequencing and external genotyping data for each sample is not available. +keywords: + - popscle + - demultiplexing + - genotype-based deconvoltion + - single cell +tools: + - "popscle": + description: "A suite of population scale analysis tools for single-cell genomics data including implementation of Demuxlet / Freemuxlet methods and auxilary tools" + homepage: "https://github.com/statgen/popscle" + documentation: "https://github.com/statgen/popscle" + tool_dev_url: "https://github.com/statgen/popscle" + doi: "10.1038/nbt.4042" + licence: ["Apache-2.0"] + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1']` + + - plp: + type: directory + description: Directory contains pileup files (CEL,VAR and PLP) produced by popscle/dsc_pileup. + - n_sample: + type: integer + description: Number of samples multiplexed together. + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + + - result: + type: file + description: Output file contains the best guess of the sample identity, with detailed statistics to reach to the best guess. + pattern: "*.clust1.samples.gz" + + - vcf: + type: file + description: Output vcf file for each sample inferred and clustered from freemuxlet. + pattern: "*.clust1.vcf.gz" + + - lmix: + type: file + description: Output file contains basic statistics for each barcode. + pattern: "*.lmix" + + - singlet_result: + type: file + description: Optional output file contains the best sample identity assuming all droplets are singlets when writing auxiliary output files is turned on. + pattern: "*.clust0.samples.gz" + + - singlet_vcf: + type: file + description: Optional output vcf file for each sample inferred and clustered from freemuxlet assuming all droplets are singlets when writing auxiliary output files is turned on. + pattern: "*.clust0.vcf.gz" + +authors: + - "@wxicu" +maintainers: + - "@wxicu" diff --git a/modules/nf-core/popscle/freemuxlet/tests/main.nf.test b/modules/nf-core/popscle/freemuxlet/tests/main.nf.test new file mode 100644 index 00000000000..e8c2225c6e7 --- /dev/null +++ b/modules/nf-core/popscle/freemuxlet/tests/main.nf.test @@ -0,0 +1,183 @@ +nextflow_process { + + name "Test Process POPSCLE_FREEMUXLET" + script "../main.nf" + process "POPSCLE_FREEMUXLET" + + tag "modules" + tag "modules_nfcore" + tag "popscle" + tag "popscle/dscpileup" + tag "popscle/freemuxlet" + + test("demultiplexing") { + setup { + run("POPSCLE_DSCPILEUP") { + script "../../dscpileup/main.nf" + process { + """ + input[0] = [ + [ id:'sample1' ], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/demultiplexing/chr21.bam', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/demultiplexing/donor_genotype_chr21.vcf', checkIfExists: true), + ] + """ + } + } + } + + when { + process { + """ + input[0] = POPSCLE_DSCPILEUP.out.plp.collect{ meta, plp -> plp }.map{ + plp -> [[ id: 'sample1'], + plp[0].getParent(), + 2 ]} + """ + } + } + + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.versions).match("versions") }, + { assert path(process.out.result.get(0).get(1)).exists() }, + { assert path(process.out.vcf.get(0).get(1)).exists() }, + { assert path(process.out.lmix.get(0).get(1)).exists() } + ) + } + + } + + test("demultiplexing - auxilary - files") { + config "./nextflow.config" + setup { + run("POPSCLE_DSCPILEUP") { + script "../../dscpileup/main.nf" + process { + """ + input[0] = [ + [ id:'sample1' ], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/demultiplexing/chr21.bam', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/demultiplexing/donor_genotype_chr21.vcf', checkIfExists: true), + ] + """ + } + } + } + + when { + process { + """ + input[0] = POPSCLE_DSCPILEUP.out.plp.collect{ meta, plp -> plp }.map{ + plp -> [[ id: 'sample1'], + plp[0].getParent(), + 2 ]} + """ + } + } + + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.versions).match("versions-aux-files") }, + { assert path(process.out.result.get(0).get(1)).exists() }, + { assert path(process.out.vcf.get(0).get(1)).exists() }, + { assert path(process.out.lmix.get(0).get(1)).exists() }, + { assert path(process.out.singlet_result.get(0).get(1)).exists() }, + { assert path(process.out.singlet_vcf.get(0).get(1)).exists() } + ) + } + + } + + test("demultiplexing - stub") { + + options "-stub" + + setup { + run("POPSCLE_DSCPILEUP") { + script "../../dscpileup/main.nf" + process { + """ + input[0] = [ + [ id:'sample1' ], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/demultiplexing/chr21.bam', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/demultiplexing/donor_genotype_chr21.vcf', checkIfExists: true), + ] + """ + } + } + } + + when { + process { + """ + input[0] = POPSCLE_DSCPILEUP.out.plp.collect{ meta, plp -> plp }.map{ + plp -> [[ id: 'sample1'], + plp[0].toString() - '.plp.gz', + 2 ]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.versions).match("versions-stub") }, + { assert path(process.out.result.get(0).get(1)).exists() }, + { assert path(process.out.vcf.get(0).get(1)).exists() }, + { assert path(process.out.lmix.get(0).get(1)).exists() } + ) + } + + } + + test("demultiplexing - auxilary - files - stub") { + + options "-stub" + config "./nextflow.config" + + setup { + run("POPSCLE_DSCPILEUP") { + script "../../dscpileup/main.nf" + process { + """ + input[0] = [ + [ id:'sample1' ], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/demultiplexing/chr21.bam', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/demultiplexing/donor_genotype_chr21.vcf', checkIfExists: true), + ] + """ + } + } + } + + when { + process { + """ + input[0] = POPSCLE_DSCPILEUP.out.plp.collect{ meta, plp -> plp }.map{ + plp -> [[ id: 'sample1'], + plp[0].toString() - '.plp.gz', + 2 ]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.versions).match("versions-aux-files-stub") }, + { assert path(process.out.result.get(0).get(1)).exists() }, + { assert path(process.out.vcf.get(0).get(1)).exists() }, + { assert path(process.out.lmix.get(0).get(1)).exists() }, + { assert path(process.out.singlet_result.get(0).get(1)).exists() }, + { assert path(process.out.singlet_vcf.get(0).get(1)).exists() } + ) + } + + } + +} diff --git a/modules/nf-core/popscle/freemuxlet/tests/main.nf.test.snap b/modules/nf-core/popscle/freemuxlet/tests/main.nf.test.snap new file mode 100644 index 00000000000..b2502c9194d --- /dev/null +++ b/modules/nf-core/popscle/freemuxlet/tests/main.nf.test.snap @@ -0,0 +1,50 @@ +{ + "versions": { + "content": [ + [ + "versions.yml:md5,8d90ac14cd657f4c831007418a55910d" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-25T12:49:23.684387488" + }, + "versions-aux-files": { + "content": [ + [ + "versions.yml:md5,8d90ac14cd657f4c831007418a55910d" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-25T12:49:35.355844696" + }, + "versions-aux-files-stub": { + "content": [ + [ + "versions.yml:md5,8d90ac14cd657f4c831007418a55910d" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-25T12:49:56.179166814" + }, + "versions-stub": { + "content": [ + [ + "versions.yml:md5,8d90ac14cd657f4c831007418a55910d" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-25T12:49:45.801327201" + } +} \ No newline at end of file diff --git a/modules/nf-core/popscle/freemuxlet/tests/nextflow.config b/modules/nf-core/popscle/freemuxlet/tests/nextflow.config new file mode 100644 index 00000000000..55d2a6d11bf --- /dev/null +++ b/modules/nf-core/popscle/freemuxlet/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: POPSCLE_FREEMUXLET { + ext.args = '--aux-files' + } +} diff --git a/modules/nf-core/popscle/freemuxlet/tests/tags.yml b/modules/nf-core/popscle/freemuxlet/tests/tags.yml new file mode 100644 index 00000000000..8eca91f7a48 --- /dev/null +++ b/modules/nf-core/popscle/freemuxlet/tests/tags.yml @@ -0,0 +1,2 @@ +popscle/freemuxlet: + - "modules/nf-core/popscle/freemuxlet/**"