From 92b5a42360a54df50a499f69f82517aa7b014fbf Mon Sep 17 00:00:00 2001 From: CI Date: Fri, 13 Sep 2024 11:32:59 +0000 Subject: [PATCH] Build branch main with version main (cb9b328) Build pipeline: viash-hub.rnaseq.main-mf5kg Source commit: https://github.com/viash-hub/rnaseq/commit/cb9b32883494c48f394213551a82e9103f2e620c Source message: Update pointers to biobox and craftbox --- .../config.vsh.yaml | 4 +- src/workflows/post_processing/config.vsh.yaml | 4 +- src/workflows/pre_processing/config.vsh.yaml | 2 +- src/workflows/prepare_genome/config.vsh.yaml | 4 +- .../config.vsh.yaml | 4 +- src/workflows/quality_control/config.vsh.yaml | 4 +- .../salmon/salmon_quant/.config.vsh.yaml | 1185 ----- .../v0.1/nextflow/salmon/salmon_quant/main.nf | 4693 ----------------- .../salmon/salmon_quant/nextflow.config | 125 - .../salmon/salmon_quant/nextflow_schema.json | 1119 ---- .../samtools_flagstat/.config.vsh.yaml | 185 - .../samtools/samtools_flagstat/main.nf | 3528 ------------- .../samtools_flagstat/nextflow.config | 125 - .../samtools_flagstat/nextflow_schema.json | 105 - .../samtools_idxstats/.config.vsh.yaml | 195 - .../samtools/samtools_idxstats/main.nf | 3538 ------------- .../samtools_idxstats/nextflow.config | 125 - .../samtools_idxstats/nextflow_schema.json | 115 - .../samtools/samtools_index/.config.vsh.yaml | 201 - .../nextflow/samtools/samtools_index/main.nf | 3562 ------------- .../samtools/samtools_index/nextflow.config | 125 - .../samtools_index/nextflow_schema.json | 141 - .../samtools/samtools_sort/.config.vsh.yaml | 344 -- .../nextflow/samtools/samtools_sort/main.nf | 3775 ------------- .../samtools/samtools_sort/nextflow.config | 125 - .../samtools_sort/nextflow_schema.json | 309 -- .../samtools/samtools_stats/.config.vsh.yaml | 406 -- .../nextflow/samtools/samtools_stats/main.nf | 3836 -------------- .../samtools/samtools_stats/nextflow.config | 125 - .../samtools_stats/nextflow_schema.json | 327 -- .../nextflow/fastp/.config.vsh.yaml | 32 +- .../{v0.1 => v0.2.0}/nextflow/fastp/main.nf | 168 +- .../nextflow/fastp/nextflow.config | 3 +- .../nextflow/fastp/nextflow_schema.json | 0 .../nextflow/featurecounts/.config.vsh.yaml | 28 +- .../nextflow/featurecounts/main.nf | 160 +- .../nextflow/featurecounts/nextflow.config | 3 +- .../featurecounts/nextflow_schema.json | 24 +- .../nextflow/gffread/.config.vsh.yaml | 14 +- .../{main => v0.2.0}/nextflow/gffread/main.nf | 47 +- .../nextflow/gffread/nextflow.config | 2 +- .../nextflow/gffread/nextflow_schema.json | 0 .../nextflow/multiqc/.config.vsh.yaml | 48 +- .../{v0.1 => v0.2.0}/nextflow/multiqc/main.nf | 189 +- .../nextflow/multiqc/nextflow.config | 3 +- .../nextflow/multiqc/nextflow_schema.json | 20 +- .../rsem_prepare_reference/.config.vsh.yaml | 14 +- .../rsem/rsem_prepare_reference/main.nf | 47 +- .../rsem_prepare_reference/nextflow.config | 2 +- .../nextflow_schema.json | 0 .../salmon/salmon_index/.config.vsh.yaml | 14 +- .../nextflow/salmon/salmon_index/main.nf | 47 +- .../salmon/salmon_index/nextflow.config | 2 +- .../salmon/salmon_index/nextflow_schema.json | 0 .../salmon/salmon_quant/.config.vsh.yaml | 14 +- .../nextflow/salmon/salmon_quant/main.nf | 47 +- .../salmon/salmon_quant/nextflow.config | 2 +- .../salmon/salmon_quant/nextflow_schema.json | 0 .../samtools_flagstat/.config.vsh.yaml | 14 +- .../samtools/samtools_flagstat/main.nf | 47 +- .../samtools_flagstat/nextflow.config | 2 +- .../samtools_flagstat/nextflow_schema.json | 0 .../samtools_idxstats/.config.vsh.yaml | 14 +- .../samtools/samtools_idxstats/main.nf | 47 +- .../samtools_idxstats/nextflow.config | 2 +- .../samtools_idxstats/nextflow_schema.json | 0 .../samtools/samtools_index/.config.vsh.yaml | 14 +- .../nextflow/samtools/samtools_index/main.nf | 47 +- .../samtools/samtools_index/nextflow.config | 2 +- .../samtools_index/nextflow_schema.json | 0 .../samtools/samtools_sort/.config.vsh.yaml | 14 +- .../nextflow/samtools/samtools_sort/main.nf | 47 +- .../samtools/samtools_sort/nextflow.config | 2 +- .../samtools_sort/nextflow_schema.json | 0 .../samtools/samtools_stats/.config.vsh.yaml | 14 +- .../nextflow/samtools/samtools_stats/main.nf | 47 +- .../samtools/samtools_stats/nextflow.config | 2 +- .../samtools_stats/nextflow_schema.json | 0 .../star/star_align_reads/.config.vsh.yaml | 14 +- .../nextflow/star/star_align_reads/main.nf | 49 +- .../star/star_align_reads/nextflow.config | 2 +- .../star_align_reads/nextflow_schema.json | 0 .../star_genome_generate/.config.vsh.yaml | 14 +- .../star/star_genome_generate/main.nf | 47 +- .../star/star_genome_generate/nextflow.config | 2 +- .../star_genome_generate/nextflow_schema.json | 0 .../nextflow/untar/.config.vsh.yaml | 10 +- .../{main => v0.1.0}/nextflow/untar/main.nf | 14 +- .../nextflow/untar/nextflow.config | 2 +- .../nextflow/untar/nextflow_schema.json | 0 .../executable/bbmap_bbsplit/.config.vsh.yaml | 2 +- target/executable/bbmap_bbsplit/bbmap_bbsplit | 4 +- .../bedtools_genomecov/.config.vsh.yaml | 2 +- .../bedtools_genomecov/bedtools_genomecov | 4 +- .../cat_additional_fasta/.config.vsh.yaml | 2 +- .../cat_additional_fasta/cat_additional_fasta | 4 +- target/executable/cat_fastq/.config.vsh.yaml | 2 +- target/executable/cat_fastq/cat_fastq | 4 +- target/executable/deseq2_qc/.config.vsh.yaml | 2 +- target/executable/deseq2_qc/deseq2_qc | 4 +- target/executable/dupradar/.config.vsh.yaml | 2 +- target/executable/dupradar/dupradar | 4 +- target/executable/fastqc/.config.vsh.yaml | 2 +- target/executable/fastqc/fastqc | 4 +- .../executable/fq_subsample/.config.vsh.yaml | 2 +- target/executable/fq_subsample/fq_subsample | 4 +- .../executable/getchromsizes/.config.vsh.yaml | 2 +- target/executable/getchromsizes/getchromsizes | 4 +- target/executable/gtf2bed/.config.vsh.yaml | 2 +- target/executable/gtf2bed/gtf2bed | 4 +- target/executable/gtf_filter/.config.vsh.yaml | 2 +- target/executable/gtf_filter/gtf_filter | 4 +- target/executable/gunzip/.config.vsh.yaml | 2 +- target/executable/gunzip/gunzip | 4 +- .../kallisto/kallisto_index/.config.vsh.yaml | 2 +- .../kallisto/kallisto_index/kallisto_index | 4 +- .../kallisto/kallisto_quant/.config.vsh.yaml | 2 +- .../kallisto/kallisto_quant/kallisto_quant | 4 +- .../multiqc_custom_biotype/.config.vsh.yaml | 2 +- .../multiqc_custom_biotype | 4 +- .../picard_markduplicates/.config.vsh.yaml | 2 +- .../picard_markduplicates | 4 +- .../prepare_multiqc_input/.config.vsh.yaml | 2 +- .../prepare_multiqc_input | 4 +- .../.config.vsh.yaml | 2 +- .../preprocess_transcripts_fasta | 4 +- .../preseq_lcextrap/.config.vsh.yaml | 2 +- .../preseq_lcextrap/preseq_lcextrap | 4 +- target/executable/qualimap/.config.vsh.yaml | 2 +- target/executable/qualimap/qualimap | 4 +- .../.config.vsh.yaml | 2 +- .../rsem_calculate_expression | 4 +- .../rsem/rsem_merge_counts/.config.vsh.yaml | 2 +- .../rsem/rsem_merge_counts/rsem_merge_counts | 4 +- .../rseqc/rseqc_bamstat/.config.vsh.yaml | 2 +- .../rseqc/rseqc_bamstat/rseqc_bamstat | 4 +- .../rseqc_inferexperiment/.config.vsh.yaml | 2 +- .../rseqc_inferexperiment | 4 +- .../rseqc_innerdistance/.config.vsh.yaml | 2 +- .../rseqc_innerdistance/rseqc_innerdistance | 4 +- .../rseqc_junctionannotation/.config.vsh.yaml | 2 +- .../rseqc_junctionannotation | 4 +- .../rseqc_junctionsaturation/.config.vsh.yaml | 2 +- .../rseqc_junctionsaturation | 4 +- .../rseqc_readdistribution/.config.vsh.yaml | 2 +- .../rseqc_readdistribution | 4 +- .../rseqc_readduplication/.config.vsh.yaml | 2 +- .../rseqc_readduplication | 4 +- .../rseqc/rseqc_tin/.config.vsh.yaml | 2 +- target/executable/rseqc/rseqc_tin/rseqc_tin | 4 +- target/executable/sortmerna/.config.vsh.yaml | 2 +- target/executable/sortmerna/sortmerna | 4 +- target/executable/stringtie/.config.vsh.yaml | 2 +- target/executable/stringtie/stringtie | 4 +- .../summarizedexperiment/.config.vsh.yaml | 2 +- .../summarizedexperiment/summarizedexperiment | 4 +- target/executable/trimgalore/.config.vsh.yaml | 2 +- target/executable/trimgalore/trimgalore | 4 +- target/executable/tx2gene/.config.vsh.yaml | 2 +- target/executable/tx2gene/tx2gene | 4 +- target/executable/tximport/.config.vsh.yaml | 2 +- target/executable/tximport/tximport | 4 +- .../executable/ucsc/bedclip/.config.vsh.yaml | 2 +- target/executable/ucsc/bedclip/bedclip | 4 +- .../ucsc/bedgraphtobigwig/.config.vsh.yaml | 2 +- .../ucsc/bedgraphtobigwig/bedgraphtobigwig | 4 +- .../umitools/umitools_dedup/.config.vsh.yaml | 2 +- .../umitools/umitools_dedup/umitools_dedup | 4 +- .../umitools_extract/.config.vsh.yaml | 2 +- .../umitools_extract/umitools_extract | 4 +- .../umitools_prepareforquant/.config.vsh.yaml | 2 +- .../umitools_prepareforquant | 4 +- .../.config.vsh.yaml | 24 +- .../genome_alignment_and_quant | 14 +- .../merge_quant_results/.config.vsh.yaml | 2 +- .../post_processing/.config.vsh.yaml | 24 +- .../workflows/post_processing/post_processing | 10 +- .../workflows/pre_processing/.config.vsh.yaml | 12 +- .../workflows/pre_processing/pre_processing | 4 +- .../workflows/prepare_genome/.config.vsh.yaml | 26 +- .../workflows/prepare_genome/prepare_genome | 10 +- .../.config.vsh.yaml | 8 +- .../pseudo_alignment_and_quant | 2 +- .../quality_control/.config.vsh.yaml | 12 +- .../workflows/quality_control/quality_control | 4 +- .../workflows/rnaseq/.config.vsh.yaml | 2 +- .../nextflow/bbmap_bbsplit/.config.vsh.yaml | 2 +- target/nextflow/bbmap_bbsplit/main.nf | 2 +- .../bedtools_genomecov/.config.vsh.yaml | 2 +- target/nextflow/bedtools_genomecov/main.nf | 2 +- .../cat_additional_fasta/.config.vsh.yaml | 2 +- target/nextflow/cat_additional_fasta/main.nf | 2 +- target/nextflow/cat_fastq/.config.vsh.yaml | 2 +- target/nextflow/cat_fastq/main.nf | 2 +- target/nextflow/deseq2_qc/.config.vsh.yaml | 2 +- target/nextflow/deseq2_qc/main.nf | 2 +- target/nextflow/dupradar/.config.vsh.yaml | 2 +- target/nextflow/dupradar/main.nf | 2 +- target/nextflow/fastqc/.config.vsh.yaml | 2 +- target/nextflow/fastqc/main.nf | 2 +- target/nextflow/fq_subsample/.config.vsh.yaml | 2 +- target/nextflow/fq_subsample/main.nf | 2 +- .../nextflow/getchromsizes/.config.vsh.yaml | 2 +- target/nextflow/getchromsizes/main.nf | 2 +- target/nextflow/gtf2bed/.config.vsh.yaml | 2 +- target/nextflow/gtf2bed/main.nf | 2 +- target/nextflow/gtf_filter/.config.vsh.yaml | 2 +- target/nextflow/gtf_filter/main.nf | 2 +- target/nextflow/gunzip/.config.vsh.yaml | 2 +- target/nextflow/gunzip/main.nf | 2 +- .../kallisto/kallisto_index/.config.vsh.yaml | 2 +- .../nextflow/kallisto/kallisto_index/main.nf | 2 +- .../kallisto/kallisto_quant/.config.vsh.yaml | 2 +- .../nextflow/kallisto/kallisto_quant/main.nf | 2 +- .../multiqc_custom_biotype/.config.vsh.yaml | 2 +- .../nextflow/multiqc_custom_biotype/main.nf | 2 +- .../picard_markduplicates/.config.vsh.yaml | 2 +- target/nextflow/picard_markduplicates/main.nf | 2 +- .../prepare_multiqc_input/.config.vsh.yaml | 2 +- target/nextflow/prepare_multiqc_input/main.nf | 2 +- .../.config.vsh.yaml | 2 +- .../preprocess_transcripts_fasta/main.nf | 2 +- .../nextflow/preseq_lcextrap/.config.vsh.yaml | 2 +- target/nextflow/preseq_lcextrap/main.nf | 2 +- target/nextflow/qualimap/.config.vsh.yaml | 2 +- target/nextflow/qualimap/main.nf | 2 +- .../.config.vsh.yaml | 2 +- .../rsem/rsem_calculate_expression/main.nf | 2 +- .../rsem/rsem_merge_counts/.config.vsh.yaml | 2 +- .../nextflow/rsem/rsem_merge_counts/main.nf | 2 +- .../rseqc/rseqc_bamstat/.config.vsh.yaml | 2 +- target/nextflow/rseqc/rseqc_bamstat/main.nf | 2 +- .../rseqc_inferexperiment/.config.vsh.yaml | 2 +- .../rseqc/rseqc_inferexperiment/main.nf | 2 +- .../rseqc_innerdistance/.config.vsh.yaml | 2 +- .../rseqc/rseqc_innerdistance/main.nf | 2 +- .../rseqc_junctionannotation/.config.vsh.yaml | 2 +- .../rseqc/rseqc_junctionannotation/main.nf | 2 +- .../rseqc_junctionsaturation/.config.vsh.yaml | 2 +- .../rseqc/rseqc_junctionsaturation/main.nf | 2 +- .../rseqc_readdistribution/.config.vsh.yaml | 2 +- .../rseqc/rseqc_readdistribution/main.nf | 2 +- .../rseqc_readduplication/.config.vsh.yaml | 2 +- .../rseqc/rseqc_readduplication/main.nf | 2 +- .../nextflow/rseqc/rseqc_tin/.config.vsh.yaml | 2 +- target/nextflow/rseqc/rseqc_tin/main.nf | 2 +- target/nextflow/sortmerna/.config.vsh.yaml | 2 +- target/nextflow/sortmerna/main.nf | 2 +- target/nextflow/stringtie/.config.vsh.yaml | 2 +- target/nextflow/stringtie/main.nf | 2 +- .../summarizedexperiment/.config.vsh.yaml | 2 +- target/nextflow/summarizedexperiment/main.nf | 2 +- target/nextflow/trimgalore/.config.vsh.yaml | 2 +- target/nextflow/trimgalore/main.nf | 2 +- target/nextflow/tx2gene/.config.vsh.yaml | 2 +- target/nextflow/tx2gene/main.nf | 2 +- target/nextflow/tximport/.config.vsh.yaml | 2 +- target/nextflow/tximport/main.nf | 2 +- target/nextflow/ucsc/bedclip/.config.vsh.yaml | 2 +- target/nextflow/ucsc/bedclip/main.nf | 2 +- .../ucsc/bedgraphtobigwig/.config.vsh.yaml | 2 +- target/nextflow/ucsc/bedgraphtobigwig/main.nf | 2 +- .../umitools/umitools_dedup/.config.vsh.yaml | 2 +- .../nextflow/umitools/umitools_dedup/main.nf | 2 +- .../umitools_extract/.config.vsh.yaml | 2 +- .../umitools/umitools_extract/main.nf | 2 +- .../umitools_prepareforquant/.config.vsh.yaml | 2 +- .../nextflow/umitools_prepareforquant/main.nf | 2 +- .../.config.vsh.yaml | 24 +- .../genome_alignment_and_quant/main.nf | 40 +- .../merge_quant_results/.config.vsh.yaml | 2 +- .../workflows/merge_quant_results/main.nf | 2 +- .../post_processing/.config.vsh.yaml | 24 +- .../workflows/post_processing/main.nf | 24 +- .../workflows/pre_processing/.config.vsh.yaml | 12 +- .../nextflow/workflows/pre_processing/main.nf | 12 +- .../workflows/prepare_genome/.config.vsh.yaml | 26 +- .../nextflow/workflows/prepare_genome/main.nf | 26 +- .../.config.vsh.yaml | 8 +- .../pseudo_alignment_and_quant/main.nf | 8 +- .../quality_control/.config.vsh.yaml | 12 +- .../workflows/quality_control/main.nf | 12 +- .../workflows/rnaseq/.config.vsh.yaml | 2 +- target/nextflow/workflows/rnaseq/main.nf | 2 +- 284 files changed, 1310 insertions(+), 29225 deletions(-) delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/.config.vsh.yaml delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/main.nf delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/nextflow.config delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/nextflow_schema.json delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/.config.vsh.yaml delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/main.nf delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/nextflow.config delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/nextflow_schema.json delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/.config.vsh.yaml delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/main.nf delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/nextflow.config delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/nextflow_schema.json delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/.config.vsh.yaml delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/main.nf delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/nextflow.config delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/nextflow_schema.json delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/.config.vsh.yaml delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/main.nf delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/nextflow.config delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/nextflow_schema.json delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/.config.vsh.yaml delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/main.nf delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/nextflow.config delete mode 100644 target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/nextflow_schema.json rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/fastp/.config.vsh.yaml (98%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/fastp/main.nf (97%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/fastp/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/fastp/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/featurecounts/.config.vsh.yaml (97%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/featurecounts/main.nf (97%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/featurecounts/nextflow.config (98%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/featurecounts/nextflow_schema.json (95%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/gffread/.config.vsh.yaml (98%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/gffread/main.nf (99%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/gffread/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/gffread/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/multiqc/.config.vsh.yaml (94%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/multiqc/main.nf (97%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/multiqc/nextflow.config (98%) rename target/dependencies/vsh/vsh/biobox/{v0.1 => v0.2.0}/nextflow/multiqc/nextflow_schema.json (96%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/rsem/rsem_prepare_reference/.config.vsh.yaml (98%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/rsem/rsem_prepare_reference/main.nf (98%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/rsem/rsem_prepare_reference/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/rsem/rsem_prepare_reference/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/salmon/salmon_index/.config.vsh.yaml (97%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/salmon/salmon_index/main.nf (98%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/salmon/salmon_index/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/salmon/salmon_index/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/salmon/salmon_quant/.config.vsh.yaml (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/salmon/salmon_quant/main.nf (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/salmon/salmon_quant/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/salmon/salmon_quant/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_flagstat/.config.vsh.yaml (95%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_flagstat/main.nf (98%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_flagstat/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_flagstat/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_idxstats/.config.vsh.yaml (96%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_idxstats/main.nf (98%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_idxstats/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_idxstats/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_index/.config.vsh.yaml (96%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_index/main.nf (98%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_index/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_index/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_sort/.config.vsh.yaml (97%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_sort/main.nf (98%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_sort/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_sort/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_stats/.config.vsh.yaml (97%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_stats/main.nf (98%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_stats/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/samtools/samtools_stats/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/star/star_align_reads/.config.vsh.yaml (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/star/star_align_reads/main.nf (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/star/star_align_reads/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{ => v0.2.0}/nextflow/star/star_align_reads/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/star/star_genome_generate/.config.vsh.yaml (97%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/star/star_genome_generate/main.nf (98%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/star/star_genome_generate/nextflow.config (99%) rename target/dependencies/vsh/vsh/biobox/{main => v0.2.0}/nextflow/star/star_genome_generate/nextflow_schema.json (100%) rename target/dependencies/vsh/vsh/craftbox/{main => v0.1.0}/nextflow/untar/.config.vsh.yaml (96%) rename target/dependencies/vsh/vsh/craftbox/{main => v0.1.0}/nextflow/untar/main.nf (99%) rename target/dependencies/vsh/vsh/craftbox/{main => v0.1.0}/nextflow/untar/nextflow.config (99%) rename target/dependencies/vsh/vsh/craftbox/{main => v0.1.0}/nextflow/untar/nextflow_schema.json (100%) diff --git a/src/workflows/genome_alignment_and_quant/config.vsh.yaml b/src/workflows/genome_alignment_and_quant/config.vsh.yaml index cab3e19..6e79592 100644 --- a/src/workflows/genome_alignment_and_quant/config.vsh.yaml +++ b/src/workflows/genome_alignment_and_quant/config.vsh.yaml @@ -177,9 +177,9 @@ repositories: - name: biobox type: vsh repo: vsh/biobox - # tag: v0.1 + tag: v0.2.0 runners: - type: executable -- type: nextflow \ No newline at end of file +- type: nextflow diff --git a/src/workflows/post_processing/config.vsh.yaml b/src/workflows/post_processing/config.vsh.yaml index 4756a0a..778b69a 100644 --- a/src/workflows/post_processing/config.vsh.yaml +++ b/src/workflows/post_processing/config.vsh.yaml @@ -159,8 +159,8 @@ repositories: - name: biobox type: vsh repo: vsh/biobox - tag: v0.1 + tag: v0.2.0 runners: - type: executable -- type: nextflow \ No newline at end of file +- type: nextflow diff --git a/src/workflows/pre_processing/config.vsh.yaml b/src/workflows/pre_processing/config.vsh.yaml index dd89507..6535dde 100644 --- a/src/workflows/pre_processing/config.vsh.yaml +++ b/src/workflows/pre_processing/config.vsh.yaml @@ -271,7 +271,7 @@ repositories: - name: biobox type: vsh repo: vsh/biobox - tag: v0.1 + tag: v0.2.0 runners: - type: executable diff --git a/src/workflows/prepare_genome/config.vsh.yaml b/src/workflows/prepare_genome/config.vsh.yaml index 7c228a3..4bd9bc0 100644 --- a/src/workflows/prepare_genome/config.vsh.yaml +++ b/src/workflows/prepare_genome/config.vsh.yaml @@ -168,11 +168,11 @@ repositories: - name: biobox type: vsh repo: biobox - tag: main + tag: v0.2.0 - name: craftbox type: vsh repo: craftbox - tag: main + tag: v0.1.0 runners: - type: executable diff --git a/src/workflows/pseudo_alignment_and_quant/config.vsh.yaml b/src/workflows/pseudo_alignment_and_quant/config.vsh.yaml index a9f41e6..586c472 100644 --- a/src/workflows/pseudo_alignment_and_quant/config.vsh.yaml +++ b/src/workflows/pseudo_alignment_and_quant/config.vsh.yaml @@ -87,8 +87,8 @@ repositories: - name: biobox type: vsh repo: vsh/biobox - tag: v0.1 + tag: v0.2.0 runners: - type: executable -- type: nextflow \ No newline at end of file +- type: nextflow diff --git a/src/workflows/quality_control/config.vsh.yaml b/src/workflows/quality_control/config.vsh.yaml index c5c4546..b615e7a 100644 --- a/src/workflows/quality_control/config.vsh.yaml +++ b/src/workflows/quality_control/config.vsh.yaml @@ -656,9 +656,9 @@ repositories: - name: biobox type: vsh repo: vsh/biobox - tag: v0.1 + tag: v0.2.0 runners: - type: executable -- type: nextflow \ No newline at end of file +- type: nextflow diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/.config.vsh.yaml deleted file mode 100644 index 381e237..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/.config.vsh.yaml +++ /dev/null @@ -1,1185 +0,0 @@ -name: "salmon_quant" -namespace: "salmon" -version: "v0.1.0" -argument_groups: -- name: "Common input options" - arguments: - - type: "string" - name: "--lib_type" - alternatives: - - "-l" - description: "Format string describing the library.\nThe library type string consists\ - \ of three parts: \n1. Relative orientation of the reads: This part is only\ - \ provided if the library is paired-end, THe possible options are\n I = inward\n\ - \ O = outward\n M = matching\n2. Strandedness of the library: This part specifies\ - \ whether the protocol is stranded or unstranded. The options are:\n S = stranded\n\ - \ U = unstranded\n3. Directionality of the reads: If the library is stranded,\ - \ the final part of the library string is used to specify the strand from which\ - \ the read originates. The possible values are\n F = read 1 (or single-end\ - \ read) comes from the forward strand\n R = read 1 (or single-end read) comes\ - \ from the reverse strand\n" - info: null - default: - - "A" - required: false - choices: - - "A" - - "U" - - "SF" - - "SR" - - "IU" - - "IS" - - "ISF" - - "ISR" - - "OU" - - "OS" - - "OSF" - - "OSR" - - "MU" - - "MS" - - "MSF" - - "MSR" - direction: "input" - multiple: false - multiple_sep: ";" -- name: "Mapping input options" - arguments: - - type: "file" - name: "--index" - alternatives: - - "-i" - description: "Salmon index.\n" - info: null - example: - - "transcriptome_index" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--unmated_reads" - alternatives: - - "-r" - description: "List of files containing unmated reads of (e.g. single-end reads).\n" - info: null - example: - - "sample.fq.gz" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: true - multiple_sep: ";" - - type: "file" - name: "--mates1" - alternatives: - - "-m1" - description: "File containing the #1 mates.\n" - info: null - example: - - "sample_1.fq.gz" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: true - multiple_sep: ";" - - type: "file" - name: "--mates2" - alternatives: - - "-m2" - description: "File containing the #2 mates.\n" - info: null - example: - - "sample_2.fq.gz" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: true - multiple_sep: ";" -- name: "Alignment input options" - arguments: - - type: "boolean_true" - name: "--discard_orphans" - description: "Discard orphan alignments in the input [for alignment-based mode\ - \ only]. If this flag is passed, then only paired alignments will be considered\ - \ toward quantification estimates. The default behavior is to consider orphan\ - \ alignments if no valid paired mappings exist.\n" - info: null - direction: "input" - - type: "file" - name: "--alignments" - alternatives: - - "-a" - description: "Input alignment (BAM) file(s).\n" - info: null - example: - - "sample.fq.gz" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: true - multiple_sep: ";" - - type: "file" - name: "--eqclasses" - alternatives: - - "-e" - description: "input salmon weighted equivalence class file.\n" - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--targets" - alternatives: - - "-t" - description: "FASTA format file containing target transcripts.\n" - info: null - example: - - "transcripts.fasta" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--ont" - description: "Use alignment model for Oxford Nanopore long reads\n" - info: null - direction: "input" -- name: "Output" - arguments: - - type: "file" - name: "--output" - alternatives: - - "-o" - description: "Output quantification directory.\n" - info: null - example: - - "quant_output" - must_exist: true - create_parent: true - required: true - direction: "output" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--quant_results" - description: "Salmon quantification file.\n" - info: null - example: - - "quant.sf" - must_exist: true - create_parent: true - required: true - direction: "output" - multiple: false - multiple_sep: ";" -- name: "Basic options" - arguments: - - type: "boolean_true" - name: "--seq_bias" - description: "Perform sequence-specific bias correction.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--gc_bias" - description: "Perform fragment GC bias correction [beta for single-end reads].\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--pos_bias" - description: "Perform positional bias correction.\n" - info: null - direction: "input" - - type: "double" - name: "--incompat_prior" - description: "Set the prior probability that an alignment that disagrees with\ - \ the specified library type (--lib_type) results from the true fragment origin.\ - \ Setting this to 0 specifies that alignments that disagree with the library\ - \ type should be \"impossible\", while setting it to 1 says that alignments\ - \ that disagree with the library type are no less likely than those that do.\n" - info: null - example: - - 0.0 - required: false - min: 0.0 - max: 1.0 - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--gene_map" - alternatives: - - "-g" - description: "File containing a mapping of transcripts to genes. If this file\ - \ is provided salmon will output both quant.sf and quant.genes.sf files, where\ - \ the latter contains aggregated gene-level abundance estimates. The transcript\ - \ to gene mapping should be provided as either a GTF file, or a in a simple\ - \ tab-delimited format where each line contains the name of a transcript and\ - \ the gene to which it belongs separated by a tab. The extension of the file\ - \ is used to determine how the file should be parsed. Files ending in '.gtf',\ - \ '.gff' or '.gff3' are assumed to be in GTF format; files with any other extension\ - \ are assumed to be in the simple format. In GTF / GFF format, the \"transcript_id\"\ - \ is assumed to contain the transcript identifier and the \"gene_id\" is assumed\ - \ to contain the corresponding gene identifier.\n" - info: null - example: - - "gene_map.gtf" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--aux_target_file" - description: "A file containing a list of \"auxiliary\" targets. These are valid\ - \ targets (i.e., not decoys) to which fragments are allowed to map and be assigned,\ - \ and which will be quantified, but for which auxiliary models like sequence-specific\ - \ and fragment-GC bias correction should not be applied.\n" - info: null - example: - - "auxilary_targets.txt" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--meta" - description: "If you're using Salmon on a metagenomic dataset, consider setting\ - \ this flag to disable parts of the abundance estimation model that make less\ - \ sense for metagenomic data.\n" - info: null - direction: "input" - - type: "double" - name: "--score_exp" - description: "The factor by which sub-optimal alignment scores are downweighted\ - \ to produce a probability. If the best alignment score for the current read\ - \ is S, and the score for a particular alignment is w, then the probability\ - \ will be computed porportional to exp( - scoreExp * (S-w) ).\n" - info: null - example: - - 1.0 - required: false - direction: "input" - multiple: false - multiple_sep: ";" -- name: "Options specific to mapping mode" - arguments: - - type: "boolean_true" - name: "--discard_orphans_quasi" - description: "[selective-alignment mode only] \nDiscard orphan mappings in selective-alignment\ - \ mode. If this flag is passed then only paired mappings will be considered\ - \ toward quantification estimates. The default behavior is to consider orphan\ - \ mappings if no valid paired mappings exist. This flag is independent of the\ - \ option to write the orphaned mappings to file (--writeOrphanLinks).\n" - info: null - direction: "input" - - type: "double" - name: "--consensus_slack" - description: "[selective-alignment mode only] \nThe amount of slack allowed in\ - \ the selective-alignment filtering mechanism. If this is set to a fraction,\ - \ X, greater than 0 (and in [0,1)), then uniMEM chains with scores below (100\ - \ * X)% of the best chain score for a read, and read pairs with a sum of chain\ - \ scores below (100 * X)% of the best chain score for a read pair will be discounted\ - \ as a mapping candidates. The default value of this option is 0.35.\n" - info: null - example: - - 0.35 - required: false - min: 0.0 - max: 0.999999999 - direction: "input" - multiple: false - multiple_sep: ";" - - type: "double" - name: "--pre_merge_chain_sub_thresh" - description: "[selective-alignment mode only] \nThe threshold of sub-optimal chains,\ - \ compared to the best chain on a given target, that will be retained and passed\ - \ to the next phase of mapping. Specifically, if the best chain for a read (or\ - \ read-end in paired-end mode) to target t has score X_t, then all chains for\ - \ this read with score >= X_t * preMergeChainSubThresh will be retained and\ - \ passed to subsequent mapping phases. This value must be in the range [0,\ - \ 1].\n" - info: null - example: - - 0.75 - required: false - min: 0.0 - max: 1.0 - direction: "input" - multiple: false - multiple_sep: ";" - - type: "double" - name: "--post_merge_chain_sub_thresh" - description: "[selective-alignment mode only] \nThe threshold of sub-optimal chains,\ - \ compared to the best chain on a given target, that will be retained and passed\ - \ to the next phase of mapping. This is different than post_merge_chain_sub_thresh,\ - \ because this is applied to pairs of chains (from the ends of paired-end reads)\ - \ after merging (i.e. after checking concordancy constraints etc.). Specifically,\ - \ if the best chain pair to target t has score X_t, then all chain pairs for\ - \ this read pair with score >= X_t * post_merge_chain_sub_thresh will be retained\ - \ and passed to subsequent mapping phases. This value must be in the range [0,\ - \ 1]. Note: This option is only meaningful for paired-end libraries, and is\ - \ ignored for single-end libraries.\n" - info: null - example: - - 0.9 - required: false - min: 0.0 - max: 1.0 - direction: "input" - multiple: false - multiple_sep: ";" - - type: "double" - name: "--orphan_chain_sub_thresh" - description: "[selective-alignment mode only]\nThis threshold sets a global sub-optimality\ - \ threshold for chains corresponding to orphan mappings. That is, if the merging\ - \ procedure results in no concordant mappings then only orphan mappings with\ - \ a chain score >= orphan_chain_sub_thresh * bestChainScore will be retained\ - \ and passed to subsequent mapping phases. This value must be in the range [0,\ - \ 1]. Note: This option is only meaningful for paired-end libraries, and is\ - \ ignored for single-end libraries.\n" - info: null - example: - - 0.95 - required: false - min: 0.0 - max: 1.0 - direction: "input" - multiple: false - multiple_sep: ";" - - type: "double" - name: "--min_score_fraction" - description: "[selective-alignment mode only]\nThe fraction of the optimal possible\ - \ alignment score that a mapping must achieve in order to be considered \"valid\"\ - \ --- should be in (0,1]. Default 0.65\n" - info: null - example: - - 0.65 - required: false - min: 1.0E-9 - max: 1.0 - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--mismatch_seed_skip" - description: "[selective-alignment mode only]\nAfter a k-mer hit is extended to\ - \ a uni-MEM, the uni-MEM extension can terminate for one of 3 reasons; the end\ - \ of the read, the end of the unitig, or a mismatch. If the extension ends because\ - \ of a mismatch, this is likely the result of a sequencing error. To avoid looking\ - \ up many k-mers that will likely fail to be located in the index, the search\ - \ procedure skips by a factor of mismatch_seed_skip until it either (1) finds\ - \ another match or (2) is k-bases past the mismatch position. This value controls\ - \ that skip length. A smaller value can increase sensitivity, while a larger\ - \ value can speed up seeding.\n" - info: null - example: - - 3 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--disable_chaining_heuristic" - description: "[selective-alignment mode only] \nBy default, the heuristic of (Li\ - \ 2018) is implemented, which terminates the chaining DP once a given number\ - \ of valid backpointers are found. This speeds up the seed (MEM) chaining step,\ - \ but may result in sub-optimal chains in complex situations (e.g. sequences\ - \ with many repeats and overlapping repeats). Passing this flag will disable\ - \ the chaining heuristic, and perform the full chaining dynamic program, guaranteeing\ - \ the optimal chain is found in this step.\n" - info: null - direction: "input" - - type: "double" - name: "--decoy_threshold" - description: "[selective-alignment mode only]\nFor an alignemnt to an annotated\ - \ transcript to be considered invalid, it must have an alignment score < (decoy_threshold\ - \ * bestDecoyScore). A value of 1.0 means that any alignment strictly worse\ - \ than the best decoy alignment will be discarded. A smaller value will allow\ - \ reads to be allocated to transcripts even if they strictly align better to\ - \ the decoy sequence.\n" - info: null - example: - - 1.0 - required: false - min: 0.0 - max: 1.0 - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--ma" - description: "[selective-alignment mode only]\nThe value given to a match between\ - \ read and reference nucleotides in an alignment.\n" - info: null - example: - - 2 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--mp" - description: "[selective-alignment mode only]\nThe value given to a mis-match\ - \ between read and reference nucleotides in an alignment.\n" - info: null - example: - - -4 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--go" - description: "[selective-alignment mode only]\nThe value given to a gap opening\ - \ in an alignment.\n" - info: null - example: - - 6 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--ge" - description: "[selective-alignment mode only]\nThe value given to a gap extension\ - \ in an alignment.\n" - info: null - example: - - 2 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--bandwidth" - description: "[selective-alignment mode only]\nThe value used for the bandwidth\ - \ passed to ksw2. A smaller bandwidth can make the alignment verification run\ - \ more quickly, but could possibly miss valid alignments.\n" - info: null - example: - - 15 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--allow_dovetail" - description: "[selective-alignment mode only] \nAllow dovetailing mappings.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--recover_orphans" - description: "[selective-alignment mode only] \nAttempt to recover the mates of\ - \ orphaned reads. This uses edlib for orphan recovery, and so introduces some\ - \ computational overhead, but it can improve sensitivity.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--mimicBT2" - description: "[selective-alignment mode only] \nSet flags to mimic parameters\ - \ similar to Bowtie2 with --no-discordant and --no-mixed flags. This increases\ - \ disallows dovetailing reads, and discards orphans. Note, this does not impose\ - \ the very strict parameters assumed by RSEM+Bowtie2, like gapless alignments.\ - \ For that behavior, use the --mimic_strictBT2 flag below.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--mimic_strictBT2" - description: "[selective-alignment mode only] \nSet flags to mimic the very strict\ - \ parameters used by RSEM+Bowtie2. This increases --min_score_fraction to 0.8,\ - \ disallows dovetailing reads, discards orphans, and disallows gaps in alignments.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--softclip" - description: "[selective-alignment mode only] \nAllos soft-clipping of reads during\ - \ selective-alignment. If this option is provided, then regions at the beginning\ - \ or end of the read can be withheld from alignment without any effect on the\ - \ resulting score (i.e. neither adding nor removing from the score). This will\ - \ drastically reduce the penalty if there are mismatches at the beginning or\ - \ end of the read due to e.g. low-quality bases or adapters. NOTE: Even with\ - \ soft-clipping enabled, the read must still achieve a score of at least min_score_fraction\ - \ * maximum achievable score, where the maximum achievable score is computed\ - \ based on the full (un-clipped) read length.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--softclip_overhangs" - description: "[selective-alignment mode only] \nAllow soft-clipping of reads that\ - \ overhang the beginning or ends of the transcript. In this case, the overhaning\ - \ section of the read will simply be unaligned, and will not contribute or detract\ - \ from the alignment score. The default policy is to force an end-to-end alignment\ - \ of the entire read, so that overhanings will result in some deletion of nucleotides\ - \ from the read.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--full_length_alignment" - description: "[selective-alignment mode only] \nPerform selective alignment over\ - \ the full length of the read, beginning from the (approximate) initial mapping\ - \ location and using extension alignment. This is in contrast with the default\ - \ behavior which is to only perform alignment between the MEMs in the optimal\ - \ chain (and before the first and after the last MEM if applicable). The default\ - \ strategy forces the MEMs to belong to the alignment, but has the benefit that\ - \ it can discover indels prior to the first hit shared between the read and\ - \ reference. Except in very rare circumstances, the default mode should be more\ - \ accurate.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--hard_filter" - description: "[selective-alignment mode only] \nInstead of weighting mappings\ - \ by their alignment score, this flag will discard any mappings with sub-optimal\ - \ alignment score. The default option of soft-filtering (i.e. weighting mappings\ - \ by their alignment score) usually yields slightly more accurate abundance\ - \ estimates but this flag may be desirable if you want more accurate 'naive'\ - \ equivalence classes, rather than range factorized equivalence classes.\n" - info: null - direction: "input" - - type: "double" - name: "--min_aln_prob" - description: "The minimum number of fragments that must be assigned to the transcriptome\ - \ for quantification to proceed.\n" - info: null - example: - - 1.0E-5 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--write_mappings" - alternatives: - - "-z" - description: "If this option is provided, then the selective-alignment results\ - \ will be written out in SAM-compatible format. By default, output will be directed\ - \ to stdout, but an alternative file name can be provided instead.\n" - info: null - direction: "input" - - type: "file" - name: "--mapping_sam" - description: "Path to file that should output the selective-alignment results\ - \ in SAM-compatible format. THis option must be provided while using --write_mappings" - info: null - example: - - "mappings.sam" - must_exist: true - create_parent: true - required: false - direction: "output" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--write_qualities" - description: "This flag only has meaning if mappings are being written (with --write_mappings/-z).\ - \ If this flag is provided, then the output SAM file will contain quality strings\ - \ as well as read sequences. Note that this can greatly increase the size of\ - \ the output file.\n" - info: null - direction: "input" - - type: "string" - name: "--hit_filter_policy" - description: "[selective-alignment mode only]\nDetermines the policy by which\ - \ hits are filtered in selective alignment. Filtering hits after chaining (the\ - \ default) is more sensitive, but more computationally intensive, because it\ - \ performs the chaining dynamic program for all hits. Filtering before chaining\ - \ is faster, but some true hits may be missed. The options are BEFORE, AFTER,\ - \ BOTH and NONE.\n" - info: null - example: - - "AFTER" - required: false - choices: - - "BEFORE" - - "AFTER" - - "BOTH" - - "NONE" - direction: "input" - multiple: false - multiple_sep: ";" -- name: "Advance options" - arguments: - - type: "boolean_true" - name: "--alternative_init_mode" - description: "Use an alternative strategy (rather than simple interpolation between)\ - \ the online and uniform abundance estimates to initialize the EM / VBEM algorithm.\n" - info: null - direction: "input" - - type: "file" - name: "--aux_dir" - description: "The sub-directory of the quantification directory where auxiliary\ - \ information e.g. bootstraps, bias parameters, etc. will be written.\n" - info: null - example: - - "aux_info" - must_exist: true - create_parent: true - required: false - direction: "output" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--skip_quant" - description: "Skip performing the actual transcript quantification (including\ - \ any Gibbs sampling or bootstrapping).\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--dump_eq" - description: "Dump the simple equivalence class counts that were computed during\ - \ mapping or alignment.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--dump_eq_weights" - alternatives: - - "-d" - description: "Dump conditional probabilities associated with transcripts when\ - \ equivalence class information is being dumped to file. Note, this will dump\ - \ the factorization that is actually used by salmon's offline phase for inference.\ - \ If you are using range-factorized equivalence classes (the default) then the\ - \ same transcript set may appear multiple times with different associated conditional\ - \ probabilities.\n" - info: null - direction: "input" - - type: "integer" - name: "--min_assigned_frags" - description: "The minimum number of fragments that must be assigned to the transcriptome\ - \ for quantification to proceed.\n" - info: null - example: - - 10 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--reduce_GC_memory" - description: "If this option is selected, a more memory efficient (but slightly\ - \ slower) representation is used to compute fragment GC content. Enabling this\ - \ will reduce memory usage, but can also reduce speed. However, the results\ - \ themselves will remain the same.\n" - info: null - direction: "input" - - type: "integer" - name: "--bias_speed_samp" - description: "The value at which the fragment length PMF is down-sampled when\ - \ evaluating sequence-specific & GC fragment bias. Larger values speed up effective\ - \ length correction, but may decrease the fidelity of bias modeling results.\n" - info: null - example: - - 5 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--fld_max" - description: "The maximum fragment length to consider when building the empirical\ - \ distribution\n" - info: null - example: - - 1000 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--fld_mean" - description: "The mean used in the fragment length distribution prior\n" - info: null - example: - - 250 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--fld_SD" - description: "The standard deviation used in the fragment length distribution\ - \ prior\n" - info: null - example: - - 25 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "double" - name: "--forgetting_factor" - alternatives: - - "-f" - description: "The forgetting factor used in the online learning schedule. A smallervalue\ - \ results in quicker learning, but higher variance and may be unstable. A larger\ - \ value results in slower learning but may be more stable. Value should be\ - \ in the interval (0.5, 1.0].\n" - info: null - example: - - 0.65 - required: false - min: 0.500000001 - max: 1.0 - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--init_uniform" - description: "Initialize the offline inference with uniform parameters, rather\ - \ than seeding with online parameters.\n" - info: null - direction: "input" - - type: "integer" - name: "--max_occs_per_hit" - description: "When collecting \"hits\" (MEMs), hits having more than max_occs_per_hit\ - \ occurrences won't be considered.\n" - info: null - example: - - 1000 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--max_read_occ" - description: "Reads \"mapping\" to more than this many places won't be considered.\n" - info: null - example: - - 200 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--no_length_correction" - description: "Entirely disables length correction when estimating the abundance\ - \ of transcripts. This option can be used with protocols where one expects that\ - \ fragments derive from their underlying targets without regard to that target's\ - \ length (e.g. QuantSeq)\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--no_effective_length_correction" - description: "Disables effective length correction when computing the probability\ - \ that a fragment was generated from a transcript. If this flag is passed in,the\ - \ fragment length distribution is not taken into account when computing this\ - \ probability.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--no_single_frag_prob" - description: "Disables the estimation of an associated fragment length probability\ - \ for single-end reads or for orphaned mappings in paired-end libraries. The\ - \ default behavior is to consider the probability of all possible fragment\ - \ lengths associated with the retained mapping. Enabling this flag (i.e. turning\ - \ this default behavior off) will simply not attempt to estimate a fragment\ - \ length probability in such cases.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--no_frag_length_dist" - description: "Don't consider concordance with the learned fragment length distribution\ - \ when trying to determine the probability that a fragment has originated from\ - \ a specified location. Normally, Fragments with unlikely lengths will be assigned\ - \ a smaller relative probability than those with more likely lengths. When this\ - \ flag is passed in, the observed fragment length has no effect on that fragment's\ - \ a priori probability.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--no_bias_length_threshold" - description: "If this option is enabled, then no (lower) threshold will be set\ - \ on how short bias correction can make effective lengths. This can increase\ - \ the precision of bias correction, but harm robustness. The default correction\ - \ applies a threshold.\n" - info: null - direction: "input" - - type: "integer" - name: "--num_bias_samples" - description: "Number of fragment mappings to use when learning the sequence-specific\ - \ bias model.\n" - info: null - example: - - 2000000 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--num_aux_model_samples" - description: "The first are used to train the auxiliary\ - \ model parameters (e.g. fragment length distribution, bias, etc.). After ther\ - \ first observations the auxiliary model parameters\ - \ will be assumed to have converged and will be fixed.\n" - info: null - example: - - 5000000 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--num_pre_aux_model_samples" - description: "The first will have their assignment likelihoods\ - \ and contributions to the transcript abundances computed without applying any\ - \ auxiliary models. The purpose of ignoring the auxiliary models for the first\ - \ observations is to avoid applying these models\ - \ before their parameters have been learned sufficiently well.\n" - info: null - example: - - 5000 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--useEM" - description: "Use the traditional EM algorithm for optimization in the batch passes.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--useVBOpt" - description: "Use the Variational Bayesian EM [default]\n" - info: null - direction: "input" - - type: "integer" - name: "--range_factorization_bins" - description: "Factorizes the likelihood used in quantification by adopting a new\ - \ notion of equivalence classes based on the conditional probabilities with\ - \ which fragments are generated from different transcripts. This is a more fine-grained\ - \ factorization than the normal rich equivalence classes. The default value\ - \ (4) corresponds to the default used in Zakeri et al. 2017 (doi: 10.1093/bioinformatics/btx262),\ - \ and larger values imply a more fine-grained factorization. If range factorization\ - \ is enabled, a common value to select for this parameter is 4. A value of 0\ - \ signifies the use of basic rich equivalence classes.\n" - info: null - example: - - 4 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--num_Gibbs_samples" - description: "Number of Gibbs sampling rounds to perform.\n" - info: null - example: - - 0 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--no_Gamma_draw" - description: "This switch will disable drawing transcript fractions from a Gamma\ - \ distribution during Gibbs sampling. In this case the sampler does not account\ - \ for shot-noise, but only assignment ambiguity\n" - info: null - direction: "input" - - type: "integer" - name: "--num_bootstraps" - description: "Number of bootstrap samples to generate. Note: This is mutually\ - \ exclusive with Gibbs sampling.\n" - info: null - example: - - 0 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--bootstrap_reproject" - description: "This switch will learn the parameter distribution from the bootstrapped\ - \ counts for each sample, but will reproject those parameters onto the original\ - \ equivalence class counts.\n" - info: null - direction: "input" - - type: "integer" - name: "--thinning_factor" - description: "Number of steps to discard for every sample kept from the Gibbs\ - \ chain. The larger this number, the less chance that subsequent samples are\ - \ auto-correlated, but the slower sampling becomes.\n" - info: null - example: - - 16 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--quiet" - alternatives: - - "-q" - description: "Be quiet while doing quantification (don't write informative output\ - \ to the console unless something goes wrong).\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--per_transcript_prior" - description: "The prior (either the default or the argument provided via --vb_prior)\ - \ will be interpreted as a transcript-level prior (i.e. each transcript will\ - \ be given a prior read count of this value)\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--per_nucleotide_prior" - description: "The prior (either the default or the argument provided via --vb_prior)\ - \ will be interpreted as a nucleotide-level prior (i.e. each nucleotide will\ - \ be given a prior read count of this value)\n" - info: null - direction: "input" - - type: "integer" - name: "--sig_digits" - description: "The number of significant digits to write when outputting the EffectiveLength\ - \ and NumReads columns\n" - info: null - example: - - 3 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "double" - name: "--vb_prior" - description: "The prior that will be used in the VBEM algorithm. This is interpreted\ - \ as a per-transcript prior, unless the --per_nucleotide_prior flag is also\ - \ given. If the --per_nucleotide_prior flag is given, this is used as a nucleotide-level\ - \ prior. If the default is used, it will be divided by 1000 before being used\ - \ as a nucleotide-level prior, i.e. the default per-nucleotide prior will be\ - \ 1e-5.\n" - info: null - example: - - 0.01 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--write_orphan_links" - description: "Write the transcripts that are linked by orphaned reads.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--write_unmapped_names" - description: "Write the names of un-mapped reads to the file unmapped_names.txt\ - \ in the auxiliary directory.\n" - info: null - direction: "input" -- name: "Alignment-specific options" - arguments: - - type: "boolean_true" - name: "--no_error_model" - description: "Turn off the alignment error model, which takes into account the\ - \ the observed frequency of different types of mismatches / indels when computing\ - \ the likelihood of a given alignment. Turning this off can speed up alignment-based\ - \ salmon, but can harm quantification accuracy.\n" - info: null - direction: "input" - - type: "integer" - name: "--num_error_bins" - description: "The number of bins into which to divide each read when learning\ - \ and applying the error model. For example, a value of 10 would mean that\ - \ effectively, a separate error model is leared and applied to each 10th of\ - \ the read, while a value of 3 would mean that a separate error model is applied\ - \ to the read beginning (first third), middle (second third) and end (final\ - \ third).\n" - info: null - example: - - 6 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--sample_out" - alternatives: - - "-s" - description: "Write a \"postSample.bam\" file in the output directory that will\ - \ sample the input alignments according to the estimated transcript abundances.\ - \ If you're going to perform downstream analysis of the alignments with tools\ - \ which don't, themselves, take fragment assignment ambiguity into account,\ - \ you should use this output.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--sample_unaligned" - alternatives: - - "-u" - description: "In addition to sampling the aligned reads, also write the un-aligned\ - \ reads to \"postSample.bam\".\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--gencode" - description: "This flag will expect the input transcript fasta to be in GENCODE\ - \ format, and will split the transcript name at the first '|' character. These\ - \ reduced names will be used in the output and when looking for these transcripts\ - \ in a gene to transcript GTF.\n" - info: null - direction: "input" - - type: "integer" - name: "--mapping_cache_memory_limit" - description: "If the file contained fewer than this many mapped reads, then just\ - \ keep the data in memory for subsequent rounds of inference. Obviously, this\ - \ value should not be too large if you wish to keep a low memory usage, but\ - \ setting it large enough to accommodate all of the mapped read can substantially\ - \ speed up inference on \"small\" files that contain only a few million reads.\n" - info: null - example: - - 2000000 - required: false - direction: "input" - multiple: false - multiple_sep: ";" -resources: -- type: "bash_script" - path: "script.sh" - is_executable: true -description: "Salmon is a tool for wicked-fast transcript quantification from RNA-seq\ - \ data. It can either make use of pre-computed alignments (in the form of a SAM/BAM\ - \ file) to the transcripts rather than the raw reads, or can be run in the mapping-based\ - \ mode. \n" -test_resources: -- type: "bash_script" - path: "test.sh" - is_executable: true -info: null -status: "enabled" -requirements: - commands: - - "ps" -keywords: -- "Transcriptome" -- "Quantification" -license: "GPL-3.0" -references: - doi: - - "10.1038/nmeth.4197" -links: - repository: "https://github.com/COMBINE-lab/salmon" - homepage: "https://salmon.readthedocs.io/en/latest/salmon.html" - documentation: "https://salmon.readthedocs.io/en/latest/salmon.html" -runners: -- type: "executable" - id: "executable" - docker_setup_strategy: "ifneedbepullelsecachedbuild" -- type: "nextflow" - id: "nextflow" - directives: - tag: "$id" - auto: - simplifyInput: true - simplifyOutput: false - transcript: false - publish: false - config: - labels: - mem1gb: "memory = 1000000000.B" - mem2gb: "memory = 2000000000.B" - mem5gb: "memory = 5000000000.B" - mem10gb: "memory = 10000000000.B" - mem20gb: "memory = 20000000000.B" - mem50gb: "memory = 50000000000.B" - mem100gb: "memory = 100000000000.B" - mem200gb: "memory = 200000000000.B" - mem500gb: "memory = 500000000000.B" - mem1tb: "memory = 1000000000000.B" - mem2tb: "memory = 2000000000000.B" - mem5tb: "memory = 5000000000000.B" - mem10tb: "memory = 10000000000000.B" - mem20tb: "memory = 20000000000000.B" - mem50tb: "memory = 50000000000000.B" - mem100tb: "memory = 100000000000000.B" - mem200tb: "memory = 200000000000000.B" - mem500tb: "memory = 500000000000000.B" - mem1gib: "memory = 1073741824.B" - mem2gib: "memory = 2147483648.B" - mem4gib: "memory = 4294967296.B" - mem8gib: "memory = 8589934592.B" - mem16gib: "memory = 17179869184.B" - mem32gib: "memory = 34359738368.B" - mem64gib: "memory = 68719476736.B" - mem128gib: "memory = 137438953472.B" - mem256gib: "memory = 274877906944.B" - mem512gib: "memory = 549755813888.B" - mem1tib: "memory = 1099511627776.B" - mem2tib: "memory = 2199023255552.B" - mem4tib: "memory = 4398046511104.B" - mem8tib: "memory = 8796093022208.B" - mem16tib: "memory = 17592186044416.B" - mem32tib: "memory = 35184372088832.B" - mem64tib: "memory = 70368744177664.B" - mem128tib: "memory = 140737488355328.B" - mem256tib: "memory = 281474976710656.B" - mem512tib: "memory = 562949953421312.B" - cpu1: "cpus = 1" - cpu2: "cpus = 2" - cpu5: "cpus = 5" - cpu10: "cpus = 10" - cpu20: "cpus = 20" - cpu50: "cpus = 50" - cpu100: "cpus = 100" - cpu200: "cpus = 200" - cpu500: "cpus = 500" - cpu1000: "cpus = 1000" - debug: false - container: "docker" -engines: -- type: "docker" - id: "docker" - image: "quay.io/biocontainers/salmon:1.10.2--hecfa306_0" - target_registry: "images.viash-hub.com" - target_tag: "v0.1.0" - namespace_separator: "/" - setup: - - type: "docker" - run: - - "salmon index -v 2>&1 | sed 's/salmon \\([0-9.]*\\)/salmon: \\1/' > /var/software_versions.txt\n" - entrypoint: [] - cmd: null -- type: "native" - id: "native" -build_info: - config: "src/salmon/salmon_quant/config.vsh.yaml" - runner: "nextflow" - engine: "docker|native" - output: "target/nextflow/salmon/salmon_quant" - executable: "target/nextflow/salmon/salmon_quant/main.nf" - viash_version: "0.9.0-RC6" - git_commit: "b84b29747d0635f2ac83ea63b496be9a9edb6724" - git_remote: "https://github.com/viash-hub/biobox" -package_config: - name: "biobox" - version: "v0.1.0" - description: "A collection of bioinformatics tools for working with sequence data.\n" - info: null - viash_version: "0.9.0-RC6" - source: "src" - target: "target" - config_mods: - - ".requirements.commands := ['ps']\n" - - ".engines += { type: \"native\" }" - - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - keywords: - - "bioinformatics" - - "modules" - - "sequencing" - license: "MIT" - organization: "vsh" - links: - repository: "https://github.com/viash-hub/biobox" - issue_tracker: "https://github.com/viash-hub/biobox/issues" diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/main.nf b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/main.nf deleted file mode 100644 index 18765df..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/main.nf +++ /dev/null @@ -1,4693 +0,0 @@ -// salmon_quant v0.1.0 -// -// This wrapper script is auto-generated by viash 0.9.0-RC6 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. -// -// The component may contain files which fall under a different license. The -// authors of this component should specify the license in the header of such -// files, or include a separate license file detailing the licenses of all included -// files. - -//////////////////////////// -// VDSL3 helper functions // -//////////////////////////// - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_checkArgumentType.nf' -class UnexpectedArgumentTypeException extends Exception { - String errorIdentifier - String stage - String plainName - String expectedClass - String foundClass - - // ${key ? " in module '$key'" : ""}${id ? " id '$id'" : ""} - UnexpectedArgumentTypeException(String errorIdentifier, String stage, String plainName, String expectedClass, String foundClass) { - super("Error${errorIdentifier ? " $errorIdentifier" : ""}:${stage ? " $stage" : "" } argument '${plainName}' has the wrong type. " + - "Expected type: ${expectedClass}. Found type: ${foundClass}") - this.errorIdentifier = errorIdentifier - this.stage = stage - this.plainName = plainName - this.expectedClass = expectedClass - this.foundClass = foundClass - } -} - -/** - * Checks if the given value is of the expected type. If not, an exception is thrown. - * - * @param stage The stage of the argument (input or output) - * @param par The parameter definition - * @param value The value to check - * @param errorIdentifier The identifier to use in the error message - * @return The value, if it is of the expected type - * @throws UnexpectedArgumentTypeException If the value is not of the expected type -*/ -def _checkArgumentType(String stage, Map par, Object value, String errorIdentifier) { - // expectedClass will only be != null if value is not of the expected type - def expectedClass = null - def foundClass = null - - // todo: split if need be - - if (!par.required && value == null) { - expectedClass = null - } else if (par.multiple) { - if (value !instanceof Collection) { - value = [value] - } - - // split strings - value = value.collectMany{ val -> - if (val instanceof String) { - // collect() to ensure that the result is a List and not simply an array - val.split(par.multiple_sep).collect() - } else { - [val] - } - } - - // process globs - if (par.type == "file" && par.direction == "input") { - value = value.collect{ it instanceof String ? file(it, hidden: true) : it }.flatten() - } - - // check types of elements in list - try { - value = value.collect { listVal -> - _checkArgumentType(stage, par + [multiple: false], listVal, errorIdentifier) - } - } catch (UnexpectedArgumentTypeException e) { - expectedClass = "List[${e.expectedClass}]" - foundClass = "List[${e.foundClass}]" - } - } else if (par.type == "string") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else if (par.type == "integer") { - // cast to integer if need be - if (value instanceof String) { - try { - value = value.toInteger() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigInteger) { - value = value.intValue() - } - expectedClass = value instanceof Integer ? null : "Integer" - } else if (par.type == "long") { - // cast to long if need be - if (value instanceof String) { - try { - value = value.toLong() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof Integer) { - value = value.toLong() - } - expectedClass = value instanceof Long ? null : "Long" - } else if (par.type == "double") { - // cast to double if need be - if (value instanceof String) { - try { - value = value.toDouble() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigDecimal) { - value = value.doubleValue() - } - if (value instanceof Float) { - value = value.toDouble() - } - expectedClass = value instanceof Double ? null : "Double" - } else if (par.type == "boolean" | par.type == "boolean_true" | par.type == "boolean_false") { - // cast to boolean if need be - if (value instanceof String) { - def valueLower = value.toLowerCase() - if (valueLower == "true") { - value = true - } else if (valueLower == "false") { - value = false - } - } - expectedClass = value instanceof Boolean ? null : "Boolean" - } else if (par.type == "file" && (par.direction == "input" || stage == "output")) { - // cast to path if need be - if (value instanceof String) { - value = file(value, hidden: true) - } - if (value instanceof File) { - value = value.toPath() - } - expectedClass = value instanceof Path ? null : "Path" - } else if (par.type == "file" && stage == "input" && par.direction == "output") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else { - // didn't find a match for par.type - expectedClass = par.type - } - - if (expectedClass != null) { - if (foundClass == null) { - foundClass = value.getClass().getName() - } - throw new UnexpectedArgumentTypeException(errorIdentifier, stage, par.plainName, expectedClass, foundClass) - } - - return value -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processInputValues.nf' -Map _processInputValues(Map inputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.required) { - assert inputs.containsKey(arg.plainName) && inputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required input argument '${arg.plainName}' is missing" - } - } - - inputs = inputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid input argument" - - value = _checkArgumentType("input", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return inputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processOutputValues.nf' -Map _processOutputValues(Map outputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.direction == "output" && arg.required) { - assert outputs.containsKey(arg.plainName) && outputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required output argument '${arg.plainName}' is missing" - } - } - - outputs = outputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && it.direction == "output" } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid output argument" - - value = _checkArgumentType("output", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return outputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/IDChecker.nf' -class IDChecker { - final def items = [] as Set - - @groovy.transform.WithWriteLock - boolean observe(String item) { - if (items.contains(item)) { - return false - } else { - items << item - return true - } - } - - @groovy.transform.WithReadLock - boolean contains(String item) { - return items.contains(item) - } - - @groovy.transform.WithReadLock - Set getItems() { - return items.clone() - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_checkUniqueIds.nf' - -/** - * Check if the ids are unique across parameter sets - * - * @param parameterSets a list of parameter sets. - */ -private void _checkUniqueIds(List>> parameterSets) { - def ppIds = parameterSets.collect{it[0]} - assert ppIds.size() == ppIds.unique().size() : "All argument sets should have unique ids. Detected ids: $ppIds" -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_getChild.nf' - -// helper functions for reading params from file // -def _getChild(parent, child) { - if (child.contains("://") || java.nio.file.Paths.get(child).isAbsolute()) { - child - } else { - def parentAbsolute = java.nio.file.Paths.get(parent).toAbsolutePath().toString() - parentAbsolute.replaceAll('/[^/]*$', "/") + child - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_parseParamList.nf' -/** - * Figure out the param list format based on the file extension - * - * @param param_list A String containing the path to the parameter list file. - * - * @return A String containing the format of the parameter list file. - */ -def _paramListGuessFormat(param_list) { - if (param_list !instanceof String) { - "asis" - } else if (param_list.endsWith(".csv")) { - "csv" - } else if (param_list.endsWith(".json") || param_list.endsWith(".jsn")) { - "json" - } else if (param_list.endsWith(".yaml") || param_list.endsWith(".yml")) { - "yaml" - } else { - "yaml_blob" - } -} - - -/** - * Read the param list - * - * @param param_list One of the following: - * - A String containing the path to the parameter list file (csv, json or yaml), - * - A yaml blob of a list of maps (yaml_blob), - * - Or a groovy list of maps (asis). - * @param config A Map of the Viash configuration. - * - * @return A List of Maps containing the parameters. - */ -def _parseParamList(param_list, Map config) { - // first determine format by extension - def paramListFormat = _paramListGuessFormat(param_list) - - def paramListPath = (paramListFormat != "asis" && paramListFormat != "yaml_blob") ? - file(param_list, hidden: true) : - null - - // get the correct parser function for the detected params_list format - def paramSets = [] - if (paramListFormat == "asis") { - paramSets = param_list - } else if (paramListFormat == "yaml_blob") { - paramSets = readYamlBlob(param_list) - } else if (paramListFormat == "yaml") { - paramSets = readYaml(paramListPath) - } else if (paramListFormat == "json") { - paramSets = readJson(paramListPath) - } else if (paramListFormat == "csv") { - paramSets = readCsv(paramListPath) - } else { - error "Format of provided --param_list not recognised.\n" + - "Found: '$paramListFormat'.\n" + - "Expected: a csv file, a json file, a yaml file,\n" + - "a yaml blob or a groovy list of maps." - } - - // data checks - assert paramSets instanceof List: "--param_list should contain a list of maps" - for (value in paramSets) { - assert value instanceof Map: "--param_list should contain a list of maps" - } - - // id is argument - def idIsArgument = config.allArguments.any{it.plainName == "id"} - - // Reformat from List to List> by adding the ID as first element of a Tuple2 - paramSets = paramSets.collect({ data -> - def id = data.id - if (!idIsArgument) { - data = data.findAll{k, v -> k != "id"} - } - [id, data] - }) - - // Split parameters with 'multiple: true' - paramSets = paramSets.collect({ id, data -> - data = _splitParams(data, config) - [id, data] - }) - - // The paths of input files inside a param_list file may have been specified relatively to the - // location of the param_list file. These paths must be made absolute. - if (paramListPath) { - paramSets = paramSets.collect({ id, data -> - def new_data = data.collectEntries{ parName, parValue -> - def par = config.allArguments.find{it.plainName == parName} - if (par && par.type == "file" && par.direction == "input") { - if (parValue instanceof Collection) { - parValue = parValue.collectMany{path -> - def x = _resolveSiblingIfNotAbsolute(path, paramListPath) - x instanceof Collection ? x : [x] - } - } else { - parValue = _resolveSiblingIfNotAbsolute(parValue, paramListPath) - } - } - [parName, parValue] - } - [id, new_data] - }) - } - - return paramSets -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_splitParams.nf' -/** - * Split parameters for arguments that accept multiple values using their separator - * - * @param paramList A Map containing parameters to split. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A Map of parameters where the parameter values have been split into a list using - * their seperator. - */ -Map _splitParams(Map parValues, Map config){ - def parsedParamValues = parValues.collectEntries { parName, parValue -> - def parameterSettings = config.allArguments.find({it.plainName == parName}) - - if (!parameterSettings) { - // if argument is not found, do not alter - return [parName, parValue] - } - if (parameterSettings.multiple) { // Check if parameter can accept multiple values - if (parValue instanceof Collection) { - parValue = parValue.collect{it instanceof String ? it.split(parameterSettings.multiple_sep) : it } - } else if (parValue instanceof String) { - parValue = parValue.split(parameterSettings.multiple_sep) - } else if (parValue == null) { - parValue = [] - } else { - parValue = [ parValue ] - } - parValue = parValue.flatten() - } - // For all parameters check if multiple values are only passed for - // arguments that allow it. Quietly simplify lists of length 1. - if (!parameterSettings.multiple && parValue instanceof Collection) { - assert parValue.size() == 1 : - "Error: argument ${parName} has too many values.\n" + - " Expected amount: 1. Found: ${parValue.size()}" - parValue = parValue[0] - } - [parName, parValue] - } - return parsedParamValues -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/channelFromParams.nf' -/** - * Parse nextflow parameters based on settings defined in a viash config. - * Return a list of parameter sets, each parameter set corresponding to - * an event in a nextflow channel. The output from this function can be used - * with Channel.fromList to create a nextflow channel with Vdsl3 formatted - * events. - * - * This function performs: - * - A filtering of the params which can be found in the config file. - * - Process the params_list argument which allows a user to to initialise - * a Vsdl3 channel with multiple parameter sets. Possible formats are - * csv, json, yaml, or simply a yaml_blob. A csv should have column names - * which correspond to the different arguments of this pipeline. A json or a yaml - * file should be a list of maps, each of which has keys corresponding to the - * arguments of the pipeline. A yaml blob can also be passed directly as a parameter. - * When passing a csv, json or yaml, relative path names are relativized to the - * location of the parameter file. - * - Combine the parameter sets into a vdsl3 Channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A list of parameters with the first element of the event being - * the event ID and the second element containing a map of the parsed parameters. - */ - -private List>> _paramsToParamSets(Map params, Map config){ - // todo: fetch key from run args - def key_ = config.name - - /* parse regular parameters (not in param_list) */ - /*************************************************/ - def globalParams = config.allArguments - .findAll { params.containsKey(it.plainName) } - .collectEntries { [ it.plainName, params[it.plainName] ] } - def globalID = params.get("id", null) - - /* process params_list arguments */ - /*********************************/ - def paramList = params.containsKey("param_list") && params.param_list != null ? - params.param_list : [] - // if (paramList instanceof String) { - // paramList = [paramList] - // } - // def paramSets = paramList.collectMany{ _parseParamList(it, config) } - // TODO: be able to process param_list when it is a list of strings - def paramSets = _parseParamList(paramList, config) - if (paramSets.isEmpty()) { - paramSets = [[null, [:]]] - } - - /* combine arguments into channel */ - /**********************************/ - def processedParams = paramSets.indexed().collect{ index, tup -> - // Process ID - def id = tup[0] ?: globalID - - if (workflow.stubRun && !id) { - // if stub run, explicitly add an id if missing - id = "stub${index}" - } - assert id != null: "Each parameter set should have at least an 'id'" - - // Process params - def parValues = globalParams + tup[1] - // // Remove parameters which are null, if the default is also null - // parValues = parValues.collectEntries{paramName, paramValue -> - // parameterSettings = config.functionality.allArguments.find({it.plainName == paramName}) - // if ( paramValue != null || parameterSettings.get("default", null) != null ) { - // [paramName, paramValue] - // } - // } - parValues = parValues.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key_}' id '${id}': '${name}' is not a valid input argument" - - if (par == null) { - return [:] - } - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - - [ name, value ] - } - - [id, parValues] - } - - // Check if ids (first element of each list) is unique - _checkUniqueIds(processedParams) - return processedParams -} - -/** - * Parse nextflow parameters based on settings defined in a viash config - * and return a nextflow channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A nextflow Channel with events. Events are formatted as a tuple that contains - * first contains the ID of the event and as second element holds a parameter map. - * - * - */ -def channelFromParams(Map params, Map config) { - def processedParams = _paramsToParamSets(params, config) - return Channel.fromList(processedParams) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/checkUniqueIds.nf' -def checkUniqueIds(Map args) { - def stopOnError = args.stopOnError == null ? args.stopOnError : true - - def idChecker = new IDChecker() - - return filter { tup -> - if (!idChecker.observe(tup[0])) { - if (stopOnError) { - error "Duplicate id: ${tup[0]}" - } else { - log.warn "Duplicate id: ${tup[0]}, removing duplicate entry" - return false - } - } - return true - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/preprocessInputs.nf' -// This helper file will be deprecated soon -preprocessInputsDeprecationWarningPrinted = false - -def preprocessInputsDeprecationWarning() { - if (!preprocessInputsDeprecationWarningPrinted) { - preprocessInputsDeprecationWarningPrinted = true - System.err.println("Warning: preprocessInputs() is deprecated and will be removed in Viash 0.9.0.") - } -} - -/** - * Generate a nextflow Workflow that allows processing a channel of - * Vdsl3 formatted events and apply a Viash config to them: - * - Gather default parameters from the Viash config and make - * sure that they are correctly formatted (see applyConfig method). - * - Format the input parameters (also using the applyConfig method). - * - Apply the default parameter to the input parameters. - * - Do some assertions: - * ~ Check if the event IDs in the channel are unique. - * - * The events in the channel are formatted as tuples, with the - * first element of the tuples being a unique id of the parameter set, - * and the second element containg the the parameters themselves. - * Optional extra elements of the tuples will be passed to the output as is. - * - * @param args A map that must contain a 'config' key that points - * to a parsed config (see readConfig()). Optionally, a - * 'key' key can be provided which can be used to create a unique - * name for the workflow process. - * - * @return A workflow that allows processing a channel of Vdsl3 formatted events - * and apply a Viash config to them. - */ -def preprocessInputs(Map args) { - preprocessInputsDeprecationWarning() - - def config = args.config - assert config instanceof Map : - "Error in preprocessInputs: config must be a map. " + - "Expected class: Map. Found: config.getClass() is ${config.getClass()}" - def key_ = args.key ?: config.name - - // Get different parameter types (used throughout this function) - def defaultArgs = config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - map { tup -> - def id = tup[0] - def data = tup[1] - def passthrough = tup.drop(2) - - def new_data = (defaultArgs + data).collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - - if (par != null) { - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - } - - [ name, value ] - } - - [ id, new_data ] + passthrough - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runComponents.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component config. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component config. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component config. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component config. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runComponents(Map args) { - log.warn("runComponents is deprecated, use runEach instead") - assert args.components: "runComponents should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runComponents" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runComponentsWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def comp_config = comp_.config - - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_config) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - // def new_id = id_(tup[0], tup[1], comp_config) - def new_id = tup[0] - if (id_ instanceof String) { - new_id = id_ - } else if (id_ instanceof Closure) { - new_id = id_(new_id, tup[1], comp_config) - } - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_config) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_config) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runComponentsWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runEach.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component itself. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component itself. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component itself. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component itself. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runEach(Map args) { - assert args.components: "runEach should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runEach" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runEachWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - def new_id = id_ - if (new_id instanceof Closure) { - new_id = new_id(tup[0], tup[1], comp_) - } - assert new_id instanceof String : "Error in runEach: id should be a String or a Closure that returns a String. Expected: id instanceof String. Found: ${new_id.getClass()}" - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runEachWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/safeJoin.nf' -/** - * Join sourceChannel to targetChannel - * - * This function joins the sourceChannel to the targetChannel. - * However, each id in the targetChannel must be present in the - * sourceChannel. If _meta.join_id exists in the targetChannel, that is - * used as an id instead. If the id doesn't match any id in the sourceChannel, - * an error is thrown. - */ - -def safeJoin(targetChannel, sourceChannel, key) { - def sourceIDs = new IDChecker() - - def sourceCheck = sourceChannel - | map { tup -> - sourceIDs.observe(tup[0]) - tup - } - def targetCheck = targetChannel - | map { tup -> - def id = tup[0] - - if (!sourceIDs.contains(id)) { - error ( - "Error in module '${key}' when merging output with original state.\n" + - " Reason: output with id '${id}' could not be joined with source channel.\n" + - " If the IDs in the output channel differ from the input channel,\n" + - " please set `tup[1]._meta.join_id to the original ID.\n" + - " Original IDs in input channel: ['${sourceIDs.getItems().join("', '")}'].\n" + - " Unexpected ID in the output channel: '${id}'.\n" + - " Example input event: [\"id\", [input: file(...)]],\n" + - " Example output event: [\"newid\", [output: file(...), _meta: [join_id: \"id\"]]]" - ) - } - // TODO: add link to our documentation on how to fix this - - tup - } - - sourceCheck.cross(targetChannel) - | map{ left, right -> - right + left.drop(1) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/_processArgument.nf' -def _processArgument(arg) { - arg.multiple = arg.multiple != null ? arg.multiple : false - arg.required = arg.required != null ? arg.required : false - arg.direction = arg.direction != null ? arg.direction : "input" - arg.multiple_sep = arg.multiple_sep != null ? arg.multiple_sep : ";" - arg.plainName = arg.name.replaceAll("^-*", "") - - if (arg.type == "file") { - arg.must_exist = arg.must_exist != null ? arg.must_exist : true - arg.create_parent = arg.create_parent != null ? arg.create_parent : true - } - - // add default values to output files which haven't already got a default - if (arg.type == "file" && arg.direction == "output" && arg.default == null) { - def mult = arg.multiple ? "_*" : "" - def extSearch = "" - if (arg.default != null) { - extSearch = arg.default - } else if (arg.example != null) { - extSearch = arg.example - } - if (extSearch instanceof List) { - extSearch = extSearch[0] - } - def extSearchResult = extSearch.find("\\.[^\\.]+\$") - def ext = extSearchResult != null ? extSearchResult : "" - arg.default = "\$id.\$key.${arg.plainName}${mult}${ext}" - if (arg.multiple) { - arg.default = [arg.default] - } - } - - if (!arg.multiple) { - if (arg.default != null && arg.default instanceof List) { - arg.default = arg.default[0] - } - if (arg.example != null && arg.example instanceof List) { - arg.example = arg.example[0] - } - } - - if (arg.type == "boolean_true") { - arg.default = false - } - if (arg.type == "boolean_false") { - arg.default = true - } - - arg -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/addGlobalParams.nf' -def addGlobalArguments(config) { - def localConfig = [ - "argument_groups": [ - [ - "name": "Nextflow input-output arguments", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "arguments" : [ - [ - 'name': '--publish_dir', - 'required': true, - 'type': 'string', - 'description': 'Path to an output directory.', - 'example': 'output/', - 'multiple': false - ], - [ - 'name': '--param_list', - 'required': false, - 'type': 'string', - 'description': '''Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob. - | - |* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ ['id': 'foo', 'input': 'foo.txt'], ['id': 'bar', 'input': 'bar.txt'] ]`. - |* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`. - |* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]`. - |* A yaml blob can also be passed directly as a string. Example: `--param_list "[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]"`. - | - |When passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.'''.stripMargin(), - 'example': 'my_params.yaml', - 'multiple': false, - 'hidden': true - ] - // TODO: allow multiple: true in param_list? - // TODO: allow to specify a --param_list_regex to filter the param_list? - // TODO: allow to specify a --param_list_from_state to remap entries in the param_list? - ] - ] - ] - ] - - return processConfig(_mergeMap(config, localConfig)) -} - -def _mergeMap(Map lhs, Map rhs) { - return rhs.inject(lhs.clone()) { map, entry -> - if (map[entry.key] instanceof Map && entry.value instanceof Map) { - map[entry.key] = _mergeMap(map[entry.key], entry.value) - } else if (map[entry.key] instanceof Collection && entry.value instanceof Collection) { - map[entry.key] += entry.value - } else { - map[entry.key] = entry.value - } - return map - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/generateHelp.nf' -def _generateArgumentHelp(param) { - // alternatives are not supported - // def names = param.alternatives ::: List(param.name) - - def unnamedProps = [ - ["required parameter", param.required], - ["multiple values allowed", param.multiple], - ["output", param.direction.toLowerCase() == "output"], - ["file must exist", param.type == "file" && param.must_exist] - ].findAll{it[1]}.collect{it[0]} - - def dflt = null - if (param.default != null) { - if (param.default instanceof List) { - dflt = param.default.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - dflt = param.default.toString() - } - } - def example = null - if (param.example != null) { - if (param.example instanceof List) { - example = param.example.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - example = param.example.toString() - } - } - def min = param.min?.toString() - def max = param.max?.toString() - - def escapeChoice = { choice -> - def s1 = choice.replaceAll("\\n", "\\\\n") - def s2 = s1.replaceAll("\"", """\\\"""") - s2.contains(",") || s2 != choice ? "\"" + s2 + "\"" : s2 - } - def choices = param.choices == null ? - null : - "[ " + param.choices.collect{escapeChoice(it.toString())}.join(", ") + " ]" - - def namedPropsStr = [ - ["type", ([param.type] + unnamedProps).join(", ")], - ["default", dflt], - ["example", example], - ["choices", choices], - ["min", min], - ["max", max] - ] - .findAll{it[1]} - .collect{"\n " + it[0] + ": " + it[1].replaceAll("\n", "\\n")} - .join("") - - def descStr = param.description == null ? - "" : - _paragraphWrap("\n" + param.description.trim(), 80 - 8).join("\n ") - - "\n --" + param.plainName + - namedPropsStr + - descStr -} - -// Based on Helper.generateHelp() in Helper.scala -def _generateHelp(config) { - def fun = config - - // PART 1: NAME AND VERSION - def nameStr = fun.name + - (fun.version == null ? "" : " " + fun.version) - - // PART 2: DESCRIPTION - def descrStr = fun.description == null ? - "" : - "\n\n" + _paragraphWrap(fun.description.trim(), 80).join("\n") - - // PART 3: Usage - def usageStr = fun.usage == null ? - "" : - "\n\nUsage:\n" + fun.usage.trim() - - // PART 4: Options - def argGroupStrs = fun.allArgumentGroups.collect{argGroup -> - def name = argGroup.name - def descriptionStr = argGroup.description == null ? - "" : - "\n " + _paragraphWrap(argGroup.description.trim(), 80-4).join("\n ") + "\n" - def arguments = argGroup.arguments.collect{arg -> - arg instanceof String ? fun.allArguments.find{it.plainName == arg} : arg - }.findAll{it != null} - def argumentStrs = arguments.collect{param -> _generateArgumentHelp(param)} - - "\n\n$name:" + - descriptionStr + - argumentStrs.join("\n") - } - - // FINAL: combine - def out = nameStr + - descrStr + - usageStr + - argGroupStrs.join("") - - return out -} - -// based on Format._paragraphWrap -def _paragraphWrap(str, maxLength) { - def outLines = [] - str.split("\n").each{par -> - def words = par.split("\\s").toList() - - def word = null - def line = words.pop() - while(!words.isEmpty()) { - word = words.pop() - if (line.length() + word.length() + 1 <= maxLength) { - line = line + " " + word - } else { - outLines.add(line) - line = word - } - } - if (words.isEmpty()) { - outLines.add(line) - } - } - return outLines -} - -def helpMessage(config) { - if (params.containsKey("help") && params.help) { - def mergedConfig = addGlobalArguments(config) - def helpStr = _generateHelp(mergedConfig) - println(helpStr) - exit 0 - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/processConfig.nf' -def processConfig(config) { - // set defaults for arguments - config.arguments = - (config.arguments ?: []).collect{_processArgument(it)} - - // set defaults for argument_group arguments - config.argument_groups = - (config.argument_groups ?: []).collect{grp -> - grp.arguments = (grp.arguments ?: []).collect{_processArgument(it)} - grp - } - - // create combined arguments list - config.allArguments = - config.arguments + - config.argument_groups.collectMany{it.arguments} - - // add missing argument groups (based on Functionality::allArgumentGroups()) - def argGroups = config.argument_groups - if (argGroups.any{it.name.toLowerCase() == "arguments"}) { - argGroups = argGroups.collect{ grp -> - if (grp.name.toLowerCase() == "arguments") { - grp = grp + [ - arguments: grp.arguments + config.arguments - ] - } - grp - } - } else { - argGroups = argGroups + [ - name: "Arguments", - arguments: config.arguments - ] - } - config.allArgumentGroups = argGroups - - config -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/readConfig.nf' - -def readConfig(file) { - def config = readYaml(file ?: moduleDir.resolve("config.vsh.yaml")) - processConfig(config) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_resolveSiblingIfNotAbsolute.nf' -/** - * Resolve a path relative to the current file. - * - * @param str The path to resolve, as a String. - * @param parentPath The path to resolve relative to, as a Path. - * - * @return The path that may have been resovled, as a Path. - */ -def _resolveSiblingIfNotAbsolute(str, parentPath) { - if (str !instanceof String) { - return str - } - if (!_stringIsAbsolutePath(str)) { - return parentPath.resolveSibling(str) - } else { - return file(str, hidden: true) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_stringIsAbsolutePath.nf' -/** - * Check whether a path as a string is absolute. - * - * In the past, we tried using `file(., relative: true).isAbsolute()`, - * but the 'relative' option was added in 22.10.0. - * - * @param path The path to check, as a String. - * - * @return Whether the path is absolute, as a boolean. - */ -def _stringIsAbsolutePath(path) { - def _resolve_URL_PROTOCOL = ~/^([a-zA-Z][a-zA-Z0-9]*:)?\\/.+/ - - assert path instanceof String - return _resolve_URL_PROTOCOL.matcher(path).matches() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/collectTraces.nf' -class CustomTraceObserver implements nextflow.trace.TraceObserver { - List traces - - CustomTraceObserver(List traces) { - this.traces = traces - } - - @Override - void onProcessComplete(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } - - @Override - void onProcessCached(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } -} - -def collectTraces() { - def traces = Collections.synchronizedList([]) - - // add custom trace observer which stores traces in the traces object - session.observers.add(new CustomTraceObserver(traces)) - - traces -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/deepClone.nf' -/** - * Performs a deep clone of the given object. - * @param x an object - */ -def deepClone(x) { - iterateMap(x, {it instanceof Cloneable ? it.clone() : it}) -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getPublishDir.nf' -def getPublishDir() { - return params.containsKey("publish_dir") ? params.publish_dir : - params.containsKey("publishDir") ? params.publishDir : - null -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getRootDir.nf' - -// Recurse upwards until we find a '.build.yaml' file -def _findBuildYamlFile(pathPossiblySymlink) { - def path = pathPossiblySymlink.toRealPath() - def child = path.resolve(".build.yaml") - if (java.nio.file.Files.isDirectory(path) && java.nio.file.Files.exists(child)) { - return child - } else { - def parent = path.getParent() - if (parent == null) { - return null - } else { - return _findBuildYamlFile(parent) - } - } -} - -// get the root of the target folder -def getRootDir() { - def dir = _findBuildYamlFile(meta.resources_dir) - assert dir != null: "Could not find .build.yaml in the folder structure" - dir.getParent() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/iterateMap.nf' -/** - * Recursively apply a function over the leaves of an object. - * @param obj The object to iterate over. - * @param fun The function to apply to each value. - * @return The object with the function applied to each value. - */ -def iterateMap(obj, fun) { - if (obj instanceof List && obj !instanceof String) { - return obj.collect{item -> - iterateMap(item, fun) - } - } else if (obj instanceof Map) { - return obj.collectEntries{key, item -> - [key.toString(), iterateMap(item, fun)] - } - } else { - return fun(obj) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/niceView.nf' -/** - * A view for printing the event of each channel as a YAML blob. - * This is useful for debugging. - */ -def niceView() { - workflow niceViewWf { - take: input - main: - output = input - | view{toYamlBlob(it)} - emit: output - } - return niceViewWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readCsv.nf' - -def readCsv(file_path) { - def output = [] - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - - // todo: allow escaped quotes in string - // todo: allow single quotes? - def splitRegex = java.util.regex.Pattern.compile(''',(?=(?:[^"]*"[^"]*")*[^"]*$)''') - def removeQuote = java.util.regex.Pattern.compile('''"(.*)"''') - - def br = java.nio.file.Files.newBufferedReader(inputFile) - - def row = -1 - def header = null - while (br.ready() && header == null) { - def line = br.readLine() - row++ - if (!line.startsWith("#")) { - header = splitRegex.split(line, -1).collect{field -> - m = removeQuote.matcher(field) - m.find() ? m.replaceFirst('$1') : field - } - } - } - assert header != null: "CSV file should contain a header" - - while (br.ready()) { - def line = br.readLine() - row++ - if (line == null) { - br.close() - break - } - - if (!line.startsWith("#")) { - def predata = splitRegex.split(line, -1) - def data = predata.collect{field -> - if (field == "") { - return null - } - def m = removeQuote.matcher(field) - if (m.find()) { - return m.replaceFirst('$1') - } else { - return field - } - } - assert header.size() == data.size(): "Row $row should contain the same number as fields as the header" - - def dataMap = [header, data].transpose().collectEntries().findAll{it.value != null} - output.add(dataMap) - } - } - - output -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJson.nf' -def readJson(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parse(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJsonBlob.nf' -def readJsonBlob(str) { - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parseText(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readTaggedYaml.nf' -// Custom constructor to modify how certain objects are parsed from YAML -class CustomConstructor extends org.yaml.snakeyaml.constructor.Constructor { - Path root - - class ConstructPath extends org.yaml.snakeyaml.constructor.AbstractConstruct { - public Object construct(org.yaml.snakeyaml.nodes.Node node) { - String filename = (String) constructScalar(node); - if (root != null) { - return root.resolve(filename); - } - return java.nio.file.Paths.get(filename); - } - } - - CustomConstructor(org.yaml.snakeyaml.LoaderOptions options, Path root) { - super(options) - this.root = root - // Handling !file tag and parse it back to a File type - this.yamlConstructors.put(new org.yaml.snakeyaml.nodes.Tag("!file"), new ConstructPath()) - } -} - -def readTaggedYaml(Path path) { - def options = new org.yaml.snakeyaml.LoaderOptions() - def constructor = new CustomConstructor(options, path.getParent()) - def yaml = new org.yaml.snakeyaml.Yaml(constructor) - return yaml.load(path.text) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYaml.nf' -def readYaml(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYamlBlob.nf' -def readYamlBlob(str) { - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toJsonBlob.nf' -String toJsonBlob(data) { - return groovy.json.JsonOutput.toJson(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toTaggedYamlBlob.nf' -// Custom representer to modify how certain objects are represented in YAML -class CustomRepresenter extends org.yaml.snakeyaml.representer.Representer { - Path relativizer - - class RepresentPath implements org.yaml.snakeyaml.representer.Represent { - public String getFileName(Object obj) { - if (obj instanceof File) { - obj = ((File) obj).toPath(); - } - if (obj !instanceof Path) { - throw new IllegalArgumentException("Object: " + obj + " is not a Path or File"); - } - def path = (Path) obj; - - if (relativizer != null) { - return relativizer.relativize(path).toString() - } else { - return path.toString() - } - } - - public org.yaml.snakeyaml.nodes.Node representData(Object data) { - String filename = getFileName(data); - def tag = new org.yaml.snakeyaml.nodes.Tag("!file"); - return representScalar(tag, filename); - } - } - CustomRepresenter(org.yaml.snakeyaml.DumperOptions options, Path relativizer) { - super(options) - this.relativizer = relativizer - this.representers.put(sun.nio.fs.UnixPath, new RepresentPath()) - this.representers.put(Path, new RepresentPath()) - this.representers.put(File, new RepresentPath()) - } -} - -String toTaggedYamlBlob(data) { - return toRelativeTaggedYamlBlob(data, null) -} -String toRelativeTaggedYamlBlob(data, Path relativizer) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - def representer = new CustomRepresenter(options, relativizer) - def yaml = new org.yaml.snakeyaml.Yaml(representer, options) - return yaml.dump(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toYamlBlob.nf' -String toYamlBlob(data) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - options.setPrettyFlow(true) - def yaml = new org.yaml.snakeyaml.Yaml(options) - def cleanData = iterateMap(data, { it instanceof Path ? it.toString() : it }) - return yaml.dump(cleanData) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeJson.nf' -void writeJson(data, file) { - assert data: "writeJson: data should not be null" - assert file: "writeJson: file should not be null" - file.write(toJsonBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeYaml.nf' -void writeYaml(data, file) { - assert data: "writeYaml: data should not be null" - assert file: "writeYaml: file should not be null" - file.write(toYamlBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/findStates.nf' -def findStates(Map params, Map config) { - def auto_config = deepClone(config) - def auto_params = deepClone(params) - - auto_config = auto_config.clone() - // override arguments - auto_config.argument_groups = [] - auto_config.arguments = [ - [ - type: "string", - name: "--id", - description: "A dummy identifier", - required: false - ], - [ - type: "file", - name: "--input_states", - example: "/path/to/input/directory/**/state.yaml", - description: "Path to input directory containing the datasets to be integrated.", - required: true, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--filter", - example: "foo/.*/state.yaml", - description: "Regex to filter state files by path.", - required: false - ], - // to do: make this a yaml blob? - [ - type: "string", - name: "--rename_keys", - example: ["newKey1:oldKey1", "newKey2:oldKey2"], - description: "Rename keys in the detected input files. This is useful if the input files do not match the set of input arguments of the workflow.", - required: false, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--settings", - example: '{"output_dataset": "dataset.h5ad", "k": 10}', - description: "Global arguments as a JSON glob to be passed to all components.", - required: false - ] - ] - if (!(auto_params.containsKey("id"))) { - auto_params["id"] = "auto" - } - - // run auto config through processConfig once more - auto_config = processConfig(auto_config) - - workflow findStatesWf { - helpMessage(auto_config) - - output_ch = - channelFromParams(auto_params, auto_config) - | flatMap { autoId, args -> - - def globalSettings = args.settings ? readYamlBlob(args.settings) : [:] - - // look for state files in input dir - def stateFiles = args.input_states - - // filter state files by regex - if (args.filter) { - stateFiles = stateFiles.findAll{ stateFile -> - def stateFileStr = stateFile.toString() - def matcher = stateFileStr =~ args.filter - matcher.matches()} - } - - // read in states - def states = stateFiles.collect { stateFile -> - def state_ = readTaggedYaml(stateFile) - [state_.id, state_] - } - - // construct renameMap - if (args.rename_keys) { - def renameMap = args.rename_keys.collectEntries{renameString -> - def split = renameString.split(";") - assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey,newKey:oldKey'" - split - } - - // rename keys in state, only let states through which have all keys - // also add global settings - states = states.collectMany{id, state -> - def newState = [:] - - for (key in renameMap.keySet()) { - def origKey = renameMap[key] - if (!(state.containsKey(origKey))) { - return [] - } - newState[key] = state[origKey] - } - - [[id, globalSettings + newState]] - } - } - - states - } - emit: - output_ch - } - - return findStatesWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/joinStates.nf' -def joinStates(Closure apply_) { - workflow joinStatesWf { - take: input_ch - main: - output_ch = input_ch - | toSortedList - | filter{ it.size() > 0 } - | map{ tups -> - def ids = tups.collect{it[0]} - def states = tups.collect{it[1]} - apply_(ids, states) - } - - emit: output_ch - } - return joinStatesWf -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/publishStates.nf' -def collectFiles(obj) { - if (obj instanceof java.io.File || obj instanceof Path) { - return [obj] - } else if (obj instanceof List && obj !instanceof String) { - return obj.collectMany{item -> - collectFiles(item) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectFiles(item) - } - } else { - return [] - } -} - -/** - * Recurse through a state and collect all input files and their target output filenames. - * @param obj The state to recurse through. - * @param prefix The prefix to prepend to the output filenames. - */ -def collectInputOutputPaths(obj, prefix) { - if (obj instanceof File || obj instanceof Path) { - def path = obj instanceof Path ? obj : obj.toPath() - def ext = path.getFileName().toString().find("\\.[^\\.]+\$") ?: "" - def newFilename = prefix + ext - return [[obj, newFilename]] - } else if (obj instanceof List && obj !instanceof String) { - return obj.withIndex().collectMany{item, ix -> - collectInputOutputPaths(item, prefix + "_" + ix) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectInputOutputPaths(item, prefix + "." + key) - } - } else { - return [] - } -} - -def publishStates(Map args) { - def key_ = args.get("key") - def yamlTemplate_ = args.get("output_state", args.get("outputState", '$id.$key.state.yaml')) - - assert key_ != null : "publishStates: key must be specified" - - workflow publishStatesWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] - - // the input files and the target output filenames - def inputoutputFilenames_ = collectInputOutputPaths(state_, id_ + "." + key_).transpose() - def inputFiles_ = inputoutputFilenames_[0] - def outputFilenames_ = inputoutputFilenames_[1] - - def yamlFilename = yamlTemplate_ - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - - // TODO: do the pathnames in state_ match up with the outputFilenames_? - - // convert state to yaml blob - def yamlBlob_ = toRelativeTaggedYamlBlob([id: id_] + state_, java.nio.file.Paths.get(yamlFilename)) - - [id_, yamlBlob_, yamlFilename, inputFiles_, outputFilenames_] - } - | publishStatesProc - emit: input_ch - } - return publishStatesWf -} -process publishStatesProc { - // todo: check publishpath? - publishDir path: "${getPublishDir()}/", mode: "copy" - tag "$id" - input: - tuple val(id), val(yamlBlob), val(yamlFile), path(inputFiles, stageAs: "_inputfile?/*"), val(outputFiles) - output: - tuple val(id), path{[yamlFile] + outputFiles} - script: - def copyCommands = [ - inputFiles instanceof List ? inputFiles : [inputFiles], - outputFiles instanceof List ? outputFiles : [outputFiles] - ] - .transpose() - .collectMany{infile, outfile -> - if (infile.toString() != outfile.toString()) { - [ - "[ -d \"\$(dirname '${outfile.toString()}')\" ] || mkdir -p \"\$(dirname '${outfile.toString()}')\"", - "cp -r '${infile.toString()}' '${outfile.toString()}'" - ] - } else { - // no need to copy if infile is the same as outfile - [] - } - } - """ -mkdir -p "\$(dirname '${yamlFile}')" -echo "Storing state as yaml" -echo '${yamlBlob}' > '${yamlFile}' -echo "Copying output files to destination folder" -${copyCommands.join("\n ")} -""" -} - - -// this assumes that the state contains no other values other than those specified in the config -def publishStatesByConfig(Map args) { - def config = args.get("config") - assert config != null : "publishStatesByConfig: config must be specified" - - def key_ = args.get("key", config.name) - assert key_ != null : "publishStatesByConfig: key must be specified" - - workflow publishStatesSimpleWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] // e.g. [output: new File("myoutput.h5ad"), k: 10] - def origState_ = tup[2] // e.g. [output: '$id.$key.foo.h5ad'] - - // TODO: allow overriding the state.yaml template - // TODO TODO: if auto.publish == "state", add output_state as an argument - def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' - def yamlFilename = yamlTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() - - // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where - // - key is a String - // - value is any object that can be serialized to a Yaml (so a String/Integer/Long/Double/Boolean, a List, a Map, or a Path) - // - inputPath is a List[Path] - // - outputFilename is a List[String] - // - (key, value) are the tuples that will be saved to the state.yaml file - // - (inputPath, outputFilename) are the files that will be copied from src to dest (relative to the state.yaml) - def processedState = - config.allArguments - .findAll { it.direction == "output" } - .collectMany { par -> - def plainName_ = par.plainName - // if the state does not contain the key, it's an - // optional argument for which the component did - // not generate any output - if (!state_.containsKey(plainName_)) { - return [] - } - def value = state_[plainName_] - // if the parameter is not a file, it should be stored - // in the state as-is, but is not something that needs - // to be copied from the source path to the dest path - if (par.type != "file") { - return [[key: plainName_, value: value, inputPath: [], outputFilename: []]] - } - // if the orig state does not contain this filename, - // it's an optional argument for which the user specified - // that it should not be returned as a state - if (!origState_.containsKey(plainName_)) { - return [] - } - def filenameTemplate = origState_[plainName_] - // if the pararameter is multiple: true, fetch the template - if (par.multiple && filenameTemplate instanceof List) { - filenameTemplate = filenameTemplate[0] - } - // instantiate the template - def filename = filenameTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - if (par.multiple) { - // if the parameter is multiple: true, the filename - // should contain a wildcard '*' that is replaced with - // the index of the file - assert filename.contains("*") : "Module '${key_}' id '${id_}': Multiple output files specified, but no wildcard '*' in the filename: ${filename}" - def outputPerFile = value.withIndex().collect{ val, ix -> - def filename_ix = filename.replace("*", ix.toString()) - def value_ = java.nio.file.Paths.get(filename_ix) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = val instanceof File ? val.toPath() : val - [value: value_, inputPath: inputPath, outputFilename: filename_ix] - } - def transposedOutputs = ["value", "inputPath", "outputFilename"].collectEntries{ key -> - [key, outputPerFile.collect{dic -> dic[key]}] - } - return [[key: plainName_] + transposedOutputs] - } else { - def value_ = java.nio.file.Paths.get(filename) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = value instanceof File ? value.toPath() : value - return [[key: plainName_, value: value_, inputPath: [inputPath], outputFilename: [filename]]] - } - } - - def updatedState_ = processedState.collectEntries{[it.key, it.value]} - def inputPaths = processedState.collectMany{it.inputPath} - def outputFilenames = processedState.collectMany{it.outputFilename} - - // convert state to yaml blob - def yamlBlob_ = toTaggedYamlBlob([id: id_] + updatedState_) - - [id_, yamlBlob_, yamlFilename, inputPaths, outputFilenames] - } - | publishStatesProc - emit: input_ch - } - return publishStatesSimpleWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/setState.nf' -def setState(fun) { - assert fun instanceof Closure || fun instanceof Map || fun instanceof List : - "Error in setState: Expected process argument to be a Closure, a Map, or a List. Found: class ${fun.getClass()}" - - // if fun is a List, convert to map - if (fun instanceof List) { - // check whether fun is a list[string] - assert fun.every{it instanceof CharSequence} : "Error in setState: argument is a List, but not all elements are Strings" - fun = fun.collectEntries{[it, it]} - } - - // if fun is a map, convert to closure - if (fun instanceof Map) { - // check whether fun is a map[string, string] - assert fun.values().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all values are Strings" - assert fun.keySet().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all keys are Strings" - def funMap = fun.clone() - // turn the map into a closure to be used later on - fun = { id_, state_ -> - assert state_ instanceof Map : "Error in setState: the state is not a Map" - funMap.collectMany{newkey, origkey -> - if (state_.containsKey(origkey)) { - [[newkey, state_[origkey]]] - } else { - [] - } - }.collectEntries() - } - } - - map { tup -> - def id = tup[0] - def state = tup[1] - def unfilteredState = fun(id, state) - def newState = unfilteredState.findAll{key, val -> val != null} - [id, newState] + tup.drop(2) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processAuto.nf' -// TODO: unit test processAuto -def processAuto(Map auto) { - // remove null values - auto = auto.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = ["simplifyInput", "simplifyOutput", "transcript", "publish"] - def unexpectedKeys = auto.keySet() - expectedKeys - assert unexpectedKeys.isEmpty(), "unexpected keys in auto: '${unexpectedKeys.join("', '")}'" - - // check auto.simplifyInput - assert auto.simplifyInput instanceof Boolean, "auto.simplifyInput must be a boolean" - - // check auto.simplifyOutput - assert auto.simplifyOutput instanceof Boolean, "auto.simplifyOutput must be a boolean" - - // check auto.transcript - assert auto.transcript instanceof Boolean, "auto.transcript must be a boolean" - - // check auto.publish - assert auto.publish instanceof Boolean || auto.publish == "state", "auto.publish must be a boolean or 'state'" - - return auto.subMap(expectedKeys) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processDirectives.nf' -def assertMapKeys(map, expectedKeys, requiredKeys, mapName) { - assert map instanceof Map : "Expected argument '$mapName' to be a Map. Found: class ${map.getClass()}" - map.forEach { key, val -> - assert key in expectedKeys : "Unexpected key '$key' in ${mapName ? mapName + " " : ""}map" - } - requiredKeys.forEach { requiredKey -> - assert map.containsKey(requiredKey) : "Missing required key '$key' in ${mapName ? mapName + " " : ""}map" - } -} - -// TODO: unit test processDirectives -def processDirectives(Map drctv) { - // remove null values - drctv = drctv.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = [ - "accelerator", "afterScript", "beforeScript", "cache", "conda", "container", "containerOptions", "cpus", "disk", "echo", "errorStrategy", "executor", "machineType", "maxErrors", "maxForks", "maxRetries", "memory", "module", "penv", "pod", "publishDir", "queue", "label", "scratch", "storeDir", "stageInMode", "stageOutMode", "tag", "time" - ] - def unexpectedKeys = drctv.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Unexpected keys in process directive: '${unexpectedKeys.join("', '")}'" - - /* DIRECTIVE accelerator - accepted examples: - - [ limit: 4, type: "nvidia-tesla-k80" ] - */ - if (drctv.containsKey("accelerator")) { - assertMapKeys(drctv["accelerator"], ["type", "limit", "request", "runtime"], [], "accelerator") - } - - /* DIRECTIVE afterScript - accepted examples: - - "source /cluster/bin/cleanup" - */ - if (drctv.containsKey("afterScript")) { - assert drctv["afterScript"] instanceof CharSequence - } - - /* DIRECTIVE beforeScript - accepted examples: - - "source /cluster/bin/setup" - */ - if (drctv.containsKey("beforeScript")) { - assert drctv["beforeScript"] instanceof CharSequence - } - - /* DIRECTIVE cache - accepted examples: - - true - - false - - "deep" - - "lenient" - */ - if (drctv.containsKey("cache")) { - assert drctv["cache"] instanceof CharSequence || drctv["cache"] instanceof Boolean - if (drctv["cache"] instanceof CharSequence) { - assert drctv["cache"] in ["deep", "lenient"] : "Unexpected value for cache" - } - } - - /* DIRECTIVE conda - accepted examples: - - "bwa=0.7.15" - - "bwa=0.7.15 fastqc=0.11.5" - - ["bwa=0.7.15", "fastqc=0.11.5"] - */ - if (drctv.containsKey("conda")) { - if (drctv["conda"] instanceof List) { - drctv["conda"] = drctv["conda"].join(" ") - } - assert drctv["conda"] instanceof CharSequence - } - - /* DIRECTIVE container - accepted examples: - - "foo/bar:tag" - - [ registry: "reg", image: "im", tag: "ta" ] - is transformed to "reg/im:ta" - - [ image: "im" ] - is transformed to "im:latest" - */ - if (drctv.containsKey("container")) { - assert drctv["container"] instanceof Map || drctv["container"] instanceof CharSequence - if (drctv["container"] instanceof Map) { - def m = drctv["container"] - assertMapKeys(m, [ "registry", "image", "tag" ], ["image"], "container") - def part1 = - System.getenv('OVERRIDE_CONTAINER_REGISTRY') ? System.getenv('OVERRIDE_CONTAINER_REGISTRY') + "/" : - params.containsKey("override_container_registry") ? params["override_container_registry"] + "/" : // todo: remove? - m.registry ? m.registry + "/" : - "" - def part2 = m.image - def part3 = m.tag ? ":" + m.tag : ":latest" - drctv["container"] = part1 + part2 + part3 - } - } - - /* DIRECTIVE containerOptions - accepted examples: - - "--foo bar" - - ["--foo bar", "-f b"] - */ - if (drctv.containsKey("containerOptions")) { - if (drctv["containerOptions"] instanceof List) { - drctv["containerOptions"] = drctv["containerOptions"].join(" ") - } - assert drctv["containerOptions"] instanceof CharSequence - } - - /* DIRECTIVE cpus - accepted examples: - - 1 - - 10 - */ - if (drctv.containsKey("cpus")) { - assert drctv["cpus"] instanceof Integer - } - - /* DIRECTIVE disk - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("disk")) { - assert drctv["disk"] instanceof CharSequence - // assert drctv["disk"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE echo - accepted examples: - - true - - false - */ - if (drctv.containsKey("echo")) { - assert drctv["echo"] instanceof Boolean - } - - /* DIRECTIVE errorStrategy - accepted examples: - - "terminate" - - "finish" - */ - if (drctv.containsKey("errorStrategy")) { - assert drctv["errorStrategy"] instanceof CharSequence - assert drctv["errorStrategy"] in ["terminate", "finish", "ignore", "retry"] : "Unexpected value for errorStrategy" - } - - /* DIRECTIVE executor - accepted examples: - - "local" - - "sge" - */ - if (drctv.containsKey("executor")) { - assert drctv["executor"] instanceof CharSequence - assert drctv["executor"] in ["local", "sge", "uge", "lsf", "slurm", "pbs", "pbspro", "moab", "condor", "nqsii", "ignite", "k8s", "awsbatch", "google-pipelines"] : "Unexpected value for executor" - } - - /* DIRECTIVE machineType - accepted examples: - - "n1-highmem-8" - */ - if (drctv.containsKey("machineType")) { - assert drctv["machineType"] instanceof CharSequence - } - - /* DIRECTIVE maxErrors - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxErrors")) { - assert drctv["maxErrors"] instanceof Integer - } - - /* DIRECTIVE maxForks - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxForks")) { - assert drctv["maxForks"] instanceof Integer - } - - /* DIRECTIVE maxRetries - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxRetries")) { - assert drctv["maxRetries"] instanceof Integer - } - - /* DIRECTIVE memory - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("memory")) { - assert drctv["memory"] instanceof CharSequence - // assert drctv["memory"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE module - accepted examples: - - "ncbi-blast/2.2.27" - - "ncbi-blast/2.2.27:t_coffee/10.0" - - ["ncbi-blast/2.2.27", "t_coffee/10.0"] - */ - if (drctv.containsKey("module")) { - if (drctv["module"] instanceof List) { - drctv["module"] = drctv["module"].join(":") - } - assert drctv["module"] instanceof CharSequence - } - - /* DIRECTIVE penv - accepted examples: - - "smp" - */ - if (drctv.containsKey("penv")) { - assert drctv["penv"] instanceof CharSequence - } - - /* DIRECTIVE pod - accepted examples: - - [ label: "key", value: "val" ] - - [ annotation: "key", value: "val" ] - - [ env: "key", value: "val" ] - - [ [label: "l", value: "v"], [env: "e", value: "v"]] - */ - if (drctv.containsKey("pod")) { - if (drctv["pod"] instanceof Map) { - drctv["pod"] = [ drctv["pod"] ] - } - assert drctv["pod"] instanceof List - drctv["pod"].forEach { pod -> - assert pod instanceof Map - // TODO: should more checks be added? - // See https://www.nextflow.io/docs/latest/process.html?highlight=directives#pod - // e.g. does it contain 'label' and 'value', or 'annotation' and 'value', or ...? - } - } - - /* DIRECTIVE publishDir - accepted examples: - - [] - - [ [ path: "foo", enabled: true ], [ path: "bar", enabled: false ] ] - - "/path/to/dir" - is transformed to [[ path: "/path/to/dir" ]] - - [ path: "/path/to/dir", mode: "cache" ] - is transformed to [[ path: "/path/to/dir", mode: "cache" ]] - */ - // TODO: should we also look at params["publishDir"]? - if (drctv.containsKey("publishDir")) { - def pblsh = drctv["publishDir"] - - // check different options - assert pblsh instanceof List || pblsh instanceof Map || pblsh instanceof CharSequence - - // turn into list if not already so - // for some reason, 'if (!pblsh instanceof List) pblsh = [ pblsh ]' doesn't work. - pblsh = pblsh instanceof List ? pblsh : [ pblsh ] - - // check elements of publishDir - pblsh = pblsh.collect{ elem -> - // turn into map if not already so - elem = elem instanceof CharSequence ? [ path: elem ] : elem - - // check types and keys - assert elem instanceof Map : "Expected publish argument '$elem' to be a String or a Map. Found: class ${elem.getClass()}" - assertMapKeys(elem, [ "path", "mode", "overwrite", "pattern", "saveAs", "enabled" ], ["path"], "publishDir") - - // check elements in map - assert elem.containsKey("path") - assert elem["path"] instanceof CharSequence - if (elem.containsKey("mode")) { - assert elem["mode"] instanceof CharSequence - assert elem["mode"] in [ "symlink", "rellink", "link", "copy", "copyNoFollow", "move" ] - } - if (elem.containsKey("overwrite")) { - assert elem["overwrite"] instanceof Boolean - } - if (elem.containsKey("pattern")) { - assert elem["pattern"] instanceof CharSequence - } - if (elem.containsKey("saveAs")) { - assert elem["saveAs"] instanceof CharSequence //: "saveAs as a Closure is currently not supported. Surround your closure with single quotes to get the desired effect. Example: '\{ foo \}'" - } - if (elem.containsKey("enabled")) { - assert elem["enabled"] instanceof Boolean - } - - // return final result - elem - } - // store final directive - drctv["publishDir"] = pblsh - } - - /* DIRECTIVE queue - accepted examples: - - "long" - - "short,long" - - ["short", "long"] - */ - if (drctv.containsKey("queue")) { - if (drctv["queue"] instanceof List) { - drctv["queue"] = drctv["queue"].join(",") - } - assert drctv["queue"] instanceof CharSequence - } - - /* DIRECTIVE label - accepted examples: - - "big_mem" - - "big_cpu" - - ["big_mem", "big_cpu"] - */ - if (drctv.containsKey("label")) { - if (drctv["label"] instanceof CharSequence) { - drctv["label"] = [ drctv["label"] ] - } - assert drctv["label"] instanceof List - drctv["label"].forEach { label -> - assert label instanceof CharSequence - // assert label.matches("[a-zA-Z0-9]([a-zA-Z0-9_]*[a-zA-Z0-9])?") - // ^ does not allow closures - } - } - - /* DIRECTIVE scratch - accepted examples: - - true - - "/path/to/scratch" - - '$MY_PATH_TO_SCRATCH' - - "ram-disk" - */ - if (drctv.containsKey("scratch")) { - assert drctv["scratch"] == true || drctv["scratch"] instanceof CharSequence - } - - /* DIRECTIVE storeDir - accepted examples: - - "/path/to/storeDir" - */ - if (drctv.containsKey("storeDir")) { - assert drctv["storeDir"] instanceof CharSequence - } - - /* DIRECTIVE stageInMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageInMode")) { - assert drctv["stageInMode"] instanceof CharSequence - assert drctv["stageInMode"] in ["copy", "link", "symlink", "rellink"] - } - - /* DIRECTIVE stageOutMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageOutMode")) { - assert drctv["stageOutMode"] instanceof CharSequence - assert drctv["stageOutMode"] in ["copy", "move", "rsync"] - } - - /* DIRECTIVE tag - accepted examples: - - "foo" - - '$id' - */ - if (drctv.containsKey("tag")) { - assert drctv["tag"] instanceof CharSequence - } - - /* DIRECTIVE time - accepted examples: - - "1h" - - "2days" - - "1day 6hours 3minutes 30seconds" - */ - if (drctv.containsKey("time")) { - assert drctv["time"] instanceof CharSequence - // todo: validation regex? - } - - return drctv -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf' -def processWorkflowArgs(Map args, Map defaultWfArgs, Map meta) { - // override defaults with args - def workflowArgs = defaultWfArgs + args - - // check whether 'key' exists - assert workflowArgs.containsKey("key") : "Error in module '${meta.config.name}': key is a required argument" - - // if 'key' is a closure, apply it to the original key - if (workflowArgs["key"] instanceof Closure) { - workflowArgs["key"] = workflowArgs["key"](meta.config.name) - } - def key = workflowArgs["key"] - assert key instanceof CharSequence : "Expected process argument 'key' to be a String. Found: class ${key.getClass()}" - assert key ==~ /^[a-zA-Z_]\w*$/ : "Error in module '$key': Expected process argument 'key' to consist of only letters, digits or underscores. Found: ${key}" - - // check for any unexpected keys - def expectedKeys = ["key", "directives", "auto", "map", "mapId", "mapData", "mapPassthrough", "filter", "runIf", "fromState", "toState", "args", "renameKeys", "debug"] - def unexpectedKeys = workflowArgs.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Error in module '$key': unexpected arguments to the '.run()' function: '${unexpectedKeys.join("', '")}'" - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("directives") : "Error in module '$key': directives is a required argument" - assert workflowArgs["directives"] instanceof Map : "Error in module '$key': Expected process argument 'directives' to be a Map. Found: class ${workflowArgs['directives'].getClass()}" - workflowArgs["directives"] = processDirectives(defaultWfArgs.directives + workflowArgs["directives"]) - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("auto") : "Error in module '$key': auto is a required argument" - assert workflowArgs["auto"] instanceof Map : "Error in module '$key': Expected process argument 'auto' to be a Map. Found: class ${workflowArgs['auto'].getClass()}" - workflowArgs["auto"] = processAuto(defaultWfArgs.auto + workflowArgs["auto"]) - - // auto define publish, if so desired - if (workflowArgs.auto.publish == true && (workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : [:]).isEmpty()) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.publish is true, params.publish_dir needs to be defined.\n" + - // " Example: params.publish_dir = \"./output/\"" - def publishDir = getPublishDir() - - if (publishDir != null) { - workflowArgs.directives.publishDir = [[ - path: publishDir, - saveAs: "{ it.startsWith('.') ? null : it }", // don't publish hidden files, by default - mode: "copy" - ]] - } - } - - // auto define transcript, if so desired - if (workflowArgs.auto.transcript == true) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("transcriptsDir") || params.containsKey("transcripts_dir") || params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.transcript is true, either params.transcripts_dir or params.publish_dir needs to be defined.\n" + - // " Example: params.transcripts_dir = \"./transcripts/\"" - def transcriptsDir = - params.containsKey("transcripts_dir") ? params.transcripts_dir : - params.containsKey("transcriptsDir") ? params.transcriptsDir : - params.containsKey("publish_dir") ? params.publish_dir + "/_transcripts" : - params.containsKey("publishDir") ? params.publishDir + "/_transcripts" : - null - if (transcriptsDir != null) { - def timestamp = nextflow.Nextflow.getSession().getWorkflowMetadata().start.format('yyyy-MM-dd_HH-mm-ss') - def transcriptsPublishDir = [ - path: "$transcriptsDir/$timestamp/\${task.process.replaceAll(':', '-')}/\${id}/", - saveAs: "{ it.startsWith('.') ? it.replaceAll('^.', '') : null }", - mode: "copy" - ] - def publishDirs = workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : null ? workflowArgs.directives.publishDir : [] - workflowArgs.directives.publishDir = publishDirs + transcriptsPublishDir - } - } - - // if this is a stubrun, remove certain directives? - if (workflow.stubRun) { - workflowArgs.directives.keySet().removeAll(["publishDir", "cpus", "memory", "label"]) - } - - for (nam in ["map", "mapId", "mapData", "mapPassthrough", "filter", "runIf"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam]) { - assert workflowArgs[nam] instanceof Closure : "Error in module '$key': Expected process argument '$nam' to be null or a Closure. Found: class ${workflowArgs[nam].getClass()}" - } - } - - // TODO: should functions like 'map', 'mapId', 'mapData', 'mapPassthrough' be deprecated as well? - for (nam in ["map", "mapData", "mapPassthrough", "renameKeys"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam] != null) { - log.warn "module '$key': workflow argument '$nam' is deprecated and will be removed in Viash 0.9.0. Please use 'fromState' and 'toState' instead." - } - } - - // check fromState - workflowArgs["fromState"] = _processFromState(workflowArgs.get("fromState"), key, meta.config) - - // check toState - workflowArgs["toState"] = _processToState(workflowArgs.get("toState"), key, meta.config) - - // return output - return workflowArgs -} - -def _processFromState(fromState, key_, config_) { - assert fromState == null || fromState instanceof Closure || fromState instanceof Map || fromState instanceof List : - "Error in module '$key_': Expected process argument 'fromState' to be null, a Closure, a Map, or a List. Found: class ${fromState.getClass()}" - if (fromState == null) { - return null - } - - // if fromState is a List, convert to map - if (fromState instanceof List) { - // check whether fromstate is a list[string] - assert fromState.every{it instanceof CharSequence} : "Error in module '$key_': fromState is a List, but not all elements are Strings" - fromState = fromState.collectEntries{[it, it]} - } - - // if fromState is a map, convert to closure - if (fromState instanceof Map) { - // check whether fromstate is a map[string, string] - assert fromState.values().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all values are Strings" - assert fromState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all keys are Strings" - def fromStateMap = fromState.clone() - def requiredInputNames = meta.config.allArguments.findAll{it.required && it.direction == "Input"}.collect{it.plainName} - // turn the map into a closure to be used later on - fromState = { it -> - def state = it[1] - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def data = fromStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (state.containsKey(origkey)) { - [[newkey, state[origkey]]] - } else if (!requiredInputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': fromState key '$origkey' not found in current state") - } - }.collectEntries() - data - } - } - - return fromState -} - -def _processToState(toState, key_, config_) { - if (toState == null) { - toState = { tup -> tup[1] } - } - - // toState should be a closure, map[string, string], or list[string] - assert toState instanceof Closure || toState instanceof Map || toState instanceof List : - "Error in module '$key_': Expected process argument 'toState' to be a Closure, a Map, or a List. Found: class ${toState.getClass()}" - - // if toState is a List, convert to map - if (toState instanceof List) { - // check whether toState is a list[string] - assert toState.every{it instanceof CharSequence} : "Error in module '$key_': toState is a List, but not all elements are Strings" - toState = toState.collectEntries{[it, it]} - } - - // if toState is a map, convert to closure - if (toState instanceof Map) { - // check whether toState is a map[string, string] - assert toState.values().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all values are Strings" - assert toState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all keys are Strings" - def toStateMap = toState.clone() - def requiredOutputNames = config_.allArguments.findAll{it.required && it.direction == "Output"}.collect{it.plainName} - // turn the map into a closure to be used later on - toState = { it -> - def output = it[1] - def state = it[2] - assert output instanceof Map : "Error in module '$key_': the output is not a Map" - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def extraEntries = toStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (output.containsKey(origkey)) { - [[newkey, output[origkey]]] - } else if (!requiredOutputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': toState key '$origkey' not found in current output") - } - }.collectEntries() - state + extraEntries - } - } - - return toState -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/workflowFactory.nf' -def _debug(workflowArgs, debugKey) { - if (workflowArgs.debug) { - view { "process '${workflowArgs.key}' $debugKey tuple: $it" } - } else { - map { it } - } -} - -// depends on: innerWorkflowFactory -def workflowFactory(Map args, Map defaultWfArgs, Map meta) { - def workflowArgs = processWorkflowArgs(args, defaultWfArgs, meta) - def key_ = workflowArgs["key"] - - workflow workflowInstance { - take: input_ - - main: - def chModified = input_ - | checkUniqueIds([:]) - | _debug(workflowArgs, "input") - | map { tuple -> - tuple = deepClone(tuple) - - if (workflowArgs.map) { - tuple = workflowArgs.map(tuple) - } - if (workflowArgs.mapId) { - tuple[0] = workflowArgs.mapId(tuple[0]) - } - if (workflowArgs.mapData) { - tuple[1] = workflowArgs.mapData(tuple[1]) - } - if (workflowArgs.mapPassthrough) { - tuple = tuple.take(2) + workflowArgs.mapPassthrough(tuple.drop(2)) - } - - // check tuple - assert tuple instanceof List : - "Error in module '${key_}': element in channel should be a tuple [id, data, ...otherargs...]\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: List. Found: tuple.getClass() is ${tuple.getClass()}" - assert tuple.size() >= 2 : - "Error in module '${key_}': expected length of tuple in input channel to be two or greater.\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: tuple.size() == ${tuple.size()}" - - // check id field - if (tuple[0] instanceof GString) { - tuple[0] = tuple[0].toString() - } - assert tuple[0] instanceof CharSequence : - "Error in module '${key_}': first element of tuple in channel should be a String\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: ${tuple[0]}" - - // match file to input file - if (workflowArgs.auto.simplifyInput && (tuple[1] instanceof Path || tuple[1] instanceof List)) { - def inputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - - assert inputFiles.size() == 1 : - "Error in module '${key_}' id '${tuple[0]}'.\n" + - " Anonymous file inputs are only allowed when the process has exactly one file input.\n" + - " Expected: inputFiles.size() == 1. Found: inputFiles.size() is ${inputFiles.size()}" - - tuple[1] = [[ inputFiles[0].plainName, tuple[1] ]].collectEntries() - } - - // check data field - assert tuple[1] instanceof Map : - "Error in module '${key_}' id '${tuple[0]}': second element of tuple in channel should be a Map\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // rename keys of data field in tuple - if (workflowArgs.renameKeys) { - assert workflowArgs.renameKeys instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class: Map. Found: renameKeys.getClass() is ${workflowArgs.renameKeys.getClass()}" - assert tuple[1] instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // TODO: allow renameKeys to be a function? - workflowArgs.renameKeys.each { newKey, oldKey -> - assert newKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of newKey: String. Found: newKey.getClass() is ${newKey.getClass()}" - assert oldKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of oldKey: String. Found: oldKey.getClass() is ${oldKey.getClass()}" - assert tuple[1].containsKey(oldKey) : - "Error renaming data keys in module '${key}' id '${tuple[0]}'.\n" + - " Key '$oldKey' is missing in the data map. tuple[1].keySet() is '${tuple[1].keySet()}'" - tuple[1].put(newKey, tuple[1][oldKey]) - } - tuple[1].keySet().removeAll(workflowArgs.renameKeys.collect{ newKey, oldKey -> oldKey }) - } - tuple - } - - def chModifiedFiltered = workflowArgs.filter ? - chModified | filter{workflowArgs.filter(it)} : - chModified - - def chRun = null - def chPassthrough = null - if (workflowArgs.runIf) { - def runIfBranch = chModifiedFiltered.branch{ tup -> - run: workflowArgs.runIf(tup[0], tup[1]) - passthrough: true - } - chRun = runIfBranch.run - chPassthrough = runIfBranch.passthrough - } else { - chRun = chModifiedFiltered - chPassthrough = Channel.empty() - } - - def chArgs = workflowArgs.fromState ? - chRun | map{ - def new_data = workflowArgs.fromState(it.take(2)) - [it[0], new_data] - } : - chRun | map {tup -> tup.take(2)} - - // fill in defaults - def chArgsWithDefaults = chArgs - | map { tuple -> - def id_ = tuple[0] - def data_ = tuple[1] - - // TODO: could move fromState to here - - // fetch default params from functionality - def defaultArgs = meta.config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - // fetch overrides in params - def paramArgs = meta.config.allArguments - .findAll { par -> - def argKey = key_ + "__" + par.plainName - params.containsKey(argKey) - } - .collectEntries { [ it.plainName, params[key_ + "__" + it.plainName] ] } - - // fetch overrides in data - def dataArgs = meta.config.allArguments - .findAll { data_.containsKey(it.plainName) } - .collectEntries { [ it.plainName, data_[it.plainName] ] } - - // combine params - def combinedArgs = defaultArgs + paramArgs + workflowArgs.args + dataArgs - - // remove arguments with explicit null values - combinedArgs - .removeAll{_, val -> val == null || val == "viash_no_value" || val == "force_null"} - - combinedArgs = _processInputValues(combinedArgs, meta.config, id_, key_) - - [id_, combinedArgs] + tuple.drop(2) - } - - // TODO: move some of the _meta.join_id wrangling to the safeJoin() function. - def chInitialOutput = chArgsWithDefaults - | _debug(workflowArgs, "processed") - // run workflow - | innerWorkflowFactory(workflowArgs) - // check output tuple - | map { id_, output_ -> - - // see if output map contains metadata - def meta_ = - output_ instanceof Map && output_.containsKey("_meta") ? - output_["_meta"] : - [:] - def join_id = meta_.join_id ?: id_ - - // remove metadata - output_ = output_.findAll{k, v -> k != "_meta"} - - // check value types - output_ = _processOutputValues(output_, meta.config, id_, key_) - - // simplify output if need be - if (workflowArgs.auto.simplifyOutput && output_.size() == 1) { - output_ = output_.values()[0] - } - - [join_id, id_, output_] - } - // | view{"chInitialOutput: ${it.take(3)}"} - - // join the output [prev_id, new_id, output] with the previous state [prev_id, state, ...] - def chNewState = safeJoin(chInitialOutput, chModifiedFiltered, key_) - // input tuple format: [join_id, id, output, prev_state, ...] - // output tuple format: [join_id, id, new_state, ...] - | map{ tup -> - def new_state = workflowArgs.toState(tup.drop(1).take(3)) - tup.take(2) + [new_state] + tup.drop(4) - } - - if (workflowArgs.auto.publish == "state") { - def chPublish = chNewState - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [join_id, id, new_state] - | map{ tup -> - tup.take(3) - } - - safeJoin(chPublish, chArgsWithDefaults, key_) - // input tuple format: [join_id, id, new_state, orig_state, ...] - // output tuple format: [id, new_state, orig_state] - | map { tup -> - tup.drop(1).take(3) - } - | publishStatesByConfig(key: key_, config: meta.config) - } - - // remove join_id and meta - chReturn = chNewState - | map { tup -> - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [id, new_state, ...] - tup.drop(1) - } - | _debug(workflowArgs, "output") - | concat(chPassthrough) - - emit: chReturn - } - - def wf = workflowInstance.cloneWithName(key_) - - // add factory function - wf.metaClass.run = { runArgs -> - workflowFactory(runArgs, workflowArgs, meta) - } - // add config to module for later introspection - wf.metaClass.config = meta.config - - return wf -} - -nextflow.enable.dsl=2 - -// START COMPONENT-SPECIFIC CODE - -// create meta object -meta = [ - "resources_dir": moduleDir.toRealPath().normalize(), - "config": processConfig(readJsonBlob('''{ - "name" : "salmon_quant", - "namespace" : "salmon", - "version" : "v0.1.0", - "argument_groups" : [ - { - "name" : "Common input options", - "arguments" : [ - { - "type" : "string", - "name" : "--lib_type", - "alternatives" : [ - "-l" - ], - "description" : "Format string describing the library.\nThe library type string consists of three parts: \n1. Relative orientation of the reads: This part is only provided if the library is paired-end, THe possible options are\n I = inward\n O = outward\n M = matching\n2. Strandedness of the library: This part specifies whether the protocol is stranded or unstranded. The options are:\n S = stranded\n U = unstranded\n3. Directionality of the reads: If the library is stranded, the final part of the library string is used to specify the strand from which the read originates. The possible values are\n F = read 1 (or single-end read) comes from the forward strand\n R = read 1 (or single-end read) comes from the reverse strand\n", - "default" : [ - "A" - ], - "required" : false, - "choices" : [ - "A", - "U", - "SF", - "SR", - "IU", - "IS", - "ISF", - "ISR", - "OU", - "OS", - "OSF", - "OSR", - "MU", - "MS", - "MSF", - "MSR" - ], - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Mapping input options", - "arguments" : [ - { - "type" : "file", - "name" : "--index", - "alternatives" : [ - "-i" - ], - "description" : "Salmon index.\n", - "example" : [ - "transcriptome_index" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--unmated_reads", - "alternatives" : [ - "-r" - ], - "description" : "List of files containing unmated reads of (e.g. single-end reads).\n", - "example" : [ - "sample.fq.gz" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : true, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--mates1", - "alternatives" : [ - "-m1" - ], - "description" : "File containing the #1 mates.\n", - "example" : [ - "sample_1.fq.gz" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : true, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--mates2", - "alternatives" : [ - "-m2" - ], - "description" : "File containing the #2 mates.\n", - "example" : [ - "sample_2.fq.gz" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : true, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Alignment input options", - "arguments" : [ - { - "type" : "boolean_true", - "name" : "--discard_orphans", - "description" : "Discard orphan alignments in the input [for alignment-based mode only]. If this flag is passed, then only paired alignments will be considered toward quantification estimates. The default behavior is to consider orphan alignments if no valid paired mappings exist.\n", - "direction" : "input" - }, - { - "type" : "file", - "name" : "--alignments", - "alternatives" : [ - "-a" - ], - "description" : "Input alignment (BAM) file(s).\n", - "example" : [ - "sample.fq.gz" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : true, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--eqclasses", - "alternatives" : [ - "-e" - ], - "description" : "input salmon weighted equivalence class file.\n", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--targets", - "alternatives" : [ - "-t" - ], - "description" : "FASTA format file containing target transcripts.\n", - "example" : [ - "transcripts.fasta" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--ont", - "description" : "Use alignment model for Oxford Nanopore long reads\n", - "direction" : "input" - } - ] - }, - { - "name" : "Output", - "arguments" : [ - { - "type" : "file", - "name" : "--output", - "alternatives" : [ - "-o" - ], - "description" : "Output quantification directory.\n", - "example" : [ - "quant_output" - ], - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "output", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--quant_results", - "description" : "Salmon quantification file.\n", - "example" : [ - "quant.sf" - ], - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "output", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Basic options", - "arguments" : [ - { - "type" : "boolean_true", - "name" : "--seq_bias", - "description" : "Perform sequence-specific bias correction.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--gc_bias", - "description" : "Perform fragment GC bias correction [beta for single-end reads].\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--pos_bias", - "description" : "Perform positional bias correction.\n", - "direction" : "input" - }, - { - "type" : "double", - "name" : "--incompat_prior", - "description" : "Set the prior probability that an alignment that disagrees with the specified library type (--lib_type) results from the true fragment origin. Setting this to 0 specifies that alignments that disagree with the library type should be \\"impossible\\", while setting it to 1 says that alignments that disagree with the library type are no less likely than those that do.\n", - "example" : [ - 0.0 - ], - "required" : false, - "min" : 0.0, - "max" : 1.0, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--gene_map", - "alternatives" : [ - "-g" - ], - "description" : "File containing a mapping of transcripts to genes. If this file is provided salmon will output both quant.sf and quant.genes.sf files, where the latter contains aggregated gene-level abundance estimates. The transcript to gene mapping should be provided as either a GTF file, or a in a simple tab-delimited format where each line contains the name of a transcript and the gene to which it belongs separated by a tab. The extension of the file is used to determine how the file should be parsed. Files ending in '.gtf', '.gff' or '.gff3' are assumed to be in GTF format; files with any other extension are assumed to be in the simple format. In GTF / GFF format, the \\"transcript_id\\" is assumed to contain the transcript identifier and the \\"gene_id\\" is assumed to contain the corresponding gene identifier.\n", - "example" : [ - "gene_map.gtf" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--aux_target_file", - "description" : "A file containing a list of \\"auxiliary\\" targets. These are valid targets (i.e., not decoys) to which fragments are allowed to map and be assigned, and which will be quantified, but for which auxiliary models like sequence-specific and fragment-GC bias correction should not be applied.\n", - "example" : [ - "auxilary_targets.txt" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--meta", - "description" : "If you're using Salmon on a metagenomic dataset, consider setting this flag to disable parts of the abundance estimation model that make less sense for metagenomic data.\n", - "direction" : "input" - }, - { - "type" : "double", - "name" : "--score_exp", - "description" : "The factor by which sub-optimal alignment scores are downweighted to produce a probability. If the best alignment score for the current read is S, and the score for a particular alignment is w, then the probability will be computed porportional to exp( - scoreExp * (S-w) ).\n", - "example" : [ - 1.0 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Options specific to mapping mode", - "arguments" : [ - { - "type" : "boolean_true", - "name" : "--discard_orphans_quasi", - "description" : "[selective-alignment mode only] \nDiscard orphan mappings in selective-alignment mode. If this flag is passed then only paired mappings will be considered toward quantification estimates. The default behavior is to consider orphan mappings if no valid paired mappings exist. This flag is independent of the option to write the orphaned mappings to file (--writeOrphanLinks).\n", - "direction" : "input" - }, - { - "type" : "double", - "name" : "--consensus_slack", - "description" : "[selective-alignment mode only] \nThe amount of slack allowed in the selective-alignment filtering mechanism. If this is set to a fraction, X, greater than 0 (and in [0,1)), then uniMEM chains with scores below (100 * X)% of the best chain score for a read, and read pairs with a sum of chain scores below (100 * X)% of the best chain score for a read pair will be discounted as a mapping candidates. The default value of this option is 0.35.\n", - "example" : [ - 0.35 - ], - "required" : false, - "min" : 0.0, - "max" : 0.999999999, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "double", - "name" : "--pre_merge_chain_sub_thresh", - "description" : "[selective-alignment mode only] \nThe threshold of sub-optimal chains, compared to the best chain on a given target, that will be retained and passed to the next phase of mapping. Specifically, if the best chain for a read (or read-end in paired-end mode) to target t has score X_t, then all chains for this read with score >= X_t * preMergeChainSubThresh will be retained and passed to subsequent mapping phases. This value must be in the range [0, 1].\n", - "example" : [ - 0.75 - ], - "required" : false, - "min" : 0.0, - "max" : 1.0, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "double", - "name" : "--post_merge_chain_sub_thresh", - "description" : "[selective-alignment mode only] \nThe threshold of sub-optimal chains, compared to the best chain on a given target, that will be retained and passed to the next phase of mapping. This is different than post_merge_chain_sub_thresh, because this is applied to pairs of chains (from the ends of paired-end reads) after merging (i.e. after checking concordancy constraints etc.). Specifically, if the best chain pair to target t has score X_t, then all chain pairs for this read pair with score >= X_t * post_merge_chain_sub_thresh will be retained and passed to subsequent mapping phases. This value must be in the range [0, 1]. Note: This option is only meaningful for paired-end libraries, and is ignored for single-end libraries.\n", - "example" : [ - 0.9 - ], - "required" : false, - "min" : 0.0, - "max" : 1.0, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "double", - "name" : "--orphan_chain_sub_thresh", - "description" : "[selective-alignment mode only]\nThis threshold sets a global sub-optimality threshold for chains corresponding to orphan mappings. That is, if the merging procedure results in no concordant mappings then only orphan mappings with a chain score >= orphan_chain_sub_thresh * bestChainScore will be retained and passed to subsequent mapping phases. This value must be in the range [0, 1]. Note: This option is only meaningful for paired-end libraries, and is ignored for single-end libraries.\n", - "example" : [ - 0.95 - ], - "required" : false, - "min" : 0.0, - "max" : 1.0, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "double", - "name" : "--min_score_fraction", - "description" : "[selective-alignment mode only]\nThe fraction of the optimal possible alignment score that a mapping must achieve in order to be considered \\"valid\\" --- should be in (0,1]. Default 0.65\n", - "example" : [ - 0.65 - ], - "required" : false, - "min" : 1.0E-9, - "max" : 1.0, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--mismatch_seed_skip", - "description" : "[selective-alignment mode only]\nAfter a k-mer hit is extended to a uni-MEM, the uni-MEM extension can terminate for one of 3 reasons; the end of the read, the end of the unitig, or a mismatch. If the extension ends because of a mismatch, this is likely the result of a sequencing error. To avoid looking up many k-mers that will likely fail to be located in the index, the search procedure skips by a factor of mismatch_seed_skip until it either (1) finds another match or (2) is k-bases past the mismatch position. This value controls that skip length. A smaller value can increase sensitivity, while a larger value can speed up seeding.\n", - "example" : [ - 3 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--disable_chaining_heuristic", - "description" : "[selective-alignment mode only] \nBy default, the heuristic of (Li 2018) is implemented, which terminates the chaining DP once a given number of valid backpointers are found. This speeds up the seed (MEM) chaining step, but may result in sub-optimal chains in complex situations (e.g. sequences with many repeats and overlapping repeats). Passing this flag will disable the chaining heuristic, and perform the full chaining dynamic program, guaranteeing the optimal chain is found in this step.\n", - "direction" : "input" - }, - { - "type" : "double", - "name" : "--decoy_threshold", - "description" : "[selective-alignment mode only]\nFor an alignemnt to an annotated transcript to be considered invalid, it must have an alignment score < (decoy_threshold * bestDecoyScore). A value of 1.0 means that any alignment strictly worse than the best decoy alignment will be discarded. A smaller value will allow reads to be allocated to transcripts even if they strictly align better to the decoy sequence.\n", - "example" : [ - 1.0 - ], - "required" : false, - "min" : 0.0, - "max" : 1.0, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--ma", - "description" : "[selective-alignment mode only]\nThe value given to a match between read and reference nucleotides in an alignment.\n", - "example" : [ - 2 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--mp", - "description" : "[selective-alignment mode only]\nThe value given to a mis-match between read and reference nucleotides in an alignment.\n", - "example" : [ - -4 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--go", - "description" : "[selective-alignment mode only]\nThe value given to a gap opening in an alignment.\n", - "example" : [ - 6 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--ge", - "description" : "[selective-alignment mode only]\nThe value given to a gap extension in an alignment.\n", - "example" : [ - 2 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--bandwidth", - "description" : "[selective-alignment mode only]\nThe value used for the bandwidth passed to ksw2. A smaller bandwidth can make the alignment verification run more quickly, but could possibly miss valid alignments.\n", - "example" : [ - 15 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--allow_dovetail", - "description" : "[selective-alignment mode only] \nAllow dovetailing mappings.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--recover_orphans", - "description" : "[selective-alignment mode only] \nAttempt to recover the mates of orphaned reads. This uses edlib for orphan recovery, and so introduces some computational overhead, but it can improve sensitivity.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--mimicBT2", - "description" : "[selective-alignment mode only] \nSet flags to mimic parameters similar to Bowtie2 with --no-discordant and --no-mixed flags. This increases disallows dovetailing reads, and discards orphans. Note, this does not impose the very strict parameters assumed by RSEM+Bowtie2, like gapless alignments. For that behavior, use the --mimic_strictBT2 flag below.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--mimic_strictBT2", - "description" : "[selective-alignment mode only] \nSet flags to mimic the very strict parameters used by RSEM+Bowtie2. This increases --min_score_fraction to 0.8, disallows dovetailing reads, discards orphans, and disallows gaps in alignments.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--softclip", - "description" : "[selective-alignment mode only] \nAllos soft-clipping of reads during selective-alignment. If this option is provided, then regions at the beginning or end of the read can be withheld from alignment without any effect on the resulting score (i.e. neither adding nor removing from the score). This will drastically reduce the penalty if there are mismatches at the beginning or end of the read due to e.g. low-quality bases or adapters. NOTE: Even with soft-clipping enabled, the read must still achieve a score of at least min_score_fraction * maximum achievable score, where the maximum achievable score is computed based on the full (un-clipped) read length.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--softclip_overhangs", - "description" : "[selective-alignment mode only] \nAllow soft-clipping of reads that overhang the beginning or ends of the transcript. In this case, the overhaning section of the read will simply be unaligned, and will not contribute or detract from the alignment score. The default policy is to force an end-to-end alignment of the entire read, so that overhanings will result in some deletion of nucleotides from the read.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--full_length_alignment", - "description" : "[selective-alignment mode only] \nPerform selective alignment over the full length of the read, beginning from the (approximate) initial mapping location and using extension alignment. This is in contrast with the default behavior which is to only perform alignment between the MEMs in the optimal chain (and before the first and after the last MEM if applicable). The default strategy forces the MEMs to belong to the alignment, but has the benefit that it can discover indels prior to the first hit shared between the read and reference. Except in very rare circumstances, the default mode should be more accurate.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--hard_filter", - "description" : "[selective-alignment mode only] \nInstead of weighting mappings by their alignment score, this flag will discard any mappings with sub-optimal alignment score. The default option of soft-filtering (i.e. weighting mappings by their alignment score) usually yields slightly more accurate abundance estimates but this flag may be desirable if you want more accurate 'naive' equivalence classes, rather than range factorized equivalence classes.\n", - "direction" : "input" - }, - { - "type" : "double", - "name" : "--min_aln_prob", - "description" : "The minimum number of fragments that must be assigned to the transcriptome for quantification to proceed.\n", - "example" : [ - 1.0E-5 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--write_mappings", - "alternatives" : [ - "-z" - ], - "description" : "If this option is provided, then the selective-alignment results will be written out in SAM-compatible format. By default, output will be directed to stdout, but an alternative file name can be provided instead.\n", - "direction" : "input" - }, - { - "type" : "file", - "name" : "--mapping_sam", - "description" : "Path to file that should output the selective-alignment results in SAM-compatible format. THis option must be provided while using --write_mappings", - "example" : [ - "mappings.sam" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "output", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--write_qualities", - "description" : "This flag only has meaning if mappings are being written (with --write_mappings/-z). If this flag is provided, then the output SAM file will contain quality strings as well as read sequences. Note that this can greatly increase the size of the output file.\n", - "direction" : "input" - }, - { - "type" : "string", - "name" : "--hit_filter_policy", - "description" : "[selective-alignment mode only]\nDetermines the policy by which hits are filtered in selective alignment. Filtering hits after chaining (the default) is more sensitive, but more computationally intensive, because it performs the chaining dynamic program for all hits. Filtering before chaining is faster, but some true hits may be missed. The options are BEFORE, AFTER, BOTH and NONE.\n", - "example" : [ - "AFTER" - ], - "required" : false, - "choices" : [ - "BEFORE", - "AFTER", - "BOTH", - "NONE" - ], - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Advance options", - "arguments" : [ - { - "type" : "boolean_true", - "name" : "--alternative_init_mode", - "description" : "Use an alternative strategy (rather than simple interpolation between) the online and uniform abundance estimates to initialize the EM / VBEM algorithm.\n", - "direction" : "input" - }, - { - "type" : "file", - "name" : "--aux_dir", - "description" : "The sub-directory of the quantification directory where auxiliary information e.g. bootstraps, bias parameters, etc. will be written.\n", - "example" : [ - "aux_info" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "output", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--skip_quant", - "description" : "Skip performing the actual transcript quantification (including any Gibbs sampling or bootstrapping).\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--dump_eq", - "description" : "Dump the simple equivalence class counts that were computed during mapping or alignment.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--dump_eq_weights", - "alternatives" : [ - "-d" - ], - "description" : "Dump conditional probabilities associated with transcripts when equivalence class information is being dumped to file. Note, this will dump the factorization that is actually used by salmon's offline phase for inference. If you are using range-factorized equivalence classes (the default) then the same transcript set may appear multiple times with different associated conditional probabilities.\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--min_assigned_frags", - "description" : "The minimum number of fragments that must be assigned to the transcriptome for quantification to proceed.\n", - "example" : [ - 10 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--reduce_GC_memory", - "description" : "If this option is selected, a more memory efficient (but slightly slower) representation is used to compute fragment GC content. Enabling this will reduce memory usage, but can also reduce speed. However, the results themselves will remain the same.\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--bias_speed_samp", - "description" : "The value at which the fragment length PMF is down-sampled when evaluating sequence-specific & GC fragment bias. Larger values speed up effective length correction, but may decrease the fidelity of bias modeling results.\n", - "example" : [ - 5 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--fld_max", - "description" : "The maximum fragment length to consider when building the empirical distribution\n", - "example" : [ - 1000 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--fld_mean", - "description" : "The mean used in the fragment length distribution prior\n", - "example" : [ - 250 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--fld_SD", - "description" : "The standard deviation used in the fragment length distribution prior\n", - "example" : [ - 25 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "double", - "name" : "--forgetting_factor", - "alternatives" : [ - "-f" - ], - "description" : "The forgetting factor used in the online learning schedule. A smallervalue results in quicker learning, but higher variance and may be unstable. A larger value results in slower learning but may be more stable. Value should be in the interval (0.5, 1.0].\n", - "example" : [ - 0.65 - ], - "required" : false, - "min" : 0.500000001, - "max" : 1.0, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--init_uniform", - "description" : "Initialize the offline inference with uniform parameters, rather than seeding with online parameters.\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--max_occs_per_hit", - "description" : "When collecting \\"hits\\" (MEMs), hits having more than max_occs_per_hit occurrences won't be considered.\n", - "example" : [ - 1000 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--max_read_occ", - "description" : "Reads \\"mapping\\" to more than this many places won't be considered.\n", - "example" : [ - 200 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--no_length_correction", - "description" : "Entirely disables length correction when estimating the abundance of transcripts. This option can be used with protocols where one expects that fragments derive from their underlying targets without regard to that target's length (e.g. QuantSeq)\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--no_effective_length_correction", - "description" : "Disables effective length correction when computing the probability that a fragment was generated from a transcript. If this flag is passed in,the fragment length distribution is not taken into account when computing this probability.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--no_single_frag_prob", - "description" : "Disables the estimation of an associated fragment length probability for single-end reads or for orphaned mappings in paired-end libraries. The default behavior is to consider the probability of all possible fragment lengths associated with the retained mapping. Enabling this flag (i.e. turning this default behavior off) will simply not attempt to estimate a fragment length probability in such cases.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--no_frag_length_dist", - "description" : "Don't consider concordance with the learned fragment length distribution when trying to determine the probability that a fragment has originated from a specified location. Normally, Fragments with unlikely lengths will be assigned a smaller relative probability than those with more likely lengths. When this flag is passed in, the observed fragment length has no effect on that fragment's a priori probability.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--no_bias_length_threshold", - "description" : "If this option is enabled, then no (lower) threshold will be set on how short bias correction can make effective lengths. This can increase the precision of bias correction, but harm robustness. The default correction applies a threshold.\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--num_bias_samples", - "description" : "Number of fragment mappings to use when learning the sequence-specific bias model.\n", - "example" : [ - 2000000 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--num_aux_model_samples", - "description" : "The first are used to train the auxiliary model parameters (e.g. fragment length distribution, bias, etc.). After ther first observations the auxiliary model parameters will be assumed to have converged and will be fixed.\n", - "example" : [ - 5000000 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--num_pre_aux_model_samples", - "description" : "The first will have their assignment likelihoods and contributions to the transcript abundances computed without applying any auxiliary models. The purpose of ignoring the auxiliary models for the first observations is to avoid applying these models before their parameters have been learned sufficiently well.\n", - "example" : [ - 5000 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--useEM", - "description" : "Use the traditional EM algorithm for optimization in the batch passes.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--useVBOpt", - "description" : "Use the Variational Bayesian EM [default]\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--range_factorization_bins", - "description" : "Factorizes the likelihood used in quantification by adopting a new notion of equivalence classes based on the conditional probabilities with which fragments are generated from different transcripts. This is a more fine-grained factorization than the normal rich equivalence classes. The default value (4) corresponds to the default used in Zakeri et al. 2017 (doi: 10.1093/bioinformatics/btx262), and larger values imply a more fine-grained factorization. If range factorization is enabled, a common value to select for this parameter is 4. A value of 0 signifies the use of basic rich equivalence classes.\n", - "example" : [ - 4 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--num_Gibbs_samples", - "description" : "Number of Gibbs sampling rounds to perform.\n", - "example" : [ - 0 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--no_Gamma_draw", - "description" : "This switch will disable drawing transcript fractions from a Gamma distribution during Gibbs sampling. In this case the sampler does not account for shot-noise, but only assignment ambiguity\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--num_bootstraps", - "description" : "Number of bootstrap samples to generate. Note: This is mutually exclusive with Gibbs sampling.\n", - "example" : [ - 0 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--bootstrap_reproject", - "description" : "This switch will learn the parameter distribution from the bootstrapped counts for each sample, but will reproject those parameters onto the original equivalence class counts.\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--thinning_factor", - "description" : "Number of steps to discard for every sample kept from the Gibbs chain. The larger this number, the less chance that subsequent samples are auto-correlated, but the slower sampling becomes.\n", - "example" : [ - 16 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--quiet", - "alternatives" : [ - "-q" - ], - "description" : "Be quiet while doing quantification (don't write informative output to the console unless something goes wrong).\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--per_transcript_prior", - "description" : "The prior (either the default or the argument provided via --vb_prior) will be interpreted as a transcript-level prior (i.e. each transcript will be given a prior read count of this value)\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--per_nucleotide_prior", - "description" : "The prior (either the default or the argument provided via --vb_prior) will be interpreted as a nucleotide-level prior (i.e. each nucleotide will be given a prior read count of this value)\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--sig_digits", - "description" : "The number of significant digits to write when outputting the EffectiveLength and NumReads columns\n", - "example" : [ - 3 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "double", - "name" : "--vb_prior", - "description" : "The prior that will be used in the VBEM algorithm. This is interpreted as a per-transcript prior, unless the --per_nucleotide_prior flag is also given. If the --per_nucleotide_prior flag is given, this is used as a nucleotide-level prior. If the default is used, it will be divided by 1000 before being used as a nucleotide-level prior, i.e. the default per-nucleotide prior will be 1e-5.\n", - "example" : [ - 0.01 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--write_orphan_links", - "description" : "Write the transcripts that are linked by orphaned reads.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--write_unmapped_names", - "description" : "Write the names of un-mapped reads to the file unmapped_names.txt in the auxiliary directory.\n", - "direction" : "input" - } - ] - }, - { - "name" : "Alignment-specific options", - "arguments" : [ - { - "type" : "boolean_true", - "name" : "--no_error_model", - "description" : "Turn off the alignment error model, which takes into account the the observed frequency of different types of mismatches / indels when computing the likelihood of a given alignment. Turning this off can speed up alignment-based salmon, but can harm quantification accuracy.\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--num_error_bins", - "description" : "The number of bins into which to divide each read when learning and applying the error model. For example, a value of 10 would mean that effectively, a separate error model is leared and applied to each 10th of the read, while a value of 3 would mean that a separate error model is applied to the read beginning (first third), middle (second third) and end (final third).\n", - "example" : [ - 6 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--sample_out", - "alternatives" : [ - "-s" - ], - "description" : "Write a \\"postSample.bam\\" file in the output directory that will sample the input alignments according to the estimated transcript abundances. If you're going to perform downstream analysis of the alignments with tools which don't, themselves, take fragment assignment ambiguity into account, you should use this output.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--sample_unaligned", - "alternatives" : [ - "-u" - ], - "description" : "In addition to sampling the aligned reads, also write the un-aligned reads to \\"postSample.bam\\".\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--gencode", - "description" : "This flag will expect the input transcript fasta to be in GENCODE format, and will split the transcript name at the first '|' character. These reduced names will be used in the output and when looking for these transcripts in a gene to transcript GTF.\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--mapping_cache_memory_limit", - "description" : "If the file contained fewer than this many mapped reads, then just keep the data in memory for subsequent rounds of inference. Obviously, this value should not be too large if you wish to keep a low memory usage, but setting it large enough to accommodate all of the mapped read can substantially speed up inference on \\"small\\" files that contain only a few million reads.\n", - "example" : [ - 2000000 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - } - ], - "resources" : [ - { - "type" : "bash_script", - "path" : "script.sh", - "is_executable" : true - } - ], - "description" : "Salmon is a tool for wicked-fast transcript quantification from RNA-seq data. It can either make use of pre-computed alignments (in the form of a SAM/BAM file) to the transcripts rather than the raw reads, or can be run in the mapping-based mode. \n", - "test_resources" : [ - { - "type" : "bash_script", - "path" : "test.sh", - "is_executable" : true - } - ], - "status" : "enabled", - "requirements" : { - "commands" : [ - "ps" - ] - }, - "keywords" : [ - "Transcriptome", - "Quantification" - ], - "license" : "GPL-3.0", - "references" : { - "doi" : [ - "10.1038/nmeth.4197" - ] - }, - "links" : { - "repository" : "https://github.com/COMBINE-lab/salmon", - "homepage" : "https://salmon.readthedocs.io/en/latest/salmon.html", - "documentation" : "https://salmon.readthedocs.io/en/latest/salmon.html" - }, - "runners" : [ - { - "type" : "executable", - "id" : "executable", - "docker_setup_strategy" : "ifneedbepullelsecachedbuild" - }, - { - "type" : "nextflow", - "id" : "nextflow", - "directives" : { - "tag" : "$id" - }, - "auto" : { - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false - }, - "config" : { - "labels" : { - "mem1gb" : "memory = 1000000000.B", - "mem2gb" : "memory = 2000000000.B", - "mem5gb" : "memory = 5000000000.B", - "mem10gb" : "memory = 10000000000.B", - "mem20gb" : "memory = 20000000000.B", - "mem50gb" : "memory = 50000000000.B", - "mem100gb" : "memory = 100000000000.B", - "mem200gb" : "memory = 200000000000.B", - "mem500gb" : "memory = 500000000000.B", - "mem1tb" : "memory = 1000000000000.B", - "mem2tb" : "memory = 2000000000000.B", - "mem5tb" : "memory = 5000000000000.B", - "mem10tb" : "memory = 10000000000000.B", - "mem20tb" : "memory = 20000000000000.B", - "mem50tb" : "memory = 50000000000000.B", - "mem100tb" : "memory = 100000000000000.B", - "mem200tb" : "memory = 200000000000000.B", - "mem500tb" : "memory = 500000000000000.B", - "mem1gib" : "memory = 1073741824.B", - "mem2gib" : "memory = 2147483648.B", - "mem4gib" : "memory = 4294967296.B", - "mem8gib" : "memory = 8589934592.B", - "mem16gib" : "memory = 17179869184.B", - "mem32gib" : "memory = 34359738368.B", - "mem64gib" : "memory = 68719476736.B", - "mem128gib" : "memory = 137438953472.B", - "mem256gib" : "memory = 274877906944.B", - "mem512gib" : "memory = 549755813888.B", - "mem1tib" : "memory = 1099511627776.B", - "mem2tib" : "memory = 2199023255552.B", - "mem4tib" : "memory = 4398046511104.B", - "mem8tib" : "memory = 8796093022208.B", - "mem16tib" : "memory = 17592186044416.B", - "mem32tib" : "memory = 35184372088832.B", - "mem64tib" : "memory = 70368744177664.B", - "mem128tib" : "memory = 140737488355328.B", - "mem256tib" : "memory = 281474976710656.B", - "mem512tib" : "memory = 562949953421312.B", - "cpu1" : "cpus = 1", - "cpu2" : "cpus = 2", - "cpu5" : "cpus = 5", - "cpu10" : "cpus = 10", - "cpu20" : "cpus = 20", - "cpu50" : "cpus = 50", - "cpu100" : "cpus = 100", - "cpu200" : "cpus = 200", - "cpu500" : "cpus = 500", - "cpu1000" : "cpus = 1000" - } - }, - "debug" : false, - "container" : "docker" - } - ], - "engines" : [ - { - "type" : "docker", - "id" : "docker", - "image" : "quay.io/biocontainers/salmon:1.10.2--hecfa306_0", - "target_registry" : "images.viash-hub.com", - "target_tag" : "v0.1.0", - "namespace_separator" : "/", - "setup" : [ - { - "type" : "docker", - "run" : [ - "salmon index -v 2>&1 | sed 's/salmon \\\\([0-9.]*\\\\)/salmon: \\\\1/' > /var/software_versions.txt\n" - ] - } - ] - }, - { - "type" : "native", - "id" : "native" - } - ], - "build_info" : { - "config" : "/workdir/root/repo/src/salmon/salmon_quant/config.vsh.yaml", - "runner" : "nextflow", - "engine" : "docker|native", - "output" : "target/nextflow/salmon/salmon_quant", - "viash_version" : "0.9.0-RC6", - "git_commit" : "b84b29747d0635f2ac83ea63b496be9a9edb6724", - "git_remote" : "https://github.com/viash-hub/biobox" - }, - "package_config" : { - "name" : "biobox", - "version" : "v0.1.0", - "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC6", - "source" : "src", - "target" : "target", - "config_mods" : [ - ".requirements.commands := ['ps']\n", - ".engines += { type: \\"native\\" }", - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - ], - "keywords" : [ - "bioinformatics", - "modules", - "sequencing" - ], - "license" : "MIT", - "organization" : "vsh", - "links" : { - "repository" : "https://github.com/viash-hub/biobox", - "issue_tracker" : "https://github.com/viash-hub/biobox/issues" - } - } -}''')) -] - -// resolve dependencies dependencies (if any) - - -// inner workflow -// inner workflow hook -def innerWorkflowFactory(args) { - def rawScript = '''set -e -tempscript=".viash_script.sh" -cat > "$tempscript" << VIASHMAIN -#!/bin/bash - -set -e - -## VIASH START -# The following code has been auto-generated by Viash. -$( if [ ! -z ${VIASH_PAR_LIB_TYPE+x} ]; then echo "${VIASH_PAR_LIB_TYPE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_lib_type='&'#" ; else echo "# par_lib_type="; fi ) -$( if [ ! -z ${VIASH_PAR_INDEX+x} ]; then echo "${VIASH_PAR_INDEX}" | sed "s#'#'\\"'\\"'#g;s#.*#par_index='&'#" ; else echo "# par_index="; fi ) -$( if [ ! -z ${VIASH_PAR_UNMATED_READS+x} ]; then echo "${VIASH_PAR_UNMATED_READS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_unmated_reads='&'#" ; else echo "# par_unmated_reads="; fi ) -$( if [ ! -z ${VIASH_PAR_MATES1+x} ]; then echo "${VIASH_PAR_MATES1}" | sed "s#'#'\\"'\\"'#g;s#.*#par_mates1='&'#" ; else echo "# par_mates1="; fi ) -$( if [ ! -z ${VIASH_PAR_MATES2+x} ]; then echo "${VIASH_PAR_MATES2}" | sed "s#'#'\\"'\\"'#g;s#.*#par_mates2='&'#" ; else echo "# par_mates2="; fi ) -$( if [ ! -z ${VIASH_PAR_DISCARD_ORPHANS+x} ]; then echo "${VIASH_PAR_DISCARD_ORPHANS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_discard_orphans='&'#" ; else echo "# par_discard_orphans="; fi ) -$( if [ ! -z ${VIASH_PAR_ALIGNMENTS+x} ]; then echo "${VIASH_PAR_ALIGNMENTS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_alignments='&'#" ; else echo "# par_alignments="; fi ) -$( if [ ! -z ${VIASH_PAR_EQCLASSES+x} ]; then echo "${VIASH_PAR_EQCLASSES}" | sed "s#'#'\\"'\\"'#g;s#.*#par_eqclasses='&'#" ; else echo "# par_eqclasses="; fi ) -$( if [ ! -z ${VIASH_PAR_TARGETS+x} ]; then echo "${VIASH_PAR_TARGETS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_targets='&'#" ; else echo "# par_targets="; fi ) -$( if [ ! -z ${VIASH_PAR_ONT+x} ]; then echo "${VIASH_PAR_ONT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_ont='&'#" ; else echo "# par_ont="; fi ) -$( if [ ! -z ${VIASH_PAR_OUTPUT+x} ]; then echo "${VIASH_PAR_OUTPUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_output='&'#" ; else echo "# par_output="; fi ) -$( if [ ! -z ${VIASH_PAR_QUANT_RESULTS+x} ]; then echo "${VIASH_PAR_QUANT_RESULTS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_quant_results='&'#" ; else echo "# par_quant_results="; fi ) -$( if [ ! -z ${VIASH_PAR_SEQ_BIAS+x} ]; then echo "${VIASH_PAR_SEQ_BIAS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_seq_bias='&'#" ; else echo "# par_seq_bias="; fi ) -$( if [ ! -z ${VIASH_PAR_GC_BIAS+x} ]; then echo "${VIASH_PAR_GC_BIAS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_gc_bias='&'#" ; else echo "# par_gc_bias="; fi ) -$( if [ ! -z ${VIASH_PAR_POS_BIAS+x} ]; then echo "${VIASH_PAR_POS_BIAS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_pos_bias='&'#" ; else echo "# par_pos_bias="; fi ) -$( if [ ! -z ${VIASH_PAR_INCOMPAT_PRIOR+x} ]; then echo "${VIASH_PAR_INCOMPAT_PRIOR}" | sed "s#'#'\\"'\\"'#g;s#.*#par_incompat_prior='&'#" ; else echo "# par_incompat_prior="; fi ) -$( if [ ! -z ${VIASH_PAR_GENE_MAP+x} ]; then echo "${VIASH_PAR_GENE_MAP}" | sed "s#'#'\\"'\\"'#g;s#.*#par_gene_map='&'#" ; else echo "# par_gene_map="; fi ) -$( if [ ! -z ${VIASH_PAR_AUX_TARGET_FILE+x} ]; then echo "${VIASH_PAR_AUX_TARGET_FILE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_aux_target_file='&'#" ; else echo "# par_aux_target_file="; fi ) -$( if [ ! -z ${VIASH_PAR_META+x} ]; then echo "${VIASH_PAR_META}" | sed "s#'#'\\"'\\"'#g;s#.*#par_meta='&'#" ; else echo "# par_meta="; fi ) -$( if [ ! -z ${VIASH_PAR_SCORE_EXP+x} ]; then echo "${VIASH_PAR_SCORE_EXP}" | sed "s#'#'\\"'\\"'#g;s#.*#par_score_exp='&'#" ; else echo "# par_score_exp="; fi ) -$( if [ ! -z ${VIASH_PAR_DISCARD_ORPHANS_QUASI+x} ]; then echo "${VIASH_PAR_DISCARD_ORPHANS_QUASI}" | sed "s#'#'\\"'\\"'#g;s#.*#par_discard_orphans_quasi='&'#" ; else echo "# par_discard_orphans_quasi="; fi ) -$( if [ ! -z ${VIASH_PAR_CONSENSUS_SLACK+x} ]; then echo "${VIASH_PAR_CONSENSUS_SLACK}" | sed "s#'#'\\"'\\"'#g;s#.*#par_consensus_slack='&'#" ; else echo "# par_consensus_slack="; fi ) -$( if [ ! -z ${VIASH_PAR_PRE_MERGE_CHAIN_SUB_THRESH+x} ]; then echo "${VIASH_PAR_PRE_MERGE_CHAIN_SUB_THRESH}" | sed "s#'#'\\"'\\"'#g;s#.*#par_pre_merge_chain_sub_thresh='&'#" ; else echo "# par_pre_merge_chain_sub_thresh="; fi ) -$( if [ ! -z ${VIASH_PAR_POST_MERGE_CHAIN_SUB_THRESH+x} ]; then echo "${VIASH_PAR_POST_MERGE_CHAIN_SUB_THRESH}" | sed "s#'#'\\"'\\"'#g;s#.*#par_post_merge_chain_sub_thresh='&'#" ; else echo "# par_post_merge_chain_sub_thresh="; fi ) -$( if [ ! -z ${VIASH_PAR_ORPHAN_CHAIN_SUB_THRESH+x} ]; then echo "${VIASH_PAR_ORPHAN_CHAIN_SUB_THRESH}" | sed "s#'#'\\"'\\"'#g;s#.*#par_orphan_chain_sub_thresh='&'#" ; else echo "# par_orphan_chain_sub_thresh="; fi ) -$( if [ ! -z ${VIASH_PAR_MIN_SCORE_FRACTION+x} ]; then echo "${VIASH_PAR_MIN_SCORE_FRACTION}" | sed "s#'#'\\"'\\"'#g;s#.*#par_min_score_fraction='&'#" ; else echo "# par_min_score_fraction="; fi ) -$( if [ ! -z ${VIASH_PAR_MISMATCH_SEED_SKIP+x} ]; then echo "${VIASH_PAR_MISMATCH_SEED_SKIP}" | sed "s#'#'\\"'\\"'#g;s#.*#par_mismatch_seed_skip='&'#" ; else echo "# par_mismatch_seed_skip="; fi ) -$( if [ ! -z ${VIASH_PAR_DISABLE_CHAINING_HEURISTIC+x} ]; then echo "${VIASH_PAR_DISABLE_CHAINING_HEURISTIC}" | sed "s#'#'\\"'\\"'#g;s#.*#par_disable_chaining_heuristic='&'#" ; else echo "# par_disable_chaining_heuristic="; fi ) -$( if [ ! -z ${VIASH_PAR_DECOY_THRESHOLD+x} ]; then echo "${VIASH_PAR_DECOY_THRESHOLD}" | sed "s#'#'\\"'\\"'#g;s#.*#par_decoy_threshold='&'#" ; else echo "# par_decoy_threshold="; fi ) -$( if [ ! -z ${VIASH_PAR_MA+x} ]; then echo "${VIASH_PAR_MA}" | sed "s#'#'\\"'\\"'#g;s#.*#par_ma='&'#" ; else echo "# par_ma="; fi ) -$( if [ ! -z ${VIASH_PAR_MP+x} ]; then echo "${VIASH_PAR_MP}" | sed "s#'#'\\"'\\"'#g;s#.*#par_mp='&'#" ; else echo "# par_mp="; fi ) -$( if [ ! -z ${VIASH_PAR_GO+x} ]; then echo "${VIASH_PAR_GO}" | sed "s#'#'\\"'\\"'#g;s#.*#par_go='&'#" ; else echo "# par_go="; fi ) -$( if [ ! -z ${VIASH_PAR_GE+x} ]; then echo "${VIASH_PAR_GE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_ge='&'#" ; else echo "# par_ge="; fi ) -$( if [ ! -z ${VIASH_PAR_BANDWIDTH+x} ]; then echo "${VIASH_PAR_BANDWIDTH}" | sed "s#'#'\\"'\\"'#g;s#.*#par_bandwidth='&'#" ; else echo "# par_bandwidth="; fi ) -$( if [ ! -z ${VIASH_PAR_ALLOW_DOVETAIL+x} ]; then echo "${VIASH_PAR_ALLOW_DOVETAIL}" | sed "s#'#'\\"'\\"'#g;s#.*#par_allow_dovetail='&'#" ; else echo "# par_allow_dovetail="; fi ) -$( if [ ! -z ${VIASH_PAR_RECOVER_ORPHANS+x} ]; then echo "${VIASH_PAR_RECOVER_ORPHANS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_recover_orphans='&'#" ; else echo "# par_recover_orphans="; fi ) -$( if [ ! -z ${VIASH_PAR_MIMICBT2+x} ]; then echo "${VIASH_PAR_MIMICBT2}" | sed "s#'#'\\"'\\"'#g;s#.*#par_mimicBT2='&'#" ; else echo "# par_mimicBT2="; fi ) -$( if [ ! -z ${VIASH_PAR_MIMIC_STRICTBT2+x} ]; then echo "${VIASH_PAR_MIMIC_STRICTBT2}" | sed "s#'#'\\"'\\"'#g;s#.*#par_mimic_strictBT2='&'#" ; else echo "# par_mimic_strictBT2="; fi ) -$( if [ ! -z ${VIASH_PAR_SOFTCLIP+x} ]; then echo "${VIASH_PAR_SOFTCLIP}" | sed "s#'#'\\"'\\"'#g;s#.*#par_softclip='&'#" ; else echo "# par_softclip="; fi ) -$( if [ ! -z ${VIASH_PAR_SOFTCLIP_OVERHANGS+x} ]; then echo "${VIASH_PAR_SOFTCLIP_OVERHANGS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_softclip_overhangs='&'#" ; else echo "# par_softclip_overhangs="; fi ) -$( if [ ! -z ${VIASH_PAR_FULL_LENGTH_ALIGNMENT+x} ]; then echo "${VIASH_PAR_FULL_LENGTH_ALIGNMENT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_full_length_alignment='&'#" ; else echo "# par_full_length_alignment="; fi ) -$( if [ ! -z ${VIASH_PAR_HARD_FILTER+x} ]; then echo "${VIASH_PAR_HARD_FILTER}" | sed "s#'#'\\"'\\"'#g;s#.*#par_hard_filter='&'#" ; else echo "# par_hard_filter="; fi ) -$( if [ ! -z ${VIASH_PAR_MIN_ALN_PROB+x} ]; then echo "${VIASH_PAR_MIN_ALN_PROB}" | sed "s#'#'\\"'\\"'#g;s#.*#par_min_aln_prob='&'#" ; else echo "# par_min_aln_prob="; fi ) -$( if [ ! -z ${VIASH_PAR_WRITE_MAPPINGS+x} ]; then echo "${VIASH_PAR_WRITE_MAPPINGS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_write_mappings='&'#" ; else echo "# par_write_mappings="; fi ) -$( if [ ! -z ${VIASH_PAR_MAPPING_SAM+x} ]; then echo "${VIASH_PAR_MAPPING_SAM}" | sed "s#'#'\\"'\\"'#g;s#.*#par_mapping_sam='&'#" ; else echo "# par_mapping_sam="; fi ) -$( if [ ! -z ${VIASH_PAR_WRITE_QUALITIES+x} ]; then echo "${VIASH_PAR_WRITE_QUALITIES}" | sed "s#'#'\\"'\\"'#g;s#.*#par_write_qualities='&'#" ; else echo "# par_write_qualities="; fi ) -$( if [ ! -z ${VIASH_PAR_HIT_FILTER_POLICY+x} ]; then echo "${VIASH_PAR_HIT_FILTER_POLICY}" | sed "s#'#'\\"'\\"'#g;s#.*#par_hit_filter_policy='&'#" ; else echo "# par_hit_filter_policy="; fi ) -$( if [ ! -z ${VIASH_PAR_ALTERNATIVE_INIT_MODE+x} ]; then echo "${VIASH_PAR_ALTERNATIVE_INIT_MODE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_alternative_init_mode='&'#" ; else echo "# par_alternative_init_mode="; fi ) -$( if [ ! -z ${VIASH_PAR_AUX_DIR+x} ]; then echo "${VIASH_PAR_AUX_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#par_aux_dir='&'#" ; else echo "# par_aux_dir="; fi ) -$( if [ ! -z ${VIASH_PAR_SKIP_QUANT+x} ]; then echo "${VIASH_PAR_SKIP_QUANT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_skip_quant='&'#" ; else echo "# par_skip_quant="; fi ) -$( if [ ! -z ${VIASH_PAR_DUMP_EQ+x} ]; then echo "${VIASH_PAR_DUMP_EQ}" | sed "s#'#'\\"'\\"'#g;s#.*#par_dump_eq='&'#" ; else echo "# par_dump_eq="; fi ) -$( if [ ! -z ${VIASH_PAR_DUMP_EQ_WEIGHTS+x} ]; then echo "${VIASH_PAR_DUMP_EQ_WEIGHTS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_dump_eq_weights='&'#" ; else echo "# par_dump_eq_weights="; fi ) -$( if [ ! -z ${VIASH_PAR_MIN_ASSIGNED_FRAGS+x} ]; then echo "${VIASH_PAR_MIN_ASSIGNED_FRAGS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_min_assigned_frags='&'#" ; else echo "# par_min_assigned_frags="; fi ) -$( if [ ! -z ${VIASH_PAR_REDUCE_GC_MEMORY+x} ]; then echo "${VIASH_PAR_REDUCE_GC_MEMORY}" | sed "s#'#'\\"'\\"'#g;s#.*#par_reduce_GC_memory='&'#" ; else echo "# par_reduce_GC_memory="; fi ) -$( if [ ! -z ${VIASH_PAR_BIAS_SPEED_SAMP+x} ]; then echo "${VIASH_PAR_BIAS_SPEED_SAMP}" | sed "s#'#'\\"'\\"'#g;s#.*#par_bias_speed_samp='&'#" ; else echo "# par_bias_speed_samp="; fi ) -$( if [ ! -z ${VIASH_PAR_FLD_MAX+x} ]; then echo "${VIASH_PAR_FLD_MAX}" | sed "s#'#'\\"'\\"'#g;s#.*#par_fld_max='&'#" ; else echo "# par_fld_max="; fi ) -$( if [ ! -z ${VIASH_PAR_FLD_MEAN+x} ]; then echo "${VIASH_PAR_FLD_MEAN}" | sed "s#'#'\\"'\\"'#g;s#.*#par_fld_mean='&'#" ; else echo "# par_fld_mean="; fi ) -$( if [ ! -z ${VIASH_PAR_FLD_SD+x} ]; then echo "${VIASH_PAR_FLD_SD}" | sed "s#'#'\\"'\\"'#g;s#.*#par_fld_SD='&'#" ; else echo "# par_fld_SD="; fi ) -$( if [ ! -z ${VIASH_PAR_FORGETTING_FACTOR+x} ]; then echo "${VIASH_PAR_FORGETTING_FACTOR}" | sed "s#'#'\\"'\\"'#g;s#.*#par_forgetting_factor='&'#" ; else echo "# par_forgetting_factor="; fi ) -$( if [ ! -z ${VIASH_PAR_INIT_UNIFORM+x} ]; then echo "${VIASH_PAR_INIT_UNIFORM}" | sed "s#'#'\\"'\\"'#g;s#.*#par_init_uniform='&'#" ; else echo "# par_init_uniform="; fi ) -$( if [ ! -z ${VIASH_PAR_MAX_OCCS_PER_HIT+x} ]; then echo "${VIASH_PAR_MAX_OCCS_PER_HIT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_max_occs_per_hit='&'#" ; else echo "# par_max_occs_per_hit="; fi ) -$( if [ ! -z ${VIASH_PAR_MAX_READ_OCC+x} ]; then echo "${VIASH_PAR_MAX_READ_OCC}" | sed "s#'#'\\"'\\"'#g;s#.*#par_max_read_occ='&'#" ; else echo "# par_max_read_occ="; fi ) -$( if [ ! -z ${VIASH_PAR_NO_LENGTH_CORRECTION+x} ]; then echo "${VIASH_PAR_NO_LENGTH_CORRECTION}" | sed "s#'#'\\"'\\"'#g;s#.*#par_no_length_correction='&'#" ; else echo "# par_no_length_correction="; fi ) -$( if [ ! -z ${VIASH_PAR_NO_EFFECTIVE_LENGTH_CORRECTION+x} ]; then echo "${VIASH_PAR_NO_EFFECTIVE_LENGTH_CORRECTION}" | sed "s#'#'\\"'\\"'#g;s#.*#par_no_effective_length_correction='&'#" ; else echo "# par_no_effective_length_correction="; fi ) -$( if [ ! -z ${VIASH_PAR_NO_SINGLE_FRAG_PROB+x} ]; then echo "${VIASH_PAR_NO_SINGLE_FRAG_PROB}" | sed "s#'#'\\"'\\"'#g;s#.*#par_no_single_frag_prob='&'#" ; else echo "# par_no_single_frag_prob="; fi ) -$( if [ ! -z ${VIASH_PAR_NO_FRAG_LENGTH_DIST+x} ]; then echo "${VIASH_PAR_NO_FRAG_LENGTH_DIST}" | sed "s#'#'\\"'\\"'#g;s#.*#par_no_frag_length_dist='&'#" ; else echo "# par_no_frag_length_dist="; fi ) -$( if [ ! -z ${VIASH_PAR_NO_BIAS_LENGTH_THRESHOLD+x} ]; then echo "${VIASH_PAR_NO_BIAS_LENGTH_THRESHOLD}" | sed "s#'#'\\"'\\"'#g;s#.*#par_no_bias_length_threshold='&'#" ; else echo "# par_no_bias_length_threshold="; fi ) -$( if [ ! -z ${VIASH_PAR_NUM_BIAS_SAMPLES+x} ]; then echo "${VIASH_PAR_NUM_BIAS_SAMPLES}" | sed "s#'#'\\"'\\"'#g;s#.*#par_num_bias_samples='&'#" ; else echo "# par_num_bias_samples="; fi ) -$( if [ ! -z ${VIASH_PAR_NUM_AUX_MODEL_SAMPLES+x} ]; then echo "${VIASH_PAR_NUM_AUX_MODEL_SAMPLES}" | sed "s#'#'\\"'\\"'#g;s#.*#par_num_aux_model_samples='&'#" ; else echo "# par_num_aux_model_samples="; fi ) -$( if [ ! -z ${VIASH_PAR_NUM_PRE_AUX_MODEL_SAMPLES+x} ]; then echo "${VIASH_PAR_NUM_PRE_AUX_MODEL_SAMPLES}" | sed "s#'#'\\"'\\"'#g;s#.*#par_num_pre_aux_model_samples='&'#" ; else echo "# par_num_pre_aux_model_samples="; fi ) -$( if [ ! -z ${VIASH_PAR_USEEM+x} ]; then echo "${VIASH_PAR_USEEM}" | sed "s#'#'\\"'\\"'#g;s#.*#par_useEM='&'#" ; else echo "# par_useEM="; fi ) -$( if [ ! -z ${VIASH_PAR_USEVBOPT+x} ]; then echo "${VIASH_PAR_USEVBOPT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_useVBOpt='&'#" ; else echo "# par_useVBOpt="; fi ) -$( if [ ! -z ${VIASH_PAR_RANGE_FACTORIZATION_BINS+x} ]; then echo "${VIASH_PAR_RANGE_FACTORIZATION_BINS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_range_factorization_bins='&'#" ; else echo "# par_range_factorization_bins="; fi ) -$( if [ ! -z ${VIASH_PAR_NUM_GIBBS_SAMPLES+x} ]; then echo "${VIASH_PAR_NUM_GIBBS_SAMPLES}" | sed "s#'#'\\"'\\"'#g;s#.*#par_num_Gibbs_samples='&'#" ; else echo "# par_num_Gibbs_samples="; fi ) -$( if [ ! -z ${VIASH_PAR_NO_GAMMA_DRAW+x} ]; then echo "${VIASH_PAR_NO_GAMMA_DRAW}" | sed "s#'#'\\"'\\"'#g;s#.*#par_no_Gamma_draw='&'#" ; else echo "# par_no_Gamma_draw="; fi ) -$( if [ ! -z ${VIASH_PAR_NUM_BOOTSTRAPS+x} ]; then echo "${VIASH_PAR_NUM_BOOTSTRAPS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_num_bootstraps='&'#" ; else echo "# par_num_bootstraps="; fi ) -$( if [ ! -z ${VIASH_PAR_BOOTSTRAP_REPROJECT+x} ]; then echo "${VIASH_PAR_BOOTSTRAP_REPROJECT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_bootstrap_reproject='&'#" ; else echo "# par_bootstrap_reproject="; fi ) -$( if [ ! -z ${VIASH_PAR_THINNING_FACTOR+x} ]; then echo "${VIASH_PAR_THINNING_FACTOR}" | sed "s#'#'\\"'\\"'#g;s#.*#par_thinning_factor='&'#" ; else echo "# par_thinning_factor="; fi ) -$( if [ ! -z ${VIASH_PAR_QUIET+x} ]; then echo "${VIASH_PAR_QUIET}" | sed "s#'#'\\"'\\"'#g;s#.*#par_quiet='&'#" ; else echo "# par_quiet="; fi ) -$( if [ ! -z ${VIASH_PAR_PER_TRANSCRIPT_PRIOR+x} ]; then echo "${VIASH_PAR_PER_TRANSCRIPT_PRIOR}" | sed "s#'#'\\"'\\"'#g;s#.*#par_per_transcript_prior='&'#" ; else echo "# par_per_transcript_prior="; fi ) -$( if [ ! -z ${VIASH_PAR_PER_NUCLEOTIDE_PRIOR+x} ]; then echo "${VIASH_PAR_PER_NUCLEOTIDE_PRIOR}" | sed "s#'#'\\"'\\"'#g;s#.*#par_per_nucleotide_prior='&'#" ; else echo "# par_per_nucleotide_prior="; fi ) -$( if [ ! -z ${VIASH_PAR_SIG_DIGITS+x} ]; then echo "${VIASH_PAR_SIG_DIGITS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_sig_digits='&'#" ; else echo "# par_sig_digits="; fi ) -$( if [ ! -z ${VIASH_PAR_VB_PRIOR+x} ]; then echo "${VIASH_PAR_VB_PRIOR}" | sed "s#'#'\\"'\\"'#g;s#.*#par_vb_prior='&'#" ; else echo "# par_vb_prior="; fi ) -$( if [ ! -z ${VIASH_PAR_WRITE_ORPHAN_LINKS+x} ]; then echo "${VIASH_PAR_WRITE_ORPHAN_LINKS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_write_orphan_links='&'#" ; else echo "# par_write_orphan_links="; fi ) -$( if [ ! -z ${VIASH_PAR_WRITE_UNMAPPED_NAMES+x} ]; then echo "${VIASH_PAR_WRITE_UNMAPPED_NAMES}" | sed "s#'#'\\"'\\"'#g;s#.*#par_write_unmapped_names='&'#" ; else echo "# par_write_unmapped_names="; fi ) -$( if [ ! -z ${VIASH_PAR_NO_ERROR_MODEL+x} ]; then echo "${VIASH_PAR_NO_ERROR_MODEL}" | sed "s#'#'\\"'\\"'#g;s#.*#par_no_error_model='&'#" ; else echo "# par_no_error_model="; fi ) -$( if [ ! -z ${VIASH_PAR_NUM_ERROR_BINS+x} ]; then echo "${VIASH_PAR_NUM_ERROR_BINS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_num_error_bins='&'#" ; else echo "# par_num_error_bins="; fi ) -$( if [ ! -z ${VIASH_PAR_SAMPLE_OUT+x} ]; then echo "${VIASH_PAR_SAMPLE_OUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_sample_out='&'#" ; else echo "# par_sample_out="; fi ) -$( if [ ! -z ${VIASH_PAR_SAMPLE_UNALIGNED+x} ]; then echo "${VIASH_PAR_SAMPLE_UNALIGNED}" | sed "s#'#'\\"'\\"'#g;s#.*#par_sample_unaligned='&'#" ; else echo "# par_sample_unaligned="; fi ) -$( if [ ! -z ${VIASH_PAR_GENCODE+x} ]; then echo "${VIASH_PAR_GENCODE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_gencode='&'#" ; else echo "# par_gencode="; fi ) -$( if [ ! -z ${VIASH_PAR_MAPPING_CACHE_MEMORY_LIMIT+x} ]; then echo "${VIASH_PAR_MAPPING_CACHE_MEMORY_LIMIT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_mapping_cache_memory_limit='&'#" ; else echo "# par_mapping_cache_memory_limit="; fi ) -$( if [ ! -z ${VIASH_META_NAME+x} ]; then echo "${VIASH_META_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_name='&'#" ; else echo "# meta_name="; fi ) -$( if [ ! -z ${VIASH_META_FUNCTIONALITY_NAME+x} ]; then echo "${VIASH_META_FUNCTIONALITY_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_functionality_name='&'#" ; else echo "# meta_functionality_name="; fi ) -$( if [ ! -z ${VIASH_META_RESOURCES_DIR+x} ]; then echo "${VIASH_META_RESOURCES_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_resources_dir='&'#" ; else echo "# meta_resources_dir="; fi ) -$( if [ ! -z ${VIASH_META_EXECUTABLE+x} ]; then echo "${VIASH_META_EXECUTABLE}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_executable='&'#" ; else echo "# meta_executable="; fi ) -$( if [ ! -z ${VIASH_META_CONFIG+x} ]; then echo "${VIASH_META_CONFIG}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_config='&'#" ; else echo "# meta_config="; fi ) -$( if [ ! -z ${VIASH_META_TEMP_DIR+x} ]; then echo "${VIASH_META_TEMP_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_temp_dir='&'#" ; else echo "# meta_temp_dir="; fi ) -$( if [ ! -z ${VIASH_META_CPUS+x} ]; then echo "${VIASH_META_CPUS}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_cpus='&'#" ; else echo "# meta_cpus="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_B+x} ]; then echo "${VIASH_META_MEMORY_B}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_b='&'#" ; else echo "# meta_memory_b="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KB+x} ]; then echo "${VIASH_META_MEMORY_KB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kb='&'#" ; else echo "# meta_memory_kb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MB+x} ]; then echo "${VIASH_META_MEMORY_MB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mb='&'#" ; else echo "# meta_memory_mb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GB+x} ]; then echo "${VIASH_META_MEMORY_GB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gb='&'#" ; else echo "# meta_memory_gb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TB+x} ]; then echo "${VIASH_META_MEMORY_TB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tb='&'#" ; else echo "# meta_memory_tb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PB+x} ]; then echo "${VIASH_META_MEMORY_PB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pb='&'#" ; else echo "# meta_memory_pb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KIB+x} ]; then echo "${VIASH_META_MEMORY_KIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kib='&'#" ; else echo "# meta_memory_kib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MIB+x} ]; then echo "${VIASH_META_MEMORY_MIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mib='&'#" ; else echo "# meta_memory_mib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GIB+x} ]; then echo "${VIASH_META_MEMORY_GIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gib='&'#" ; else echo "# meta_memory_gib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TIB+x} ]; then echo "${VIASH_META_MEMORY_TIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tib='&'#" ; else echo "# meta_memory_tib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PIB+x} ]; then echo "${VIASH_META_MEMORY_PIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pib='&'#" ; else echo "# meta_memory_pib="; fi ) - -## VIASH END - -[[ "\\$par_discard_orphans" == "false" ]] && unset par_discard_orphans -[[ "\\$par_ont" == "false" ]] && unset par_ont -[[ "\\$par_seq_bias" == "false" ]] && unset par_seq_bias -[[ "\\$par_gc_bias" == "false" ]] && unset par_gc_bias -[[ "\\$par_pos_bias" == "false" ]] && unset par_pos_bias -[[ "\\$par_meta" == "false" ]] && unset par_meta -[[ "\\$par_discard_orphans_quasi" == "false" ]] && unset par_discard_orphans_quasi -[[ "\\$par_disable_chaining_heuristic" == "false" ]] && unset par_disable_chaining_heuristic -[[ "\\$par_allow_dovetail" == "false" ]] && unset par_allow_dovetail -[[ "\\$par_recover_orphans" == "false" ]] && unset par_recover_orphans -[[ "\\$par_mimicBT2" == "false" ]] && unset par_mimicBT2 -[[ "\\$par_mimic_strictBT2" == "false" ]] && unset par_mimic_strictBT2 -[[ "\\$par_softclip" == "false" ]] && unset par_softclip -[[ "\\$par_softclip_overhangs" == "false" ]] && unset par_softclip_overhangs -[[ "\\$par_full_length_alignment" == "false" ]] && unset par_full_length_alignment -[[ "\\$par_hard_filter" == "false" ]] && unset par_hard_filter -[[ "\\$par_write_mappings" == "false" ]] && unset par_write_mappings -[[ "\\$par_write_qualities" == "false" ]] && unset par_write_qualities -[[ "\\$par_alternative_init_mode" == "false" ]] && unset par_alternative_init_mode -[[ "\\$par_skip_quant" == "false" ]] && unset par_skip_quant -[[ "\\$par_dump_eq" == "false" ]] && unset par_dump_eq -[[ "\\$par_dump_eq_weights" == "false" ]] && unset par_dump_eq_weights -[[ "\\$par_reduce_GC_memory" == "false" ]] && unset par_reduce_GC_memory -[[ "\\$par_init_uniform" == "false" ]] && unset par_init_uniform -[[ "\\$par_no_length_correction" == "false" ]] && unset par_no_length_correction -[[ "\\$par_no_effective_length_correction" == "false" ]] && unset par_no_effective_length_correction -[[ "\\$par_no_single_frag_prob" == "false" ]] && unset par_no_single_frag_prob -[[ "\\$par_no_frag_length_dist" == "false" ]] && unset par_no_frag_length_dist -[[ "\\$par_no_bias_length_threshold" == "false" ]] && unset par_no_bias_length_threshold -[[ "\\$par_useEM" == "false" ]] && unset par_useEM -[[ "\\$par_useVBOpt" == "false" ]] && unset par_useVBOpt -[[ "\\$par_no_Gamma_draw" == "false" ]] && unset par_no_Gamma_draw -[[ "\\$par_bootstrap_reproject" == "false" ]] && unset par_bootstrap_reproject -[[ "\\$par_quiet" == "false" ]] && unset par_quiet -[[ "\\$par_per_transcript_prior" == "false" ]] && unset par_per_transcript_prior -[[ "\\$par_per_nucleotide_prior" == "false" ]] && unset par_per_nucleotide_prior -[[ "\\$par_write_orphan_links" == "false" ]] && unset par_write_orphan_links -[[ "\\$par_write_unmapped_names" == "false" ]] && unset par_write_unmapped_names -[[ "\\$par_no_error_model" == "false" ]] && unset par_no_error_model -[[ "\\$par_sample_out" == "false" ]] && unset par_sample_out -[[ "\\$par_sample_unaligned" == "false" ]] && unset par_sample_unaligned -[[ "\\$par_gencode" == "false" ]] && unset par_gencode - -IFS=";" read -ra unmated_reads <<< \\$par_unmated_reads -IFS=";" read -ra mates1 <<< \\$par_mates1 -IFS=";" read -ra mates2 <<< \\$par_mates2 -IFS=";" read -ra alignment <<< \\$par_alignments - -salmon quant \\\\ - \\${par_lib_type:+-l "\\${par_lib_type}"} \\\\ - \\${par_index:+-i "\\${par_index}"} \\\\ - \\${par_unmated_reads:+-r \\${unmated_reads[*]}} \\\\ - \\${par_mates1:+-1 \\${mates1[*]}} \\\\ - \\${par_mates2:+-2 \\${mates2[*]}} \\\\ - \\${par_alignments:+-a \\${alignment[*]}} \\\\ - \\${par_discard_orphans:+--discardOrphans} \\\\ - \\${par_eqclasses:+-e "\\${par_eqclasses}"} \\\\ - \\${par_targets:+-t "\\${par_targets}"} \\\\ - \\${par_ont:+--ont} \\\\ - \\${par_output:+-o "\\${par_output}"} \\\\ - \\${par_seq_bias:+--seqBias} \\\\ - \\${par_gc_bias:+--gcBias} \\\\ - \\${par_pos_bias:+--posBias} \\\\ - \\${meta_cpus:+-p "\\${meta_cpus}"} \\\\ - \\${par_incompat_prior:+--incompatPrior "\\${par_incompat_prior}"} \\\\ - \\${par_gene_map:+-g "\\${par_gene_map}"} \\\\ - \\${par_aux_target_file:+--auxTargetFile "\\${par_aux_target_file}"} \\\\ - \\${par_meta:+--meta} \\\\ - \\${par_score_exp:+--scoreExp "\\${par_score_exp}"} \\\\ - \\${par_discard_orphans_quasi:+--discardOrphansQuasi} \\\\ - \\${par_consensus_slack:+--consensusSlack "\\${par_consensus_slack}"} \\\\ - \\${par_pre_merge_chain_sub_thresh:+--preMergeChainSubThresh "\\${par_pre_merge_chain_sub_thresh}"} \\\\ - \\${par_post_merge_chain_sub_thresh:+--postMergeChainSubThresh "\\${par_post_merge_chain_sub_thresh}"} \\\\ - \\${par_orphan_chain_sub_thresh:+--orphanChainSubThresh "\\${par_orphan_chain_sub_thresh}"} \\\\ - \\${par_min_score_fraction:+--minScoreFraction "\\${par_min_score_fraction}"} \\\\ - \\${par_mismatch_seed_skip:+--mismatchSeedSkip "\\${par_mismatch_seed_skip}"} \\\\ - \\${par_disable_chaining_heuristic:+--disableChainingHeuristic} \\\\ - \\${par_decoy_threshold:+--decoyThreshold "\\${par_decoy_threshold}"} \\\\ - \\${par_ma:+--ma "\\${par_ma}"} \\\\ - \\${par_mp:+--mp "\\${par_mp}"} \\\\ - \\${par_go:+--go "\\${par_go}"} \\\\ - \\${par_ge:+--ge "\\${par_ge}"} \\\\ - \\${par_bandwidth:+--bandwidth "\\${par_bandwidth}"} \\\\ - \\${par_allow_dovetail:+--allowDovetail} \\\\ - \\${par_recover_orphans:+--recoverOrphans} \\\\ - \\${par_mimicBT2:+--mimicBT2} \\\\ - \\${par_mimic_strictBT2:+--mimicStrictBT2} \\\\ - \\${par_softclip:+--softclip} \\\\ - \\${par_softclip_overhangs:+--softclipOverhangs} \\\\ - \\${par_full_length_alignment:+--fullLengthAlignment} \\\\ - \\${par_hard_filter:+--hardFilter} \\\\ - \\${par_min_aln_prob:+--minAlnProb "\\${par_min_aln_prob}"} \\\\ - \\${par_write_mappings:+--write_mappings="\\${par_mappings_sam}"} \\\\ - \\${par_write_qualities:+--writeQualities} \\\\ - \\${par_hit_filter_policy:+--hitFilterPolicy "\\${par_hit_filter_policy}"} \\\\ - \\${par_alternative_init_mode:+--alternativeInitMode} \\\\ - \\${par_aux_dir:+--auxDir "\\${par_aux_dir}"} \\\\ - \\${par_skip_quant:+--skipQuant} \\\\ - \\${par_dump_eq:+--dumpEq} \\\\ - \\${par_dump_eq_weights:+-d "\\${par_dump_eq_weights}"} \\\\ - \\${par_min_assigned_frags:+--minAssignedFrags "\\${par_min_assigned_frags}"} \\\\ - \\${par_reduce_GC_memory:+--reduceGCMemory} \\\\ - \\${par_bias_speed_samp:+--biasSpeedSamp "\\${par_bias_speed_samp}"} \\\\ - \\${par_fld_max:+--fldMax "\\${par_fld_max}"} \\\\ - \\${par_fld_mean:+--fldMean "\\${par_fld_mean}"} \\\\ - \\${par_fld_SD:+--fldSD "\\${par_fld_SD}"} \\\\ - \\${par_forgetting_factor:+-f "\\${par_forgetting_factor}"} \\\\ - \\${par_init_uniform:+--initUniform} \\\\ - \\${par_max_occs_per_hit:+--maxOccsPerHit "\\${par_max_occs_per_hit}"} \\\\ - \\${par_max_read_occ:+-w "\\${par_max_read_occ}"} \\\\ - \\${par_no_length_correction:+--noLengthCorrection} \\\\ - \\${par_no_effective_length_correction:+--noEffectiveLengthCorrection} \\\\ - \\${par_no_single_frag_prob:+--noSingleFragProb} \\\\ - \\${par_no_frag_length_dist:+--noFragLengthDist} \\\\ - \\${par_no_bias_length_threshold:+--noBiasLengthThreshold} \\\\ - \\${par_num_bias_samples:+--numBiasSamples "\\${par_num_bias_samples}"} \\\\ - \\${par_num_aux_model_samples:+--numAuxModelSamples "\\${par_num_aux_model_samples}"} \\\\ - \\${par_num_pre_aux_model_samples:+--numPreAuxModelSamples "\\${par_num_pre_aux_model_samples}"} \\\\ - \\${par_useEM:+--useEM} \\\\ - \\${par_useVBOpt:+--useVBOpt} \\\\ - \\${par_range_factorization_bins:+--rangeFactorizationBins "\\${par_range_factorization_bins}"} \\\\ - \\${par_num_Gibbs_samples:+--numGibbsSamples "\\${par_num_Gibbs_samples}"} \\\\ - \\${par_no_Gamma_draw:+--noGammaDraw} \\\\ - \\${par_num_bootstraps:+--numBootstraps "\\${par_num_bootstraps}"} \\\\ - \\${par_bootstrap_reproject:+--bootstrapReproject} \\\\ - \\${par_thinning_factor:+--thinningFactor "\\${par_thinning_factor}"} \\\\ - \\${par_quiet:+--quiet} \\\\ - \\${par_per_transcript_prior:+--perTranscriptPrior} \\\\ - \\${par_per_nucleotide_prior:+--perNucleotidePrior} \\\\ - \\${par_sig_digits:+--sigDigits "\\${par_sig_digits}"} \\\\ - \\${par_vb_prior:+--vbPrior "\\${par_vb_prior}"} \\\\ - \\${par_write_orphan_links:+--writeOrphanLinks} \\\\ - \\${par_write_unmapped_names:+--writeUnmappedNames} \\\\ - \\${par_no_error_model:+--noErrorModel} \\\\ - \\${par_num_error_bins:+--numErrorBins "\\${par_num_error_bins}"} \\\\ - \\${par_sample_out:+--sampleOut} \\\\ - \\${par_sample_unaligned:+--sampleUnaligned} \\\\ - \\${par_gencode:+--gencode} \\\\ - \\${par_mapping_cache_memory_limit:+--mappingCacheMemoryLimit "\\${par_mapping_cache_memory_limit}"} - -if [ -f "\\$par_output/quant.sf" ]; then - mv \\$par_output/quant.sf \\$par_quant_results -else - echo "Quantification file not generated!" -fi -VIASHMAIN -bash "$tempscript" -''' - - return vdsl3WorkflowFactory(args, meta, rawScript) -} - - - -/** - * Generate a workflow for VDSL3 modules. - * - * This function is called by the workflowFactory() function. - * - * Input channel: [id, input_map] - * Output channel: [id, output_map] - * - * Internally, this workflow will convert the input channel - * to a format which the Nextflow module will be able to handle. - */ -def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { - def key = args["key"] - def processObj = null - - workflow processWf { - take: input_ - main: - - if (processObj == null) { - processObj = _vdsl3ProcessFactory(args, meta, rawScript) - } - - output_ = input_ - | map { tuple -> - def id = tuple[0] - def data_ = tuple[1] - - if (workflow.stubRun) { - // add id if missing - data_ = [id: 'stub'] + data_ - } - - // process input files separately - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { par -> - def val = data_.containsKey(par.plainName) ? data_[par.plainName] : [] - def inputFiles = [] - if (val == null) { - inputFiles = [] - } else if (val instanceof List) { - inputFiles = val - } else if (val instanceof Path) { - inputFiles = [ val ] - } else { - inputFiles = [] - } - if (!workflow.stubRun) { - // throw error when an input file doesn't exist - inputFiles.each{ file -> - assert file.exists() : - "Error in module '${key}' id '${id}' argument '${par.plainName}'.\n" + - " Required input file does not exist.\n" + - " Path: '$file'.\n" + - " Expected input file to exist" - } - } - inputFiles - } - - // remove input files - def argsExclInputFiles = meta.config.allArguments - .findAll { (it.type != "file" || it.direction != "input") && data_.containsKey(it.plainName) } - .collectEntries { par -> - def parName = par.plainName - def val = data_[parName] - if (par.multiple && val instanceof Collection) { - val = val.join(par.multiple_sep) - } - if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) - } - [parName, val] - } - - [ id ] + inputPaths + [ argsExclInputFiles, meta.resources_dir ] - } - | processObj - | map { output -> - def outputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .indexed() - .collectEntries{ index, par -> - def out = output[index + 1] - // strip dummy '.exitcode' file from output (see nextflow-io/nextflow#2678) - if (!out instanceof List || out.size() <= 1) { - if (par.multiple) { - out = [] - } else { - assert !par.required : - "Error in module '${key}' id '${output[0]}' argument '${par.plainName}'.\n" + - " Required output file is missing" - out = null - } - } else if (out.size() == 2 && !par.multiple) { - out = out[1] - } else { - out = out.drop(1) - } - [ par.plainName, out ] - } - - // drop null outputs - outputFiles.removeAll{it.value == null} - - [ output[0], outputFiles ] - } - emit: output_ - } - - return processWf -} - -// depends on: session? -def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { - // autodetect process key - def wfKey = workflowArgs["key"] - def procKeyPrefix = "${wfKey}_process" - def scriptMeta = nextflow.script.ScriptMeta.current() - def existing = scriptMeta.getProcessNames().findAll{it.startsWith(procKeyPrefix)} - def numbers = existing.collect{it.replace(procKeyPrefix, "0").toInteger()} - def newNumber = (numbers + [-1]).max() + 1 - - def procKey = newNumber == 0 ? procKeyPrefix : "$procKeyPrefix$newNumber" - - if (newNumber > 0) { - log.warn "Key for module '${wfKey}' is duplicated.\n", - "If you run a component multiple times in the same workflow,\n" + - "it's recommended you set a unique key for every call,\n" + - "for example: ${wfKey}.run(key: \"foo\")." - } - - // subset directives and convert to list of tuples - def drctv = workflowArgs.directives - - // TODO: unit test the two commands below - // convert publish array into tags - def valueToStr = { val -> - // ignore closures - if (val instanceof CharSequence) { - if (!val.matches('^[{].*[}]$')) { - '"' + val + '"' - } else { - val - } - } else if (val instanceof List) { - "[" + val.collect{valueToStr(it)}.join(", ") + "]" - } else if (val instanceof Map) { - "[" + val.collect{k, v -> k + ": " + valueToStr(v)}.join(", ") + "]" - } else { - val.inspect() - } - } - - // multiple entries allowed: label, publishdir - def drctvStrs = drctv.collect { key, value -> - if (key in ["label", "publishDir"]) { - value.collect{ val -> - if (val instanceof Map) { - "\n$key " + val.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else if (val == null) { - "" - } else { - "\n$key " + valueToStr(val) - } - }.join() - } else if (value instanceof Map) { - "\n$key " + value.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else { - "\n$key " + valueToStr(value) - } - }.join() - - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { ', path(viash_par_' + it.plainName + ', stageAs: "_viash_par/' + it.plainName + '_?/*")' } - .join() - - def outputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - // insert dummy into every output (see nextflow-io/nextflow#2678) - if (!par.multiple) { - ', path{[".exitcode", args.' + par.plainName + ']}' - } else { - ', path{[".exitcode"] + args.' + par.plainName + '}' - } - } - .join() - - // TODO: move this functionality somewhere else? - if (workflowArgs.auto.transcript) { - outputPaths = outputPaths + ', path{[".exitcode", ".command*"]}' - } else { - outputPaths = outputPaths + ', path{[".exitcode"]}' - } - - // create dirs for output files (based on BashWrapper.createParentFiles) - def createParentStr = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" && it.create_parent } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // construct inputFileExports - def inputFileExports = meta.config.allArguments - .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } - .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" - } - - // NOTE: if using docker, use /tmp instead of tmpDir! - def tmpDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('VIASH_TMPDIR') ?: - System.getenv('VIASH_TEMPDIR') ?: - System.getenv('VIASH_TMP') ?: - System.getenv('TEMP') ?: - System.getenv('TMPDIR') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMP') ?: - '/tmp' - ).toAbsolutePath() - - // construct stub - def stub = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"touch2 \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"].replace(\"_*\", \"_0\") : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // escape script - def escapedScript = rawScript.replace('\\', '\\\\').replace('$', '\\$').replace('"""', '\\"\\"\\"') - - // publishdir assert - def assertStr = (workflowArgs.auto.publish == true) || workflowArgs.auto.transcript ? - """\nassert task.publishDir.size() > 0: "if auto.publish is true, params.publish_dir needs to be defined.\\n Example: --publish_dir './output/'" """ : - "" - - // generate process string - def procStr = - """nextflow.enable.dsl=2 - | - |process $procKey {$drctvStrs - |input: - | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") - |output: - | tuple val("\$id")$outputPaths, optional: true - |stub: - |\"\"\" - |touch2() { mkdir -p "\\\$(dirname "\\\$1")" && touch "\\\$1" ; } - |$stub - |\"\"\" - |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } - |def parInject = args - | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} - | .join("\\n") - |\"\"\" - |# meta exports - |export VIASH_META_RESOURCES_DIR="\${resourcesDir}" - |export VIASH_META_TEMP_DIR="${['docker', 'podman', 'charliecloud'].any{ it == workflow.containerEngine } ? '/tmp' : tmpDir}" - |export VIASH_META_NAME="${meta.config.name}" - |# export VIASH_META_EXECUTABLE="\\\$VIASH_META_RESOURCES_DIR/\\\$VIASH_META_NAME" - |export VIASH_META_CONFIG="\\\$VIASH_META_RESOURCES_DIR/.config.vsh.yaml" - |\${task.cpus ? "export VIASH_META_CPUS=\$task.cpus" : "" } - |\${task.memory?.bytes != null ? "export VIASH_META_MEMORY_B=\$task.memory.bytes" : "" } - |if [ ! -z \\\${VIASH_META_MEMORY_B+x} ]; then - | export VIASH_META_MEMORY_KB=\\\$(( (\\\$VIASH_META_MEMORY_B+999) / 1000 )) - | export VIASH_META_MEMORY_MB=\\\$(( (\\\$VIASH_META_MEMORY_KB+999) / 1000 )) - | export VIASH_META_MEMORY_GB=\\\$(( (\\\$VIASH_META_MEMORY_MB+999) / 1000 )) - | export VIASH_META_MEMORY_TB=\\\$(( (\\\$VIASH_META_MEMORY_GB+999) / 1000 )) - | export VIASH_META_MEMORY_PB=\\\$(( (\\\$VIASH_META_MEMORY_TB+999) / 1000 )) - | export VIASH_META_MEMORY_KIB=\\\$(( (\\\$VIASH_META_MEMORY_B+1023) / 1024 )) - | export VIASH_META_MEMORY_MIB=\\\$(( (\\\$VIASH_META_MEMORY_KIB+1023) / 1024 )) - | export VIASH_META_MEMORY_GIB=\\\$(( (\\\$VIASH_META_MEMORY_MIB+1023) / 1024 )) - | export VIASH_META_MEMORY_TIB=\\\$(( (\\\$VIASH_META_MEMORY_GIB+1023) / 1024 )) - | export VIASH_META_MEMORY_PIB=\\\$(( (\\\$VIASH_META_MEMORY_TIB+1023) / 1024 )) - |fi - | - |# meta synonyms - |export VIASH_TEMP="\\\$VIASH_META_TEMP_DIR" - |export TEMP_DIR="\\\$VIASH_META_TEMP_DIR" - | - |# create output dirs if need be - |function mkdir_parent { - | for file in "\\\$@"; do - | mkdir -p "\\\$(dirname "\\\$file")" - | done - |} - |$createParentStr - | - |# argument exports${inputFileExports.join()} - |\$parInject - | - |# process script - |${escapedScript} - |\"\"\" - |} - |""".stripMargin() - - // TODO: print on debug - // if (workflowArgs.debug == true) { - // println("######################\n$procStr\n######################") - // } - - // write process to temp file - def tempFile = java.nio.file.Files.createTempFile("viash-process-${procKey}-", ".nf") - addShutdownHook { java.nio.file.Files.deleteIfExists(tempFile) } - tempFile.text = procStr - - // create process from temp file - def binding = new nextflow.script.ScriptBinding([:]) - def session = nextflow.Nextflow.getSession() - def parser = new nextflow.script.ScriptParser(session) - .setModule(true) - .setBinding(binding) - def moduleScript = parser.runScript(tempFile) - .getScript() - - // register module in meta - def module = new nextflow.script.IncludeDef.Module(name: procKey) - scriptMeta.addModule(moduleScript, module.name, module.alias) - - // retrieve and return process from meta - return scriptMeta.getProcess(procKey) -} - -// defaults -meta["defaults"] = [ - // key to be used to trace the process and determine output names - key: null, - - // fixed arguments to be passed to script - args: [:], - - // default directives - directives: readJsonBlob('''{ - "container" : { - "registry" : "images.viash-hub.com", - "image" : "vsh/biobox/salmon/salmon_quant", - "tag" : "v0.1.0" - }, - "tag" : "$id" -}'''), - - // auto settings - auto: readJsonBlob('''{ - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false -}'''), - - // Apply a map over the incoming tuple - // Example: `{ tup -> [ tup[0], [input: tup[1].output] ] + tup.drop(2) }` - map: null, - - // Apply a map over the ID element of a tuple (i.e. the first element) - // Example: `{ id -> id + "_foo" }` - mapId: null, - - // Apply a map over the data element of a tuple (i.e. the second element) - // Example: `{ data -> [ input: data.output ] }` - mapData: null, - - // Apply a map over the passthrough elements of a tuple (i.e. the tuple excl. the first two elements) - // Example: `{ pt -> pt.drop(1) }` - mapPassthrough: null, - - // Filter the channel - // Example: `{ tup -> tup[0] == "foo" }` - filter: null, - - // Choose whether or not to run the component on the tuple if the condition is true. - // Otherwise, the tuple will be passed through. - // Example: `{ tup -> tup[0] != "skip_this" }` - runIf: null, - - // Rename keys in the data field of the tuple (i.e. the second element) - // Will likely be deprecated in favour of `fromState`. - // Example: `[ "new_key": "old_key" ]` - renameKeys: null, - - // Fetch data from the state and pass it to the module without altering the current state. - // - // `fromState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be passed to the module as is. - // - If it is a `List[String]`, the data will be the values of the state at the given keys. - // - If it is a `Map[String, String]`, the data will be the values of the state at the given keys, with the keys renamed according to the map. - // - If it is a function, the tuple (`[id, state]`) in the channel will be passed to the function, and the result will be used as the data. - // - // Example: `{ id, state -> [input: state.fastq_file] }` - // Default: `null` - fromState: null, - - // Determine how the state should be updated after the module has been run. - // - // `toState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be replaced with the output of the module. - // - If it is a `List[String]`, the state will be updated with the values of the data at the given keys. - // - If it is a `Map[String, String]`, the state will be updated with the values of the data at the given keys, with the keys renamed according to the map. - // - If it is a function, a tuple (`[id, output, state]`) will be passed to the function, and the result will be used as the new state. - // - // Example: `{ id, output, state -> state + [counts: state.output] }` - // Default: `{ id, output, state -> output }` - toState: null, - - // Whether or not to print debug messages - // Default: `false` - debug: false -] - -// initialise default workflow -meta["workflow"] = workflowFactory([key: meta.config.name], meta.defaults, meta) - -// add workflow to environment -nextflow.script.ScriptMeta.current().addDefinition(meta.workflow) - -// anonymous workflow for running this module as a standalone -workflow { - // add id argument if it's not already in the config - // TODO: deep copy - def newConfig = deepClone(meta.config) - def newParams = deepClone(params) - - def argsContainsId = newConfig.allArguments.any{it.plainName == "id"} - if (!argsContainsId) { - def idArg = [ - 'name': '--id', - 'required': false, - 'type': 'string', - 'description': 'A unique id for every entry.', - 'multiple': false - ] - newConfig.arguments.add(0, idArg) - newConfig = processConfig(newConfig) - } - if (!newParams.containsKey("id")) { - newParams.id = "run" - } - - helpMessage(newConfig) - - channelFromParams(newParams, newConfig) - // make sure id is not in the state if id is not in the args - | map {id, state -> - if (!argsContainsId) { - [id, state.findAll{k, v -> k != "id"}] - } else { - [id, state] - } - } - | meta.workflow.run( - auto: [ publish: "state" ] - ) -} - -// END COMPONENT-SPECIFIC CODE diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/nextflow.config deleted file mode 100644 index c9fccf9..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/nextflow.config +++ /dev/null @@ -1,125 +0,0 @@ -manifest { - name = 'salmon/salmon_quant' - mainScript = 'main.nf' - nextflowVersion = '!>=20.12.1-edge' - version = 'v0.1.0' - description = 'Salmon is a tool for wicked-fast transcript quantification from RNA-seq data. It can either make use of pre-computed alignments (in the form of a SAM/BAM file) to the transcripts rather than the raw reads, or can be run in the mapping-based mode. \n' -} - -process.container = 'nextflow/bash:latest' - -// detect tempdir -tempDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMPDIR') ?: - '/tmp' -).toAbsolutePath() - -profiles { - no_publish { - process { - withName: '.*' { - publishDir = [ - enabled: false - ] - } - } - } - mount_temp { - docker.temp = tempDir - podman.temp = tempDir - charliecloud.temp = tempDir - } - docker { - docker.enabled = true - // docker.userEmulation = true - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - singularity { - singularity.enabled = true - singularity.autoMounts = true - docker.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - podman { - podman.enabled = true - docker.enabled = false - singularity.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - shifter { - shifter.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - charliecloud.enabled = false - } - charliecloud { - charliecloud.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - } -} - -process{ - withLabel: mem1gb { memory = 1000000000.B } - withLabel: mem2gb { memory = 2000000000.B } - withLabel: mem5gb { memory = 5000000000.B } - withLabel: mem10gb { memory = 10000000000.B } - withLabel: mem20gb { memory = 20000000000.B } - withLabel: mem50gb { memory = 50000000000.B } - withLabel: mem100gb { memory = 100000000000.B } - withLabel: mem200gb { memory = 200000000000.B } - withLabel: mem500gb { memory = 500000000000.B } - withLabel: mem1tb { memory = 1000000000000.B } - withLabel: mem2tb { memory = 2000000000000.B } - withLabel: mem5tb { memory = 5000000000000.B } - withLabel: mem10tb { memory = 10000000000000.B } - withLabel: mem20tb { memory = 20000000000000.B } - withLabel: mem50tb { memory = 50000000000000.B } - withLabel: mem100tb { memory = 100000000000000.B } - withLabel: mem200tb { memory = 200000000000000.B } - withLabel: mem500tb { memory = 500000000000000.B } - withLabel: mem1gib { memory = 1073741824.B } - withLabel: mem2gib { memory = 2147483648.B } - withLabel: mem4gib { memory = 4294967296.B } - withLabel: mem8gib { memory = 8589934592.B } - withLabel: mem16gib { memory = 17179869184.B } - withLabel: mem32gib { memory = 34359738368.B } - withLabel: mem64gib { memory = 68719476736.B } - withLabel: mem128gib { memory = 137438953472.B } - withLabel: mem256gib { memory = 274877906944.B } - withLabel: mem512gib { memory = 549755813888.B } - withLabel: mem1tib { memory = 1099511627776.B } - withLabel: mem2tib { memory = 2199023255552.B } - withLabel: mem4tib { memory = 4398046511104.B } - withLabel: mem8tib { memory = 8796093022208.B } - withLabel: mem16tib { memory = 17592186044416.B } - withLabel: mem32tib { memory = 35184372088832.B } - withLabel: mem64tib { memory = 70368744177664.B } - withLabel: mem128tib { memory = 140737488355328.B } - withLabel: mem256tib { memory = 281474976710656.B } - withLabel: mem512tib { memory = 562949953421312.B } - withLabel: cpu1 { cpus = 1 } - withLabel: cpu2 { cpus = 2 } - withLabel: cpu5 { cpus = 5 } - withLabel: cpu10 { cpus = 10 } - withLabel: cpu20 { cpus = 20 } - withLabel: cpu50 { cpus = 50 } - withLabel: cpu100 { cpus = 100 } - withLabel: cpu200 { cpus = 200 } - withLabel: cpu500 { cpus = 500 } - withLabel: cpu1000 { cpus = 1000 } -} - - diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/nextflow_schema.json deleted file mode 100644 index 80b2139..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/nextflow_schema.json +++ /dev/null @@ -1,1119 +0,0 @@ -{ -"$schema": "http://json-schema.org/draft-07/schema", -"title": "salmon_quant", -"description": "Salmon is a tool for wicked-fast transcript quantification from RNA-seq data. It can either make use of pre-computed alignments (in the form of a SAM/BAM file) to the transcripts rather than the raw reads, or can be run in the mapping-based mode. \n", -"type": "object", -"definitions": { - - - - "common input options" : { - "title": "Common input options", - "type": "object", - "description": "No description", - "properties": { - - - "lib_type": { - "type": - "string", - "description": "Type: `string`, default: `A`, choices: ``A`, `U`, `SF`, `SR`, `IU`, `IS`, `ISF`, `ISR`, `OU`, `OS`, `OSF`, `OSR`, `MU`, `MS`, `MSF`, `MSR``. Format string describing the library", - "help_text": "Type: `string`, default: `A`, choices: ``A`, `U`, `SF`, `SR`, `IU`, `IS`, `ISF`, `ISR`, `OU`, `OS`, `OSF`, `OSR`, `MU`, `MS`, `MSF`, `MSR``. Format string describing the library.\nThe library type string consists of three parts: \n1. Relative orientation of the reads: This part is only provided if the library is paired-end, THe possible options are\n I = inward\n O = outward\n M = matching\n2. Strandedness of the library: This part specifies whether the protocol is stranded or unstranded. The options are:\n S = stranded\n U = unstranded\n3. Directionality of the reads: If the library is stranded, the final part of the library string is used to specify the strand from which the read originates. The possible values are\n F = read 1 (or single-end read) comes from the forward strand\n R = read 1 (or single-end read) comes from the reverse strand\n", - "enum": ["A", "U", "SF", "SR", "IU", "IS", "ISF", "ISR", "OU", "OS", "OSF", "OSR", "MU", "MS", "MSF", "MSR"] - - , - "default": "A" - } - - -} -}, - - - "mapping input options" : { - "title": "Mapping input options", - "type": "object", - "description": "No description", - "properties": { - - - "index": { - "type": - "string", - "description": "Type: `file`, example: `transcriptome_index`. Salmon index", - "help_text": "Type: `file`, example: `transcriptome_index`. Salmon index.\n" - - } - - - , - "unmated_reads": { - "type": - "string", - "description": "Type: List of `file`, example: `sample.fq.gz`, multiple_sep: `\":\"`. List of files containing unmated reads of (e", - "help_text": "Type: List of `file`, example: `sample.fq.gz`, multiple_sep: `\":\"`. List of files containing unmated reads of (e.g. single-end reads).\n" - - } - - - , - "mates1": { - "type": - "string", - "description": "Type: List of `file`, example: `sample_1.fq.gz`, multiple_sep: `\":\"`. File containing the #1 mates", - "help_text": "Type: List of `file`, example: `sample_1.fq.gz`, multiple_sep: `\":\"`. File containing the #1 mates.\n" - - } - - - , - "mates2": { - "type": - "string", - "description": "Type: List of `file`, example: `sample_2.fq.gz`, multiple_sep: `\":\"`. File containing the #2 mates", - "help_text": "Type: List of `file`, example: `sample_2.fq.gz`, multiple_sep: `\":\"`. File containing the #2 mates.\n" - - } - - -} -}, - - - "alignment input options" : { - "title": "Alignment input options", - "type": "object", - "description": "No description", - "properties": { - - - "discard_orphans": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Discard orphan alignments in the input [for alignment-based mode only]", - "help_text": "Type: `boolean_true`, default: `false`. Discard orphan alignments in the input [for alignment-based mode only]. If this flag is passed, then only paired alignments will be considered toward quantification estimates. The default behavior is to consider orphan alignments if no valid paired mappings exist.\n" - , - "default": "False" - } - - - , - "alignments": { - "type": - "string", - "description": "Type: List of `file`, example: `sample.fq.gz`, multiple_sep: `\":\"`. Input alignment (BAM) file(s)", - "help_text": "Type: List of `file`, example: `sample.fq.gz`, multiple_sep: `\":\"`. Input alignment (BAM) file(s).\n" - - } - - - , - "eqclasses": { - "type": - "string", - "description": "Type: `file`. input salmon weighted equivalence class file", - "help_text": "Type: `file`. input salmon weighted equivalence class file.\n" - - } - - - , - "targets": { - "type": - "string", - "description": "Type: `file`, example: `transcripts.fasta`. FASTA format file containing target transcripts", - "help_text": "Type: `file`, example: `transcripts.fasta`. FASTA format file containing target transcripts.\n" - - } - - - , - "ont": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Use alignment model for Oxford Nanopore long reads\n", - "help_text": "Type: `boolean_true`, default: `false`. Use alignment model for Oxford Nanopore long reads\n" - , - "default": "False" - } - - -} -}, - - - "output" : { - "title": "Output", - "type": "object", - "description": "No description", - "properties": { - - - "output": { - "type": - "string", - "description": "Type: `file`, required, default: `$id.$key.output.output`, example: `quant_output`. Output quantification directory", - "help_text": "Type: `file`, required, default: `$id.$key.output.output`, example: `quant_output`. Output quantification directory.\n" - , - "default": "$id.$key.output.output" - } - - - , - "quant_results": { - "type": - "string", - "description": "Type: `file`, required, default: `$id.$key.quant_results.sf`, example: `quant.sf`. Salmon quantification file", - "help_text": "Type: `file`, required, default: `$id.$key.quant_results.sf`, example: `quant.sf`. Salmon quantification file.\n" - , - "default": "$id.$key.quant_results.sf" - } - - -} -}, - - - "basic options" : { - "title": "Basic options", - "type": "object", - "description": "No description", - "properties": { - - - "seq_bias": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Perform sequence-specific bias correction", - "help_text": "Type: `boolean_true`, default: `false`. Perform sequence-specific bias correction.\n" - , - "default": "False" - } - - - , - "gc_bias": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Perform fragment GC bias correction [beta for single-end reads]", - "help_text": "Type: `boolean_true`, default: `false`. Perform fragment GC bias correction [beta for single-end reads].\n" - , - "default": "False" - } - - - , - "pos_bias": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Perform positional bias correction", - "help_text": "Type: `boolean_true`, default: `false`. Perform positional bias correction.\n" - , - "default": "False" - } - - - , - "incompat_prior": { - "type": - "number", - "description": "Type: `double`, example: `0`. Set the prior probability that an alignment that disagrees with the specified library type (--lib_type) results from the true fragment origin", - "help_text": "Type: `double`, example: `0`. Set the prior probability that an alignment that disagrees with the specified library type (--lib_type) results from the true fragment origin. Setting this to 0 specifies that alignments that disagree with the library type should be \"impossible\", while setting it to 1 says that alignments that disagree with the library type are no less likely than those that do.\n" - - } - - - , - "gene_map": { - "type": - "string", - "description": "Type: `file`, example: `gene_map.gtf`. File containing a mapping of transcripts to genes", - "help_text": "Type: `file`, example: `gene_map.gtf`. File containing a mapping of transcripts to genes. If this file is provided salmon will output both quant.sf and quant.genes.sf files, where the latter contains aggregated gene-level abundance estimates. The transcript to gene mapping should be provided as either a GTF file, or a in a simple tab-delimited format where each line contains the name of a transcript and the gene to which it belongs separated by a tab. The extension of the file is used to determine how the file should be parsed. Files ending in \u0027.gtf\u0027, \u0027.gff\u0027 or \u0027.gff3\u0027 are assumed to be in GTF format; files with any other extension are assumed to be in the simple format. In GTF / GFF format, the \"transcript_id\" is assumed to contain the transcript identifier and the \"gene_id\" is assumed to contain the corresponding gene identifier.\n" - - } - - - , - "aux_target_file": { - "type": - "string", - "description": "Type: `file`, example: `auxilary_targets.txt`. A file containing a list of \"auxiliary\" targets", - "help_text": "Type: `file`, example: `auxilary_targets.txt`. A file containing a list of \"auxiliary\" targets. These are valid targets (i.e., not decoys) to which fragments are allowed to map and be assigned, and which will be quantified, but for which auxiliary models like sequence-specific and fragment-GC bias correction should not be applied.\n" - - } - - - , - "meta": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. If you\u0027re using Salmon on a metagenomic dataset, consider setting this flag to disable parts of the abundance estimation model that make less sense for metagenomic data", - "help_text": "Type: `boolean_true`, default: `false`. If you\u0027re using Salmon on a metagenomic dataset, consider setting this flag to disable parts of the abundance estimation model that make less sense for metagenomic data.\n" - , - "default": "False" - } - - - , - "score_exp": { - "type": - "number", - "description": "Type: `double`, example: `1`. The factor by which sub-optimal alignment scores are downweighted to produce a probability", - "help_text": "Type: `double`, example: `1`. The factor by which sub-optimal alignment scores are downweighted to produce a probability. If the best alignment score for the current read is S, and the score for a particular alignment is w, then the probability will be computed porportional to exp( - scoreExp * (S-w) ).\n" - - } - - -} -}, - - - "options specific to mapping mode" : { - "title": "Options specific to mapping mode", - "type": "object", - "description": "No description", - "properties": { - - - "discard_orphans_quasi": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nDiscard orphan mappings in selective-alignment mode", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nDiscard orphan mappings in selective-alignment mode. If this flag is passed then only paired mappings will be considered toward quantification estimates. The default behavior is to consider orphan mappings if no valid paired mappings exist. This flag is independent of the option to write the orphaned mappings to file (--writeOrphanLinks).\n" - , - "default": "False" - } - - - , - "consensus_slack": { - "type": - "number", - "description": "Type: `double`, example: `0.35`. [selective-alignment mode only] \nThe amount of slack allowed in the selective-alignment filtering mechanism", - "help_text": "Type: `double`, example: `0.35`. [selective-alignment mode only] \nThe amount of slack allowed in the selective-alignment filtering mechanism. If this is set to a fraction, X, greater than 0 (and in [0,1)), then uniMEM chains with scores below (100 * X)% of the best chain score for a read, and read pairs with a sum of chain scores below (100 * X)% of the best chain score for a read pair will be discounted as a mapping candidates. The default value of this option is 0.35.\n" - - } - - - , - "pre_merge_chain_sub_thresh": { - "type": - "number", - "description": "Type: `double`, example: `0.75`. [selective-alignment mode only] \nThe threshold of sub-optimal chains, compared to the best chain on a given target, that will be retained and passed to the next phase of mapping", - "help_text": "Type: `double`, example: `0.75`. [selective-alignment mode only] \nThe threshold of sub-optimal chains, compared to the best chain on a given target, that will be retained and passed to the next phase of mapping. Specifically, if the best chain for a read (or read-end in paired-end mode) to target t has score X_t, then all chains for this read with score \u003e= X_t * preMergeChainSubThresh will be retained and passed to subsequent mapping phases. This value must be in the range [0, 1].\n" - - } - - - , - "post_merge_chain_sub_thresh": { - "type": - "number", - "description": "Type: `double`, example: `0.9`. [selective-alignment mode only] \nThe threshold of sub-optimal chains, compared to the best chain on a given target, that will be retained and passed to the next phase of mapping", - "help_text": "Type: `double`, example: `0.9`. [selective-alignment mode only] \nThe threshold of sub-optimal chains, compared to the best chain on a given target, that will be retained and passed to the next phase of mapping. This is different than post_merge_chain_sub_thresh, because this is applied to pairs of chains (from the ends of paired-end reads) after merging (i.e. after checking concordancy constraints etc.). Specifically, if the best chain pair to target t has score X_t, then all chain pairs for this read pair with score \u003e= X_t * post_merge_chain_sub_thresh will be retained and passed to subsequent mapping phases. This value must be in the range [0, 1]. Note: This option is only meaningful for paired-end libraries, and is ignored for single-end libraries.\n" - - } - - - , - "orphan_chain_sub_thresh": { - "type": - "number", - "description": "Type: `double`, example: `0.95`. [selective-alignment mode only]\nThis threshold sets a global sub-optimality threshold for chains corresponding to orphan mappings", - "help_text": "Type: `double`, example: `0.95`. [selective-alignment mode only]\nThis threshold sets a global sub-optimality threshold for chains corresponding to orphan mappings. That is, if the merging procedure results in no concordant mappings then only orphan mappings with a chain score \u003e= orphan_chain_sub_thresh * bestChainScore will be retained and passed to subsequent mapping phases. This value must be in the range [0, 1]. Note: This option is only meaningful for paired-end libraries, and is ignored for single-end libraries.\n" - - } - - - , - "min_score_fraction": { - "type": - "number", - "description": "Type: `double`, example: `0.65`. [selective-alignment mode only]\nThe fraction of the optimal possible alignment score that a mapping must achieve in order to be considered \"valid\" --- should be in (0,1]", - "help_text": "Type: `double`, example: `0.65`. [selective-alignment mode only]\nThe fraction of the optimal possible alignment score that a mapping must achieve in order to be considered \"valid\" --- should be in (0,1]. Default 0.65\n" - - } - - - , - "mismatch_seed_skip": { - "type": - "integer", - "description": "Type: `integer`, example: `3`. [selective-alignment mode only]\nAfter a k-mer hit is extended to a uni-MEM, the uni-MEM extension can terminate for one of 3 reasons; the end of the read, the end of the unitig, or a mismatch", - "help_text": "Type: `integer`, example: `3`. [selective-alignment mode only]\nAfter a k-mer hit is extended to a uni-MEM, the uni-MEM extension can terminate for one of 3 reasons; the end of the read, the end of the unitig, or a mismatch. If the extension ends because of a mismatch, this is likely the result of a sequencing error. To avoid looking up many k-mers that will likely fail to be located in the index, the search procedure skips by a factor of mismatch_seed_skip until it either (1) finds another match or (2) is k-bases past the mismatch position. This value controls that skip length. A smaller value can increase sensitivity, while a larger value can speed up seeding.\n" - - } - - - , - "disable_chaining_heuristic": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nBy default, the heuristic of (Li 2018) is implemented, which terminates the chaining DP once a given number of valid backpointers are found", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nBy default, the heuristic of (Li 2018) is implemented, which terminates the chaining DP once a given number of valid backpointers are found. This speeds up the seed (MEM) chaining step, but may result in sub-optimal chains in complex situations (e.g. sequences with many repeats and overlapping repeats). Passing this flag will disable the chaining heuristic, and perform the full chaining dynamic program, guaranteeing the optimal chain is found in this step.\n" - , - "default": "False" - } - - - , - "decoy_threshold": { - "type": - "number", - "description": "Type: `double`, example: `1`. [selective-alignment mode only]\nFor an alignemnt to an annotated transcript to be considered invalid, it must have an alignment score \u003c (decoy_threshold * bestDecoyScore)", - "help_text": "Type: `double`, example: `1`. [selective-alignment mode only]\nFor an alignemnt to an annotated transcript to be considered invalid, it must have an alignment score \u003c (decoy_threshold * bestDecoyScore). A value of 1.0 means that any alignment strictly worse than the best decoy alignment will be discarded. A smaller value will allow reads to be allocated to transcripts even if they strictly align better to the decoy sequence.\n" - - } - - - , - "ma": { - "type": - "integer", - "description": "Type: `integer`, example: `2`. [selective-alignment mode only]\nThe value given to a match between read and reference nucleotides in an alignment", - "help_text": "Type: `integer`, example: `2`. [selective-alignment mode only]\nThe value given to a match between read and reference nucleotides in an alignment.\n" - - } - - - , - "mp": { - "type": - "integer", - "description": "Type: `integer`, example: `-4`. [selective-alignment mode only]\nThe value given to a mis-match between read and reference nucleotides in an alignment", - "help_text": "Type: `integer`, example: `-4`. [selective-alignment mode only]\nThe value given to a mis-match between read and reference nucleotides in an alignment.\n" - - } - - - , - "go": { - "type": - "integer", - "description": "Type: `integer`, example: `6`. [selective-alignment mode only]\nThe value given to a gap opening in an alignment", - "help_text": "Type: `integer`, example: `6`. [selective-alignment mode only]\nThe value given to a gap opening in an alignment.\n" - - } - - - , - "ge": { - "type": - "integer", - "description": "Type: `integer`, example: `2`. [selective-alignment mode only]\nThe value given to a gap extension in an alignment", - "help_text": "Type: `integer`, example: `2`. [selective-alignment mode only]\nThe value given to a gap extension in an alignment.\n" - - } - - - , - "bandwidth": { - "type": - "integer", - "description": "Type: `integer`, example: `15`. [selective-alignment mode only]\nThe value used for the bandwidth passed to ksw2", - "help_text": "Type: `integer`, example: `15`. [selective-alignment mode only]\nThe value used for the bandwidth passed to ksw2. A smaller bandwidth can make the alignment verification run more quickly, but could possibly miss valid alignments.\n" - - } - - - , - "allow_dovetail": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nAllow dovetailing mappings", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nAllow dovetailing mappings.\n" - , - "default": "False" - } - - - , - "recover_orphans": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nAttempt to recover the mates of orphaned reads", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nAttempt to recover the mates of orphaned reads. This uses edlib for orphan recovery, and so introduces some computational overhead, but it can improve sensitivity.\n" - , - "default": "False" - } - - - , - "mimicBT2": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nSet flags to mimic parameters similar to Bowtie2 with --no-discordant and --no-mixed flags", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nSet flags to mimic parameters similar to Bowtie2 with --no-discordant and --no-mixed flags. This increases disallows dovetailing reads, and discards orphans. Note, this does not impose the very strict parameters assumed by RSEM+Bowtie2, like gapless alignments. For that behavior, use the --mimic_strictBT2 flag below.\n" - , - "default": "False" - } - - - , - "mimic_strictBT2": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nSet flags to mimic the very strict parameters used by RSEM+Bowtie2", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nSet flags to mimic the very strict parameters used by RSEM+Bowtie2. This increases --min_score_fraction to 0.8, disallows dovetailing reads, discards orphans, and disallows gaps in alignments.\n" - , - "default": "False" - } - - - , - "softclip": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nAllos soft-clipping of reads during selective-alignment", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nAllos soft-clipping of reads during selective-alignment. If this option is provided, then regions at the beginning or end of the read can be withheld from alignment without any effect on the resulting score (i.e. neither adding nor removing from the score). This will drastically reduce the penalty if there are mismatches at the beginning or end of the read due to e.g. low-quality bases or adapters. NOTE: Even with soft-clipping enabled, the read must still achieve a score of at least min_score_fraction * maximum achievable score, where the maximum achievable score is computed based on the full (un-clipped) read length.\n" - , - "default": "False" - } - - - , - "softclip_overhangs": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nAllow soft-clipping of reads that overhang the beginning or ends of the transcript", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nAllow soft-clipping of reads that overhang the beginning or ends of the transcript. In this case, the overhaning section of the read will simply be unaligned, and will not contribute or detract from the alignment score. The default policy is to force an end-to-end alignment of the entire read, so that overhanings will result in some deletion of nucleotides from the read.\n" - , - "default": "False" - } - - - , - "full_length_alignment": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nPerform selective alignment over the full length of the read, beginning from the (approximate) initial mapping location and using extension alignment", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nPerform selective alignment over the full length of the read, beginning from the (approximate) initial mapping location and using extension alignment. This is in contrast with the default behavior which is to only perform alignment between the MEMs in the optimal chain (and before the first and after the last MEM if applicable). The default strategy forces the MEMs to belong to the alignment, but has the benefit that it can discover indels prior to the first hit shared between the read and reference. Except in very rare circumstances, the default mode should be more accurate.\n" - , - "default": "False" - } - - - , - "hard_filter": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nInstead of weighting mappings by their alignment score, this flag will discard any mappings with sub-optimal alignment score", - "help_text": "Type: `boolean_true`, default: `false`. [selective-alignment mode only] \nInstead of weighting mappings by their alignment score, this flag will discard any mappings with sub-optimal alignment score. The default option of soft-filtering (i.e. weighting mappings by their alignment score) usually yields slightly more accurate abundance estimates but this flag may be desirable if you want more accurate \u0027naive\u0027 equivalence classes, rather than range factorized equivalence classes.\n" - , - "default": "False" - } - - - , - "min_aln_prob": { - "type": - "number", - "description": "Type: `double`, example: `1.0E-5`. The minimum number of fragments that must be assigned to the transcriptome for quantification to proceed", - "help_text": "Type: `double`, example: `1.0E-5`. The minimum number of fragments that must be assigned to the transcriptome for quantification to proceed.\n" - - } - - - , - "write_mappings": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. If this option is provided, then the selective-alignment results will be written out in SAM-compatible format", - "help_text": "Type: `boolean_true`, default: `false`. If this option is provided, then the selective-alignment results will be written out in SAM-compatible format. By default, output will be directed to stdout, but an alternative file name can be provided instead.\n" - , - "default": "False" - } - - - , - "mapping_sam": { - "type": - "string", - "description": "Type: `file`, default: `$id.$key.mapping_sam.sam`, example: `mappings.sam`. Path to file that should output the selective-alignment results in SAM-compatible format", - "help_text": "Type: `file`, default: `$id.$key.mapping_sam.sam`, example: `mappings.sam`. Path to file that should output the selective-alignment results in SAM-compatible format. THis option must be provided while using --write_mappings" - , - "default": "$id.$key.mapping_sam.sam" - } - - - , - "write_qualities": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. This flag only has meaning if mappings are being written (with --write_mappings/-z)", - "help_text": "Type: `boolean_true`, default: `false`. This flag only has meaning if mappings are being written (with --write_mappings/-z). If this flag is provided, then the output SAM file will contain quality strings as well as read sequences. Note that this can greatly increase the size of the output file.\n" - , - "default": "False" - } - - - , - "hit_filter_policy": { - "type": - "string", - "description": "Type: `string`, example: `AFTER`, choices: ``BEFORE`, `AFTER`, `BOTH`, `NONE``. [selective-alignment mode only]\nDetermines the policy by which hits are filtered in selective alignment", - "help_text": "Type: `string`, example: `AFTER`, choices: ``BEFORE`, `AFTER`, `BOTH`, `NONE``. [selective-alignment mode only]\nDetermines the policy by which hits are filtered in selective alignment. Filtering hits after chaining (the default) is more sensitive, but more computationally intensive, because it performs the chaining dynamic program for all hits. Filtering before chaining is faster, but some true hits may be missed. The options are BEFORE, AFTER, BOTH and NONE.\n", - "enum": ["BEFORE", "AFTER", "BOTH", "NONE"] - - - } - - -} -}, - - - "advance options" : { - "title": "Advance options", - "type": "object", - "description": "No description", - "properties": { - - - "alternative_init_mode": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Use an alternative strategy (rather than simple interpolation between) the online and uniform abundance estimates to initialize the EM / VBEM algorithm", - "help_text": "Type: `boolean_true`, default: `false`. Use an alternative strategy (rather than simple interpolation between) the online and uniform abundance estimates to initialize the EM / VBEM algorithm.\n" - , - "default": "False" - } - - - , - "aux_dir": { - "type": - "string", - "description": "Type: `file`, default: `$id.$key.aux_dir.aux_dir`, example: `aux_info`. The sub-directory of the quantification directory where auxiliary information e", - "help_text": "Type: `file`, default: `$id.$key.aux_dir.aux_dir`, example: `aux_info`. The sub-directory of the quantification directory where auxiliary information e.g. bootstraps, bias parameters, etc. will be written.\n" - , - "default": "$id.$key.aux_dir.aux_dir" - } - - - , - "skip_quant": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Skip performing the actual transcript quantification (including any Gibbs sampling or bootstrapping)", - "help_text": "Type: `boolean_true`, default: `false`. Skip performing the actual transcript quantification (including any Gibbs sampling or bootstrapping).\n" - , - "default": "False" - } - - - , - "dump_eq": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Dump the simple equivalence class counts that were computed during mapping or alignment", - "help_text": "Type: `boolean_true`, default: `false`. Dump the simple equivalence class counts that were computed during mapping or alignment.\n" - , - "default": "False" - } - - - , - "dump_eq_weights": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Dump conditional probabilities associated with transcripts when equivalence class information is being dumped to file", - "help_text": "Type: `boolean_true`, default: `false`. Dump conditional probabilities associated with transcripts when equivalence class information is being dumped to file. Note, this will dump the factorization that is actually used by salmon\u0027s offline phase for inference. If you are using range-factorized equivalence classes (the default) then the same transcript set may appear multiple times with different associated conditional probabilities.\n" - , - "default": "False" - } - - - , - "min_assigned_frags": { - "type": - "integer", - "description": "Type: `integer`, example: `10`. The minimum number of fragments that must be assigned to the transcriptome for quantification to proceed", - "help_text": "Type: `integer`, example: `10`. The minimum number of fragments that must be assigned to the transcriptome for quantification to proceed.\n" - - } - - - , - "reduce_GC_memory": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. If this option is selected, a more memory efficient (but slightly slower) representation is used to compute fragment GC content", - "help_text": "Type: `boolean_true`, default: `false`. If this option is selected, a more memory efficient (but slightly slower) representation is used to compute fragment GC content. Enabling this will reduce memory usage, but can also reduce speed. However, the results themselves will remain the same.\n" - , - "default": "False" - } - - - , - "bias_speed_samp": { - "type": - "integer", - "description": "Type: `integer`, example: `5`. The value at which the fragment length PMF is down-sampled when evaluating sequence-specific \u0026 GC fragment bias", - "help_text": "Type: `integer`, example: `5`. The value at which the fragment length PMF is down-sampled when evaluating sequence-specific \u0026 GC fragment bias. Larger values speed up effective length correction, but may decrease the fidelity of bias modeling results.\n" - - } - - - , - "fld_max": { - "type": - "integer", - "description": "Type: `integer`, example: `1000`. The maximum fragment length to consider when building the empirical distribution\n", - "help_text": "Type: `integer`, example: `1000`. The maximum fragment length to consider when building the empirical distribution\n" - - } - - - , - "fld_mean": { - "type": - "integer", - "description": "Type: `integer`, example: `250`. The mean used in the fragment length distribution prior\n", - "help_text": "Type: `integer`, example: `250`. The mean used in the fragment length distribution prior\n" - - } - - - , - "fld_SD": { - "type": - "integer", - "description": "Type: `integer`, example: `25`. The standard deviation used in the fragment length distribution prior\n", - "help_text": "Type: `integer`, example: `25`. The standard deviation used in the fragment length distribution prior\n" - - } - - - , - "forgetting_factor": { - "type": - "number", - "description": "Type: `double`, example: `0.65`. The forgetting factor used in the online learning schedule", - "help_text": "Type: `double`, example: `0.65`. The forgetting factor used in the online learning schedule. A smallervalue results in quicker learning, but higher variance and may be unstable. A larger value results in slower learning but may be more stable. Value should be in the interval (0.5, 1.0].\n" - - } - - - , - "init_uniform": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Initialize the offline inference with uniform parameters, rather than seeding with online parameters", - "help_text": "Type: `boolean_true`, default: `false`. Initialize the offline inference with uniform parameters, rather than seeding with online parameters.\n" - , - "default": "False" - } - - - , - "max_occs_per_hit": { - "type": - "integer", - "description": "Type: `integer`, example: `1000`. When collecting \"hits\" (MEMs), hits having more than max_occs_per_hit occurrences won\u0027t be considered", - "help_text": "Type: `integer`, example: `1000`. When collecting \"hits\" (MEMs), hits having more than max_occs_per_hit occurrences won\u0027t be considered.\n" - - } - - - , - "max_read_occ": { - "type": - "integer", - "description": "Type: `integer`, example: `200`. Reads \"mapping\" to more than this many places won\u0027t be considered", - "help_text": "Type: `integer`, example: `200`. Reads \"mapping\" to more than this many places won\u0027t be considered.\n" - - } - - - , - "no_length_correction": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Entirely disables length correction when estimating the abundance of transcripts", - "help_text": "Type: `boolean_true`, default: `false`. Entirely disables length correction when estimating the abundance of transcripts. This option can be used with protocols where one expects that fragments derive from their underlying targets without regard to that target\u0027s length (e.g. QuantSeq)\n" - , - "default": "False" - } - - - , - "no_effective_length_correction": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Disables effective length correction when computing the probability that a fragment was generated from a transcript", - "help_text": "Type: `boolean_true`, default: `false`. Disables effective length correction when computing the probability that a fragment was generated from a transcript. If this flag is passed in,the fragment length distribution is not taken into account when computing this probability.\n" - , - "default": "False" - } - - - , - "no_single_frag_prob": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Disables the estimation of an associated fragment length probability for single-end reads or for orphaned mappings in paired-end libraries", - "help_text": "Type: `boolean_true`, default: `false`. Disables the estimation of an associated fragment length probability for single-end reads or for orphaned mappings in paired-end libraries. The default behavior is to consider the probability of all possible fragment lengths associated with the retained mapping. Enabling this flag (i.e. turning this default behavior off) will simply not attempt to estimate a fragment length probability in such cases.\n" - , - "default": "False" - } - - - , - "no_frag_length_dist": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Don\u0027t consider concordance with the learned fragment length distribution when trying to determine the probability that a fragment has originated from a specified location", - "help_text": "Type: `boolean_true`, default: `false`. Don\u0027t consider concordance with the learned fragment length distribution when trying to determine the probability that a fragment has originated from a specified location. Normally, Fragments with unlikely lengths will be assigned a smaller relative probability than those with more likely lengths. When this flag is passed in, the observed fragment length has no effect on that fragment\u0027s a priori probability.\n" - , - "default": "False" - } - - - , - "no_bias_length_threshold": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. If this option is enabled, then no (lower) threshold will be set on how short bias correction can make effective lengths", - "help_text": "Type: `boolean_true`, default: `false`. If this option is enabled, then no (lower) threshold will be set on how short bias correction can make effective lengths. This can increase the precision of bias correction, but harm robustness. The default correction applies a threshold.\n" - , - "default": "False" - } - - - , - "num_bias_samples": { - "type": - "integer", - "description": "Type: `integer`, example: `2000000`. Number of fragment mappings to use when learning the sequence-specific bias model", - "help_text": "Type: `integer`, example: `2000000`. Number of fragment mappings to use when learning the sequence-specific bias model.\n" - - } - - - , - "num_aux_model_samples": { - "type": - "integer", - "description": "Type: `integer`, example: `5000000`. The first \u003cnum_aux_model_samples\u003e are used to train the auxiliary model parameters (e", - "help_text": "Type: `integer`, example: `5000000`. The first \u003cnum_aux_model_samples\u003e are used to train the auxiliary model parameters (e.g. fragment length distribution, bias, etc.). After ther first \u003cnum_aux_model_samples\u003e observations the auxiliary model parameters will be assumed to have converged and will be fixed.\n" - - } - - - , - "num_pre_aux_model_samples": { - "type": - "integer", - "description": "Type: `integer`, example: `5000`. The first \u003cnumPreAuxModelSamples\u003e will have their assignment likelihoods and contributions to the transcript abundances computed without applying any auxiliary models", - "help_text": "Type: `integer`, example: `5000`. The first \u003cnumPreAuxModelSamples\u003e will have their assignment likelihoods and contributions to the transcript abundances computed without applying any auxiliary models. The purpose of ignoring the auxiliary models for the first \u003cnum_pre_aux_model_samples\u003e observations is to avoid applying these models before their parameters have been learned sufficiently well.\n" - - } - - - , - "useEM": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Use the traditional EM algorithm for optimization in the batch passes", - "help_text": "Type: `boolean_true`, default: `false`. Use the traditional EM algorithm for optimization in the batch passes.\n" - , - "default": "False" - } - - - , - "useVBOpt": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Use the Variational Bayesian EM [default]\n", - "help_text": "Type: `boolean_true`, default: `false`. Use the Variational Bayesian EM [default]\n" - , - "default": "False" - } - - - , - "range_factorization_bins": { - "type": - "integer", - "description": "Type: `integer`, example: `4`. Factorizes the likelihood used in quantification by adopting a new notion of equivalence classes based on the conditional probabilities with which fragments are generated from different transcripts", - "help_text": "Type: `integer`, example: `4`. Factorizes the likelihood used in quantification by adopting a new notion of equivalence classes based on the conditional probabilities with which fragments are generated from different transcripts. This is a more fine-grained factorization than the normal rich equivalence classes. The default value (4) corresponds to the default used in Zakeri et al. 2017 (doi: 10.1093/bioinformatics/btx262), and larger values imply a more fine-grained factorization. If range factorization is enabled, a common value to select for this parameter is 4. A value of 0 signifies the use of basic rich equivalence classes.\n" - - } - - - , - "num_Gibbs_samples": { - "type": - "integer", - "description": "Type: `integer`, example: `0`. Number of Gibbs sampling rounds to perform", - "help_text": "Type: `integer`, example: `0`. Number of Gibbs sampling rounds to perform.\n" - - } - - - , - "no_Gamma_draw": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. This switch will disable drawing transcript fractions from a Gamma distribution during Gibbs sampling", - "help_text": "Type: `boolean_true`, default: `false`. This switch will disable drawing transcript fractions from a Gamma distribution during Gibbs sampling. In this case the sampler does not account for shot-noise, but only assignment ambiguity\n" - , - "default": "False" - } - - - , - "num_bootstraps": { - "type": - "integer", - "description": "Type: `integer`, example: `0`. Number of bootstrap samples to generate", - "help_text": "Type: `integer`, example: `0`. Number of bootstrap samples to generate. Note: This is mutually exclusive with Gibbs sampling.\n" - - } - - - , - "bootstrap_reproject": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. This switch will learn the parameter distribution from the bootstrapped counts for each sample, but will reproject those parameters onto the original equivalence class counts", - "help_text": "Type: `boolean_true`, default: `false`. This switch will learn the parameter distribution from the bootstrapped counts for each sample, but will reproject those parameters onto the original equivalence class counts.\n" - , - "default": "False" - } - - - , - "thinning_factor": { - "type": - "integer", - "description": "Type: `integer`, example: `16`. Number of steps to discard for every sample kept from the Gibbs chain", - "help_text": "Type: `integer`, example: `16`. Number of steps to discard for every sample kept from the Gibbs chain. The larger this number, the less chance that subsequent samples are auto-correlated, but the slower sampling becomes.\n" - - } - - - , - "quiet": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Be quiet while doing quantification (don\u0027t write informative output to the console unless something goes wrong)", - "help_text": "Type: `boolean_true`, default: `false`. Be quiet while doing quantification (don\u0027t write informative output to the console unless something goes wrong).\n" - , - "default": "False" - } - - - , - "per_transcript_prior": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. The prior (either the default or the argument provided via --vb_prior) will be interpreted as a transcript-level prior (i", - "help_text": "Type: `boolean_true`, default: `false`. The prior (either the default or the argument provided via --vb_prior) will be interpreted as a transcript-level prior (i.e. each transcript will be given a prior read count of this value)\n" - , - "default": "False" - } - - - , - "per_nucleotide_prior": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. The prior (either the default or the argument provided via --vb_prior) will be interpreted as a nucleotide-level prior (i", - "help_text": "Type: `boolean_true`, default: `false`. The prior (either the default or the argument provided via --vb_prior) will be interpreted as a nucleotide-level prior (i.e. each nucleotide will be given a prior read count of this value)\n" - , - "default": "False" - } - - - , - "sig_digits": { - "type": - "integer", - "description": "Type: `integer`, example: `3`. The number of significant digits to write when outputting the EffectiveLength and NumReads columns\n", - "help_text": "Type: `integer`, example: `3`. The number of significant digits to write when outputting the EffectiveLength and NumReads columns\n" - - } - - - , - "vb_prior": { - "type": - "number", - "description": "Type: `double`, example: `0.01`. The prior that will be used in the VBEM algorithm", - "help_text": "Type: `double`, example: `0.01`. The prior that will be used in the VBEM algorithm. This is interpreted as a per-transcript prior, unless the --per_nucleotide_prior flag is also given. If the --per_nucleotide_prior flag is given, this is used as a nucleotide-level prior. If the default is used, it will be divided by 1000 before being used as a nucleotide-level prior, i.e. the default per-nucleotide prior will be 1e-5.\n" - - } - - - , - "write_orphan_links": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Write the transcripts that are linked by orphaned reads", - "help_text": "Type: `boolean_true`, default: `false`. Write the transcripts that are linked by orphaned reads.\n" - , - "default": "False" - } - - - , - "write_unmapped_names": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Write the names of un-mapped reads to the file unmapped_names", - "help_text": "Type: `boolean_true`, default: `false`. Write the names of un-mapped reads to the file unmapped_names.txt in the auxiliary directory.\n" - , - "default": "False" - } - - -} -}, - - - "alignment-specific options" : { - "title": "Alignment-specific options", - "type": "object", - "description": "No description", - "properties": { - - - "no_error_model": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Turn off the alignment error model, which takes into account the the observed frequency of different types of mismatches / indels when computing the likelihood of a given alignment", - "help_text": "Type: `boolean_true`, default: `false`. Turn off the alignment error model, which takes into account the the observed frequency of different types of mismatches / indels when computing the likelihood of a given alignment. Turning this off can speed up alignment-based salmon, but can harm quantification accuracy.\n" - , - "default": "False" - } - - - , - "num_error_bins": { - "type": - "integer", - "description": "Type: `integer`, example: `6`. The number of bins into which to divide each read when learning and applying the error model", - "help_text": "Type: `integer`, example: `6`. The number of bins into which to divide each read when learning and applying the error model. For example, a value of 10 would mean that effectively, a separate error model is leared and applied to each 10th of the read, while a value of 3 would mean that a separate error model is applied to the read beginning (first third), middle (second third) and end (final third).\n" - - } - - - , - "sample_out": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Write a \"postSample", - "help_text": "Type: `boolean_true`, default: `false`. Write a \"postSample.bam\" file in the output directory that will sample the input alignments according to the estimated transcript abundances. If you\u0027re going to perform downstream analysis of the alignments with tools which don\u0027t, themselves, take fragment assignment ambiguity into account, you should use this output.\n" - , - "default": "False" - } - - - , - "sample_unaligned": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. In addition to sampling the aligned reads, also write the un-aligned reads to \"postSample", - "help_text": "Type: `boolean_true`, default: `false`. In addition to sampling the aligned reads, also write the un-aligned reads to \"postSample.bam\".\n" - , - "default": "False" - } - - - , - "gencode": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. This flag will expect the input transcript fasta to be in GENCODE format, and will split the transcript name at the first \u0027|\u0027 character", - "help_text": "Type: `boolean_true`, default: `false`. This flag will expect the input transcript fasta to be in GENCODE format, and will split the transcript name at the first \u0027|\u0027 character. These reduced names will be used in the output and when looking for these transcripts in a gene to transcript GTF.\n" - , - "default": "False" - } - - - , - "mapping_cache_memory_limit": { - "type": - "integer", - "description": "Type: `integer`, example: `2000000`. If the file contained fewer than this many mapped reads, then just keep the data in memory for subsequent rounds of inference", - "help_text": "Type: `integer`, example: `2000000`. If the file contained fewer than this many mapped reads, then just keep the data in memory for subsequent rounds of inference. Obviously, this value should not be too large if you wish to keep a low memory usage, but setting it large enough to accommodate all of the mapped read can substantially speed up inference on \"small\" files that contain only a few million reads.\n" - - } - - -} -}, - - - "nextflow input-output arguments" : { - "title": "Nextflow input-output arguments", - "type": "object", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "properties": { - - - "publish_dir": { - "type": - "string", - "description": "Type: `string`, required, example: `output/`. Path to an output directory", - "help_text": "Type: `string`, required, example: `output/`. Path to an output directory." - - } - - - , - "param_list": { - "type": - "string", - "description": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel", - "help_text": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob.\n\n* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ [\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027], [\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027] ]`.\n* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`.\n* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]`.\n* A yaml blob can also be passed directly as a string. Example: `--param_list \"[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]\"`.\n\nWhen passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.", - "hidden": true - - } - - -} -} -}, -"allOf": [ - - { - "$ref": "#/definitions/common input options" - }, - - { - "$ref": "#/definitions/mapping input options" - }, - - { - "$ref": "#/definitions/alignment input options" - }, - - { - "$ref": "#/definitions/output" - }, - - { - "$ref": "#/definitions/basic options" - }, - - { - "$ref": "#/definitions/options specific to mapping mode" - }, - - { - "$ref": "#/definitions/advance options" - }, - - { - "$ref": "#/definitions/alignment-specific options" - }, - - { - "$ref": "#/definitions/nextflow input-output arguments" - } -] -} diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/.config.vsh.yaml deleted file mode 100644 index 0d6e9f3..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/.config.vsh.yaml +++ /dev/null @@ -1,185 +0,0 @@ -name: "samtools_flagstat" -namespace: "samtools" -version: "v0.1.0" -argument_groups: -- name: "Inputs" - arguments: - - type: "file" - name: "--bam" - description: "BAM input files.\n" - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--bai" - description: "BAM index file.\n" - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" -- name: "Outputs" - arguments: - - type: "file" - name: "--output" - description: "File containing samtools stats output.\n" - info: null - example: - - "output.flagstat" - must_exist: true - create_parent: true - required: true - direction: "output" - multiple: false - multiple_sep: ";" -resources: -- type: "bash_script" - path: "script.sh" - is_executable: true -description: "Counts the number of alignments in SAM/BAM/CRAM files for each FLAG\ - \ type." -test_resources: -- type: "bash_script" - path: "test.sh" - is_executable: true -- type: "file" - path: "test_data" -info: null -status: "enabled" -requirements: - commands: - - "ps" -keywords: -- "stats" -- "mapping" -- "counts" -- "bam" -- "sam" -- "cram" -license: "MIT/Expat" -references: - doi: - - "10.1093/bioinformatics/btp352" - - "10.1093/gigascience/giab008" -links: - repository: "https://github.com/samtools/samtools" - homepage: "https://www.htslib.org/" - documentation: "https://www.htslib.org/doc/samtools-flagstat.html" -runners: -- type: "executable" - id: "executable" - docker_setup_strategy: "ifneedbepullelsecachedbuild" -- type: "nextflow" - id: "nextflow" - directives: - tag: "$id" - auto: - simplifyInput: true - simplifyOutput: false - transcript: false - publish: false - config: - labels: - mem1gb: "memory = 1000000000.B" - mem2gb: "memory = 2000000000.B" - mem5gb: "memory = 5000000000.B" - mem10gb: "memory = 10000000000.B" - mem20gb: "memory = 20000000000.B" - mem50gb: "memory = 50000000000.B" - mem100gb: "memory = 100000000000.B" - mem200gb: "memory = 200000000000.B" - mem500gb: "memory = 500000000000.B" - mem1tb: "memory = 1000000000000.B" - mem2tb: "memory = 2000000000000.B" - mem5tb: "memory = 5000000000000.B" - mem10tb: "memory = 10000000000000.B" - mem20tb: "memory = 20000000000000.B" - mem50tb: "memory = 50000000000000.B" - mem100tb: "memory = 100000000000000.B" - mem200tb: "memory = 200000000000000.B" - mem500tb: "memory = 500000000000000.B" - mem1gib: "memory = 1073741824.B" - mem2gib: "memory = 2147483648.B" - mem4gib: "memory = 4294967296.B" - mem8gib: "memory = 8589934592.B" - mem16gib: "memory = 17179869184.B" - mem32gib: "memory = 34359738368.B" - mem64gib: "memory = 68719476736.B" - mem128gib: "memory = 137438953472.B" - mem256gib: "memory = 274877906944.B" - mem512gib: "memory = 549755813888.B" - mem1tib: "memory = 1099511627776.B" - mem2tib: "memory = 2199023255552.B" - mem4tib: "memory = 4398046511104.B" - mem8tib: "memory = 8796093022208.B" - mem16tib: "memory = 17592186044416.B" - mem32tib: "memory = 35184372088832.B" - mem64tib: "memory = 70368744177664.B" - mem128tib: "memory = 140737488355328.B" - mem256tib: "memory = 281474976710656.B" - mem512tib: "memory = 562949953421312.B" - cpu1: "cpus = 1" - cpu2: "cpus = 2" - cpu5: "cpus = 5" - cpu10: "cpus = 10" - cpu20: "cpus = 20" - cpu50: "cpus = 50" - cpu100: "cpus = 100" - cpu200: "cpus = 200" - cpu500: "cpus = 500" - cpu1000: "cpus = 1000" - debug: false - container: "docker" -engines: -- type: "docker" - id: "docker" - image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" - target_registry: "images.viash-hub.com" - target_tag: "v0.1.0" - namespace_separator: "/" - setup: - - type: "docker" - run: - - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\nsed 's#Using\ - \ ##;s# \\([0-9\\.]*\\)$#: \\1#' > /var/software_versions.txt\n" - entrypoint: [] - cmd: null -- type: "native" - id: "native" -build_info: - config: "src/samtools/samtools_flagstat/config.vsh.yaml" - runner: "nextflow" - engine: "docker|native" - output: "target/nextflow/samtools/samtools_flagstat" - executable: "target/nextflow/samtools/samtools_flagstat/main.nf" - viash_version: "0.9.0-RC6" - git_commit: "b84b29747d0635f2ac83ea63b496be9a9edb6724" - git_remote: "https://github.com/viash-hub/biobox" -package_config: - name: "biobox" - version: "v0.1.0" - description: "A collection of bioinformatics tools for working with sequence data.\n" - info: null - viash_version: "0.9.0-RC6" - source: "src" - target: "target" - config_mods: - - ".requirements.commands := ['ps']\n" - - ".engines += { type: \"native\" }" - - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - keywords: - - "bioinformatics" - - "modules" - - "sequencing" - license: "MIT" - organization: "vsh" - links: - repository: "https://github.com/viash-hub/biobox" - issue_tracker: "https://github.com/viash-hub/biobox/issues" diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/main.nf b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/main.nf deleted file mode 100644 index 4307310..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/main.nf +++ /dev/null @@ -1,3528 +0,0 @@ -// samtools_flagstat v0.1.0 -// -// This wrapper script is auto-generated by viash 0.9.0-RC6 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. -// -// The component may contain files which fall under a different license. The -// authors of this component should specify the license in the header of such -// files, or include a separate license file detailing the licenses of all included -// files. - -//////////////////////////// -// VDSL3 helper functions // -//////////////////////////// - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_checkArgumentType.nf' -class UnexpectedArgumentTypeException extends Exception { - String errorIdentifier - String stage - String plainName - String expectedClass - String foundClass - - // ${key ? " in module '$key'" : ""}${id ? " id '$id'" : ""} - UnexpectedArgumentTypeException(String errorIdentifier, String stage, String plainName, String expectedClass, String foundClass) { - super("Error${errorIdentifier ? " $errorIdentifier" : ""}:${stage ? " $stage" : "" } argument '${plainName}' has the wrong type. " + - "Expected type: ${expectedClass}. Found type: ${foundClass}") - this.errorIdentifier = errorIdentifier - this.stage = stage - this.plainName = plainName - this.expectedClass = expectedClass - this.foundClass = foundClass - } -} - -/** - * Checks if the given value is of the expected type. If not, an exception is thrown. - * - * @param stage The stage of the argument (input or output) - * @param par The parameter definition - * @param value The value to check - * @param errorIdentifier The identifier to use in the error message - * @return The value, if it is of the expected type - * @throws UnexpectedArgumentTypeException If the value is not of the expected type -*/ -def _checkArgumentType(String stage, Map par, Object value, String errorIdentifier) { - // expectedClass will only be != null if value is not of the expected type - def expectedClass = null - def foundClass = null - - // todo: split if need be - - if (!par.required && value == null) { - expectedClass = null - } else if (par.multiple) { - if (value !instanceof Collection) { - value = [value] - } - - // split strings - value = value.collectMany{ val -> - if (val instanceof String) { - // collect() to ensure that the result is a List and not simply an array - val.split(par.multiple_sep).collect() - } else { - [val] - } - } - - // process globs - if (par.type == "file" && par.direction == "input") { - value = value.collect{ it instanceof String ? file(it, hidden: true) : it }.flatten() - } - - // check types of elements in list - try { - value = value.collect { listVal -> - _checkArgumentType(stage, par + [multiple: false], listVal, errorIdentifier) - } - } catch (UnexpectedArgumentTypeException e) { - expectedClass = "List[${e.expectedClass}]" - foundClass = "List[${e.foundClass}]" - } - } else if (par.type == "string") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else if (par.type == "integer") { - // cast to integer if need be - if (value instanceof String) { - try { - value = value.toInteger() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigInteger) { - value = value.intValue() - } - expectedClass = value instanceof Integer ? null : "Integer" - } else if (par.type == "long") { - // cast to long if need be - if (value instanceof String) { - try { - value = value.toLong() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof Integer) { - value = value.toLong() - } - expectedClass = value instanceof Long ? null : "Long" - } else if (par.type == "double") { - // cast to double if need be - if (value instanceof String) { - try { - value = value.toDouble() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigDecimal) { - value = value.doubleValue() - } - if (value instanceof Float) { - value = value.toDouble() - } - expectedClass = value instanceof Double ? null : "Double" - } else if (par.type == "boolean" | par.type == "boolean_true" | par.type == "boolean_false") { - // cast to boolean if need be - if (value instanceof String) { - def valueLower = value.toLowerCase() - if (valueLower == "true") { - value = true - } else if (valueLower == "false") { - value = false - } - } - expectedClass = value instanceof Boolean ? null : "Boolean" - } else if (par.type == "file" && (par.direction == "input" || stage == "output")) { - // cast to path if need be - if (value instanceof String) { - value = file(value, hidden: true) - } - if (value instanceof File) { - value = value.toPath() - } - expectedClass = value instanceof Path ? null : "Path" - } else if (par.type == "file" && stage == "input" && par.direction == "output") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else { - // didn't find a match for par.type - expectedClass = par.type - } - - if (expectedClass != null) { - if (foundClass == null) { - foundClass = value.getClass().getName() - } - throw new UnexpectedArgumentTypeException(errorIdentifier, stage, par.plainName, expectedClass, foundClass) - } - - return value -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processInputValues.nf' -Map _processInputValues(Map inputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.required) { - assert inputs.containsKey(arg.plainName) && inputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required input argument '${arg.plainName}' is missing" - } - } - - inputs = inputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid input argument" - - value = _checkArgumentType("input", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return inputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processOutputValues.nf' -Map _processOutputValues(Map outputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.direction == "output" && arg.required) { - assert outputs.containsKey(arg.plainName) && outputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required output argument '${arg.plainName}' is missing" - } - } - - outputs = outputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && it.direction == "output" } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid output argument" - - value = _checkArgumentType("output", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return outputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/IDChecker.nf' -class IDChecker { - final def items = [] as Set - - @groovy.transform.WithWriteLock - boolean observe(String item) { - if (items.contains(item)) { - return false - } else { - items << item - return true - } - } - - @groovy.transform.WithReadLock - boolean contains(String item) { - return items.contains(item) - } - - @groovy.transform.WithReadLock - Set getItems() { - return items.clone() - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_checkUniqueIds.nf' - -/** - * Check if the ids are unique across parameter sets - * - * @param parameterSets a list of parameter sets. - */ -private void _checkUniqueIds(List>> parameterSets) { - def ppIds = parameterSets.collect{it[0]} - assert ppIds.size() == ppIds.unique().size() : "All argument sets should have unique ids. Detected ids: $ppIds" -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_getChild.nf' - -// helper functions for reading params from file // -def _getChild(parent, child) { - if (child.contains("://") || java.nio.file.Paths.get(child).isAbsolute()) { - child - } else { - def parentAbsolute = java.nio.file.Paths.get(parent).toAbsolutePath().toString() - parentAbsolute.replaceAll('/[^/]*$', "/") + child - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_parseParamList.nf' -/** - * Figure out the param list format based on the file extension - * - * @param param_list A String containing the path to the parameter list file. - * - * @return A String containing the format of the parameter list file. - */ -def _paramListGuessFormat(param_list) { - if (param_list !instanceof String) { - "asis" - } else if (param_list.endsWith(".csv")) { - "csv" - } else if (param_list.endsWith(".json") || param_list.endsWith(".jsn")) { - "json" - } else if (param_list.endsWith(".yaml") || param_list.endsWith(".yml")) { - "yaml" - } else { - "yaml_blob" - } -} - - -/** - * Read the param list - * - * @param param_list One of the following: - * - A String containing the path to the parameter list file (csv, json or yaml), - * - A yaml blob of a list of maps (yaml_blob), - * - Or a groovy list of maps (asis). - * @param config A Map of the Viash configuration. - * - * @return A List of Maps containing the parameters. - */ -def _parseParamList(param_list, Map config) { - // first determine format by extension - def paramListFormat = _paramListGuessFormat(param_list) - - def paramListPath = (paramListFormat != "asis" && paramListFormat != "yaml_blob") ? - file(param_list, hidden: true) : - null - - // get the correct parser function for the detected params_list format - def paramSets = [] - if (paramListFormat == "asis") { - paramSets = param_list - } else if (paramListFormat == "yaml_blob") { - paramSets = readYamlBlob(param_list) - } else if (paramListFormat == "yaml") { - paramSets = readYaml(paramListPath) - } else if (paramListFormat == "json") { - paramSets = readJson(paramListPath) - } else if (paramListFormat == "csv") { - paramSets = readCsv(paramListPath) - } else { - error "Format of provided --param_list not recognised.\n" + - "Found: '$paramListFormat'.\n" + - "Expected: a csv file, a json file, a yaml file,\n" + - "a yaml blob or a groovy list of maps." - } - - // data checks - assert paramSets instanceof List: "--param_list should contain a list of maps" - for (value in paramSets) { - assert value instanceof Map: "--param_list should contain a list of maps" - } - - // id is argument - def idIsArgument = config.allArguments.any{it.plainName == "id"} - - // Reformat from List to List> by adding the ID as first element of a Tuple2 - paramSets = paramSets.collect({ data -> - def id = data.id - if (!idIsArgument) { - data = data.findAll{k, v -> k != "id"} - } - [id, data] - }) - - // Split parameters with 'multiple: true' - paramSets = paramSets.collect({ id, data -> - data = _splitParams(data, config) - [id, data] - }) - - // The paths of input files inside a param_list file may have been specified relatively to the - // location of the param_list file. These paths must be made absolute. - if (paramListPath) { - paramSets = paramSets.collect({ id, data -> - def new_data = data.collectEntries{ parName, parValue -> - def par = config.allArguments.find{it.plainName == parName} - if (par && par.type == "file" && par.direction == "input") { - if (parValue instanceof Collection) { - parValue = parValue.collectMany{path -> - def x = _resolveSiblingIfNotAbsolute(path, paramListPath) - x instanceof Collection ? x : [x] - } - } else { - parValue = _resolveSiblingIfNotAbsolute(parValue, paramListPath) - } - } - [parName, parValue] - } - [id, new_data] - }) - } - - return paramSets -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_splitParams.nf' -/** - * Split parameters for arguments that accept multiple values using their separator - * - * @param paramList A Map containing parameters to split. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A Map of parameters where the parameter values have been split into a list using - * their seperator. - */ -Map _splitParams(Map parValues, Map config){ - def parsedParamValues = parValues.collectEntries { parName, parValue -> - def parameterSettings = config.allArguments.find({it.plainName == parName}) - - if (!parameterSettings) { - // if argument is not found, do not alter - return [parName, parValue] - } - if (parameterSettings.multiple) { // Check if parameter can accept multiple values - if (parValue instanceof Collection) { - parValue = parValue.collect{it instanceof String ? it.split(parameterSettings.multiple_sep) : it } - } else if (parValue instanceof String) { - parValue = parValue.split(parameterSettings.multiple_sep) - } else if (parValue == null) { - parValue = [] - } else { - parValue = [ parValue ] - } - parValue = parValue.flatten() - } - // For all parameters check if multiple values are only passed for - // arguments that allow it. Quietly simplify lists of length 1. - if (!parameterSettings.multiple && parValue instanceof Collection) { - assert parValue.size() == 1 : - "Error: argument ${parName} has too many values.\n" + - " Expected amount: 1. Found: ${parValue.size()}" - parValue = parValue[0] - } - [parName, parValue] - } - return parsedParamValues -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/channelFromParams.nf' -/** - * Parse nextflow parameters based on settings defined in a viash config. - * Return a list of parameter sets, each parameter set corresponding to - * an event in a nextflow channel. The output from this function can be used - * with Channel.fromList to create a nextflow channel with Vdsl3 formatted - * events. - * - * This function performs: - * - A filtering of the params which can be found in the config file. - * - Process the params_list argument which allows a user to to initialise - * a Vsdl3 channel with multiple parameter sets. Possible formats are - * csv, json, yaml, or simply a yaml_blob. A csv should have column names - * which correspond to the different arguments of this pipeline. A json or a yaml - * file should be a list of maps, each of which has keys corresponding to the - * arguments of the pipeline. A yaml blob can also be passed directly as a parameter. - * When passing a csv, json or yaml, relative path names are relativized to the - * location of the parameter file. - * - Combine the parameter sets into a vdsl3 Channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A list of parameters with the first element of the event being - * the event ID and the second element containing a map of the parsed parameters. - */ - -private List>> _paramsToParamSets(Map params, Map config){ - // todo: fetch key from run args - def key_ = config.name - - /* parse regular parameters (not in param_list) */ - /*************************************************/ - def globalParams = config.allArguments - .findAll { params.containsKey(it.plainName) } - .collectEntries { [ it.plainName, params[it.plainName] ] } - def globalID = params.get("id", null) - - /* process params_list arguments */ - /*********************************/ - def paramList = params.containsKey("param_list") && params.param_list != null ? - params.param_list : [] - // if (paramList instanceof String) { - // paramList = [paramList] - // } - // def paramSets = paramList.collectMany{ _parseParamList(it, config) } - // TODO: be able to process param_list when it is a list of strings - def paramSets = _parseParamList(paramList, config) - if (paramSets.isEmpty()) { - paramSets = [[null, [:]]] - } - - /* combine arguments into channel */ - /**********************************/ - def processedParams = paramSets.indexed().collect{ index, tup -> - // Process ID - def id = tup[0] ?: globalID - - if (workflow.stubRun && !id) { - // if stub run, explicitly add an id if missing - id = "stub${index}" - } - assert id != null: "Each parameter set should have at least an 'id'" - - // Process params - def parValues = globalParams + tup[1] - // // Remove parameters which are null, if the default is also null - // parValues = parValues.collectEntries{paramName, paramValue -> - // parameterSettings = config.functionality.allArguments.find({it.plainName == paramName}) - // if ( paramValue != null || parameterSettings.get("default", null) != null ) { - // [paramName, paramValue] - // } - // } - parValues = parValues.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key_}' id '${id}': '${name}' is not a valid input argument" - - if (par == null) { - return [:] - } - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - - [ name, value ] - } - - [id, parValues] - } - - // Check if ids (first element of each list) is unique - _checkUniqueIds(processedParams) - return processedParams -} - -/** - * Parse nextflow parameters based on settings defined in a viash config - * and return a nextflow channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A nextflow Channel with events. Events are formatted as a tuple that contains - * first contains the ID of the event and as second element holds a parameter map. - * - * - */ -def channelFromParams(Map params, Map config) { - def processedParams = _paramsToParamSets(params, config) - return Channel.fromList(processedParams) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/checkUniqueIds.nf' -def checkUniqueIds(Map args) { - def stopOnError = args.stopOnError == null ? args.stopOnError : true - - def idChecker = new IDChecker() - - return filter { tup -> - if (!idChecker.observe(tup[0])) { - if (stopOnError) { - error "Duplicate id: ${tup[0]}" - } else { - log.warn "Duplicate id: ${tup[0]}, removing duplicate entry" - return false - } - } - return true - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/preprocessInputs.nf' -// This helper file will be deprecated soon -preprocessInputsDeprecationWarningPrinted = false - -def preprocessInputsDeprecationWarning() { - if (!preprocessInputsDeprecationWarningPrinted) { - preprocessInputsDeprecationWarningPrinted = true - System.err.println("Warning: preprocessInputs() is deprecated and will be removed in Viash 0.9.0.") - } -} - -/** - * Generate a nextflow Workflow that allows processing a channel of - * Vdsl3 formatted events and apply a Viash config to them: - * - Gather default parameters from the Viash config and make - * sure that they are correctly formatted (see applyConfig method). - * - Format the input parameters (also using the applyConfig method). - * - Apply the default parameter to the input parameters. - * - Do some assertions: - * ~ Check if the event IDs in the channel are unique. - * - * The events in the channel are formatted as tuples, with the - * first element of the tuples being a unique id of the parameter set, - * and the second element containg the the parameters themselves. - * Optional extra elements of the tuples will be passed to the output as is. - * - * @param args A map that must contain a 'config' key that points - * to a parsed config (see readConfig()). Optionally, a - * 'key' key can be provided which can be used to create a unique - * name for the workflow process. - * - * @return A workflow that allows processing a channel of Vdsl3 formatted events - * and apply a Viash config to them. - */ -def preprocessInputs(Map args) { - preprocessInputsDeprecationWarning() - - def config = args.config - assert config instanceof Map : - "Error in preprocessInputs: config must be a map. " + - "Expected class: Map. Found: config.getClass() is ${config.getClass()}" - def key_ = args.key ?: config.name - - // Get different parameter types (used throughout this function) - def defaultArgs = config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - map { tup -> - def id = tup[0] - def data = tup[1] - def passthrough = tup.drop(2) - - def new_data = (defaultArgs + data).collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - - if (par != null) { - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - } - - [ name, value ] - } - - [ id, new_data ] + passthrough - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runComponents.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component config. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component config. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component config. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component config. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runComponents(Map args) { - log.warn("runComponents is deprecated, use runEach instead") - assert args.components: "runComponents should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runComponents" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runComponentsWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def comp_config = comp_.config - - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_config) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - // def new_id = id_(tup[0], tup[1], comp_config) - def new_id = tup[0] - if (id_ instanceof String) { - new_id = id_ - } else if (id_ instanceof Closure) { - new_id = id_(new_id, tup[1], comp_config) - } - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_config) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_config) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runComponentsWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runEach.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component itself. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component itself. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component itself. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component itself. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runEach(Map args) { - assert args.components: "runEach should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runEach" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runEachWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - def new_id = id_ - if (new_id instanceof Closure) { - new_id = new_id(tup[0], tup[1], comp_) - } - assert new_id instanceof String : "Error in runEach: id should be a String or a Closure that returns a String. Expected: id instanceof String. Found: ${new_id.getClass()}" - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runEachWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/safeJoin.nf' -/** - * Join sourceChannel to targetChannel - * - * This function joins the sourceChannel to the targetChannel. - * However, each id in the targetChannel must be present in the - * sourceChannel. If _meta.join_id exists in the targetChannel, that is - * used as an id instead. If the id doesn't match any id in the sourceChannel, - * an error is thrown. - */ - -def safeJoin(targetChannel, sourceChannel, key) { - def sourceIDs = new IDChecker() - - def sourceCheck = sourceChannel - | map { tup -> - sourceIDs.observe(tup[0]) - tup - } - def targetCheck = targetChannel - | map { tup -> - def id = tup[0] - - if (!sourceIDs.contains(id)) { - error ( - "Error in module '${key}' when merging output with original state.\n" + - " Reason: output with id '${id}' could not be joined with source channel.\n" + - " If the IDs in the output channel differ from the input channel,\n" + - " please set `tup[1]._meta.join_id to the original ID.\n" + - " Original IDs in input channel: ['${sourceIDs.getItems().join("', '")}'].\n" + - " Unexpected ID in the output channel: '${id}'.\n" + - " Example input event: [\"id\", [input: file(...)]],\n" + - " Example output event: [\"newid\", [output: file(...), _meta: [join_id: \"id\"]]]" - ) - } - // TODO: add link to our documentation on how to fix this - - tup - } - - sourceCheck.cross(targetChannel) - | map{ left, right -> - right + left.drop(1) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/_processArgument.nf' -def _processArgument(arg) { - arg.multiple = arg.multiple != null ? arg.multiple : false - arg.required = arg.required != null ? arg.required : false - arg.direction = arg.direction != null ? arg.direction : "input" - arg.multiple_sep = arg.multiple_sep != null ? arg.multiple_sep : ";" - arg.plainName = arg.name.replaceAll("^-*", "") - - if (arg.type == "file") { - arg.must_exist = arg.must_exist != null ? arg.must_exist : true - arg.create_parent = arg.create_parent != null ? arg.create_parent : true - } - - // add default values to output files which haven't already got a default - if (arg.type == "file" && arg.direction == "output" && arg.default == null) { - def mult = arg.multiple ? "_*" : "" - def extSearch = "" - if (arg.default != null) { - extSearch = arg.default - } else if (arg.example != null) { - extSearch = arg.example - } - if (extSearch instanceof List) { - extSearch = extSearch[0] - } - def extSearchResult = extSearch.find("\\.[^\\.]+\$") - def ext = extSearchResult != null ? extSearchResult : "" - arg.default = "\$id.\$key.${arg.plainName}${mult}${ext}" - if (arg.multiple) { - arg.default = [arg.default] - } - } - - if (!arg.multiple) { - if (arg.default != null && arg.default instanceof List) { - arg.default = arg.default[0] - } - if (arg.example != null && arg.example instanceof List) { - arg.example = arg.example[0] - } - } - - if (arg.type == "boolean_true") { - arg.default = false - } - if (arg.type == "boolean_false") { - arg.default = true - } - - arg -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/addGlobalParams.nf' -def addGlobalArguments(config) { - def localConfig = [ - "argument_groups": [ - [ - "name": "Nextflow input-output arguments", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "arguments" : [ - [ - 'name': '--publish_dir', - 'required': true, - 'type': 'string', - 'description': 'Path to an output directory.', - 'example': 'output/', - 'multiple': false - ], - [ - 'name': '--param_list', - 'required': false, - 'type': 'string', - 'description': '''Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob. - | - |* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ ['id': 'foo', 'input': 'foo.txt'], ['id': 'bar', 'input': 'bar.txt'] ]`. - |* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`. - |* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]`. - |* A yaml blob can also be passed directly as a string. Example: `--param_list "[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]"`. - | - |When passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.'''.stripMargin(), - 'example': 'my_params.yaml', - 'multiple': false, - 'hidden': true - ] - // TODO: allow multiple: true in param_list? - // TODO: allow to specify a --param_list_regex to filter the param_list? - // TODO: allow to specify a --param_list_from_state to remap entries in the param_list? - ] - ] - ] - ] - - return processConfig(_mergeMap(config, localConfig)) -} - -def _mergeMap(Map lhs, Map rhs) { - return rhs.inject(lhs.clone()) { map, entry -> - if (map[entry.key] instanceof Map && entry.value instanceof Map) { - map[entry.key] = _mergeMap(map[entry.key], entry.value) - } else if (map[entry.key] instanceof Collection && entry.value instanceof Collection) { - map[entry.key] += entry.value - } else { - map[entry.key] = entry.value - } - return map - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/generateHelp.nf' -def _generateArgumentHelp(param) { - // alternatives are not supported - // def names = param.alternatives ::: List(param.name) - - def unnamedProps = [ - ["required parameter", param.required], - ["multiple values allowed", param.multiple], - ["output", param.direction.toLowerCase() == "output"], - ["file must exist", param.type == "file" && param.must_exist] - ].findAll{it[1]}.collect{it[0]} - - def dflt = null - if (param.default != null) { - if (param.default instanceof List) { - dflt = param.default.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - dflt = param.default.toString() - } - } - def example = null - if (param.example != null) { - if (param.example instanceof List) { - example = param.example.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - example = param.example.toString() - } - } - def min = param.min?.toString() - def max = param.max?.toString() - - def escapeChoice = { choice -> - def s1 = choice.replaceAll("\\n", "\\\\n") - def s2 = s1.replaceAll("\"", """\\\"""") - s2.contains(",") || s2 != choice ? "\"" + s2 + "\"" : s2 - } - def choices = param.choices == null ? - null : - "[ " + param.choices.collect{escapeChoice(it.toString())}.join(", ") + " ]" - - def namedPropsStr = [ - ["type", ([param.type] + unnamedProps).join(", ")], - ["default", dflt], - ["example", example], - ["choices", choices], - ["min", min], - ["max", max] - ] - .findAll{it[1]} - .collect{"\n " + it[0] + ": " + it[1].replaceAll("\n", "\\n")} - .join("") - - def descStr = param.description == null ? - "" : - _paragraphWrap("\n" + param.description.trim(), 80 - 8).join("\n ") - - "\n --" + param.plainName + - namedPropsStr + - descStr -} - -// Based on Helper.generateHelp() in Helper.scala -def _generateHelp(config) { - def fun = config - - // PART 1: NAME AND VERSION - def nameStr = fun.name + - (fun.version == null ? "" : " " + fun.version) - - // PART 2: DESCRIPTION - def descrStr = fun.description == null ? - "" : - "\n\n" + _paragraphWrap(fun.description.trim(), 80).join("\n") - - // PART 3: Usage - def usageStr = fun.usage == null ? - "" : - "\n\nUsage:\n" + fun.usage.trim() - - // PART 4: Options - def argGroupStrs = fun.allArgumentGroups.collect{argGroup -> - def name = argGroup.name - def descriptionStr = argGroup.description == null ? - "" : - "\n " + _paragraphWrap(argGroup.description.trim(), 80-4).join("\n ") + "\n" - def arguments = argGroup.arguments.collect{arg -> - arg instanceof String ? fun.allArguments.find{it.plainName == arg} : arg - }.findAll{it != null} - def argumentStrs = arguments.collect{param -> _generateArgumentHelp(param)} - - "\n\n$name:" + - descriptionStr + - argumentStrs.join("\n") - } - - // FINAL: combine - def out = nameStr + - descrStr + - usageStr + - argGroupStrs.join("") - - return out -} - -// based on Format._paragraphWrap -def _paragraphWrap(str, maxLength) { - def outLines = [] - str.split("\n").each{par -> - def words = par.split("\\s").toList() - - def word = null - def line = words.pop() - while(!words.isEmpty()) { - word = words.pop() - if (line.length() + word.length() + 1 <= maxLength) { - line = line + " " + word - } else { - outLines.add(line) - line = word - } - } - if (words.isEmpty()) { - outLines.add(line) - } - } - return outLines -} - -def helpMessage(config) { - if (params.containsKey("help") && params.help) { - def mergedConfig = addGlobalArguments(config) - def helpStr = _generateHelp(mergedConfig) - println(helpStr) - exit 0 - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/processConfig.nf' -def processConfig(config) { - // set defaults for arguments - config.arguments = - (config.arguments ?: []).collect{_processArgument(it)} - - // set defaults for argument_group arguments - config.argument_groups = - (config.argument_groups ?: []).collect{grp -> - grp.arguments = (grp.arguments ?: []).collect{_processArgument(it)} - grp - } - - // create combined arguments list - config.allArguments = - config.arguments + - config.argument_groups.collectMany{it.arguments} - - // add missing argument groups (based on Functionality::allArgumentGroups()) - def argGroups = config.argument_groups - if (argGroups.any{it.name.toLowerCase() == "arguments"}) { - argGroups = argGroups.collect{ grp -> - if (grp.name.toLowerCase() == "arguments") { - grp = grp + [ - arguments: grp.arguments + config.arguments - ] - } - grp - } - } else { - argGroups = argGroups + [ - name: "Arguments", - arguments: config.arguments - ] - } - config.allArgumentGroups = argGroups - - config -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/readConfig.nf' - -def readConfig(file) { - def config = readYaml(file ?: moduleDir.resolve("config.vsh.yaml")) - processConfig(config) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_resolveSiblingIfNotAbsolute.nf' -/** - * Resolve a path relative to the current file. - * - * @param str The path to resolve, as a String. - * @param parentPath The path to resolve relative to, as a Path. - * - * @return The path that may have been resovled, as a Path. - */ -def _resolveSiblingIfNotAbsolute(str, parentPath) { - if (str !instanceof String) { - return str - } - if (!_stringIsAbsolutePath(str)) { - return parentPath.resolveSibling(str) - } else { - return file(str, hidden: true) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_stringIsAbsolutePath.nf' -/** - * Check whether a path as a string is absolute. - * - * In the past, we tried using `file(., relative: true).isAbsolute()`, - * but the 'relative' option was added in 22.10.0. - * - * @param path The path to check, as a String. - * - * @return Whether the path is absolute, as a boolean. - */ -def _stringIsAbsolutePath(path) { - def _resolve_URL_PROTOCOL = ~/^([a-zA-Z][a-zA-Z0-9]*:)?\\/.+/ - - assert path instanceof String - return _resolve_URL_PROTOCOL.matcher(path).matches() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/collectTraces.nf' -class CustomTraceObserver implements nextflow.trace.TraceObserver { - List traces - - CustomTraceObserver(List traces) { - this.traces = traces - } - - @Override - void onProcessComplete(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } - - @Override - void onProcessCached(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } -} - -def collectTraces() { - def traces = Collections.synchronizedList([]) - - // add custom trace observer which stores traces in the traces object - session.observers.add(new CustomTraceObserver(traces)) - - traces -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/deepClone.nf' -/** - * Performs a deep clone of the given object. - * @param x an object - */ -def deepClone(x) { - iterateMap(x, {it instanceof Cloneable ? it.clone() : it}) -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getPublishDir.nf' -def getPublishDir() { - return params.containsKey("publish_dir") ? params.publish_dir : - params.containsKey("publishDir") ? params.publishDir : - null -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getRootDir.nf' - -// Recurse upwards until we find a '.build.yaml' file -def _findBuildYamlFile(pathPossiblySymlink) { - def path = pathPossiblySymlink.toRealPath() - def child = path.resolve(".build.yaml") - if (java.nio.file.Files.isDirectory(path) && java.nio.file.Files.exists(child)) { - return child - } else { - def parent = path.getParent() - if (parent == null) { - return null - } else { - return _findBuildYamlFile(parent) - } - } -} - -// get the root of the target folder -def getRootDir() { - def dir = _findBuildYamlFile(meta.resources_dir) - assert dir != null: "Could not find .build.yaml in the folder structure" - dir.getParent() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/iterateMap.nf' -/** - * Recursively apply a function over the leaves of an object. - * @param obj The object to iterate over. - * @param fun The function to apply to each value. - * @return The object with the function applied to each value. - */ -def iterateMap(obj, fun) { - if (obj instanceof List && obj !instanceof String) { - return obj.collect{item -> - iterateMap(item, fun) - } - } else if (obj instanceof Map) { - return obj.collectEntries{key, item -> - [key.toString(), iterateMap(item, fun)] - } - } else { - return fun(obj) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/niceView.nf' -/** - * A view for printing the event of each channel as a YAML blob. - * This is useful for debugging. - */ -def niceView() { - workflow niceViewWf { - take: input - main: - output = input - | view{toYamlBlob(it)} - emit: output - } - return niceViewWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readCsv.nf' - -def readCsv(file_path) { - def output = [] - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - - // todo: allow escaped quotes in string - // todo: allow single quotes? - def splitRegex = java.util.regex.Pattern.compile(''',(?=(?:[^"]*"[^"]*")*[^"]*$)''') - def removeQuote = java.util.regex.Pattern.compile('''"(.*)"''') - - def br = java.nio.file.Files.newBufferedReader(inputFile) - - def row = -1 - def header = null - while (br.ready() && header == null) { - def line = br.readLine() - row++ - if (!line.startsWith("#")) { - header = splitRegex.split(line, -1).collect{field -> - m = removeQuote.matcher(field) - m.find() ? m.replaceFirst('$1') : field - } - } - } - assert header != null: "CSV file should contain a header" - - while (br.ready()) { - def line = br.readLine() - row++ - if (line == null) { - br.close() - break - } - - if (!line.startsWith("#")) { - def predata = splitRegex.split(line, -1) - def data = predata.collect{field -> - if (field == "") { - return null - } - def m = removeQuote.matcher(field) - if (m.find()) { - return m.replaceFirst('$1') - } else { - return field - } - } - assert header.size() == data.size(): "Row $row should contain the same number as fields as the header" - - def dataMap = [header, data].transpose().collectEntries().findAll{it.value != null} - output.add(dataMap) - } - } - - output -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJson.nf' -def readJson(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parse(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJsonBlob.nf' -def readJsonBlob(str) { - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parseText(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readTaggedYaml.nf' -// Custom constructor to modify how certain objects are parsed from YAML -class CustomConstructor extends org.yaml.snakeyaml.constructor.Constructor { - Path root - - class ConstructPath extends org.yaml.snakeyaml.constructor.AbstractConstruct { - public Object construct(org.yaml.snakeyaml.nodes.Node node) { - String filename = (String) constructScalar(node); - if (root != null) { - return root.resolve(filename); - } - return java.nio.file.Paths.get(filename); - } - } - - CustomConstructor(org.yaml.snakeyaml.LoaderOptions options, Path root) { - super(options) - this.root = root - // Handling !file tag and parse it back to a File type - this.yamlConstructors.put(new org.yaml.snakeyaml.nodes.Tag("!file"), new ConstructPath()) - } -} - -def readTaggedYaml(Path path) { - def options = new org.yaml.snakeyaml.LoaderOptions() - def constructor = new CustomConstructor(options, path.getParent()) - def yaml = new org.yaml.snakeyaml.Yaml(constructor) - return yaml.load(path.text) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYaml.nf' -def readYaml(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYamlBlob.nf' -def readYamlBlob(str) { - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toJsonBlob.nf' -String toJsonBlob(data) { - return groovy.json.JsonOutput.toJson(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toTaggedYamlBlob.nf' -// Custom representer to modify how certain objects are represented in YAML -class CustomRepresenter extends org.yaml.snakeyaml.representer.Representer { - Path relativizer - - class RepresentPath implements org.yaml.snakeyaml.representer.Represent { - public String getFileName(Object obj) { - if (obj instanceof File) { - obj = ((File) obj).toPath(); - } - if (obj !instanceof Path) { - throw new IllegalArgumentException("Object: " + obj + " is not a Path or File"); - } - def path = (Path) obj; - - if (relativizer != null) { - return relativizer.relativize(path).toString() - } else { - return path.toString() - } - } - - public org.yaml.snakeyaml.nodes.Node representData(Object data) { - String filename = getFileName(data); - def tag = new org.yaml.snakeyaml.nodes.Tag("!file"); - return representScalar(tag, filename); - } - } - CustomRepresenter(org.yaml.snakeyaml.DumperOptions options, Path relativizer) { - super(options) - this.relativizer = relativizer - this.representers.put(sun.nio.fs.UnixPath, new RepresentPath()) - this.representers.put(Path, new RepresentPath()) - this.representers.put(File, new RepresentPath()) - } -} - -String toTaggedYamlBlob(data) { - return toRelativeTaggedYamlBlob(data, null) -} -String toRelativeTaggedYamlBlob(data, Path relativizer) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - def representer = new CustomRepresenter(options, relativizer) - def yaml = new org.yaml.snakeyaml.Yaml(representer, options) - return yaml.dump(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toYamlBlob.nf' -String toYamlBlob(data) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - options.setPrettyFlow(true) - def yaml = new org.yaml.snakeyaml.Yaml(options) - def cleanData = iterateMap(data, { it instanceof Path ? it.toString() : it }) - return yaml.dump(cleanData) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeJson.nf' -void writeJson(data, file) { - assert data: "writeJson: data should not be null" - assert file: "writeJson: file should not be null" - file.write(toJsonBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeYaml.nf' -void writeYaml(data, file) { - assert data: "writeYaml: data should not be null" - assert file: "writeYaml: file should not be null" - file.write(toYamlBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/findStates.nf' -def findStates(Map params, Map config) { - def auto_config = deepClone(config) - def auto_params = deepClone(params) - - auto_config = auto_config.clone() - // override arguments - auto_config.argument_groups = [] - auto_config.arguments = [ - [ - type: "string", - name: "--id", - description: "A dummy identifier", - required: false - ], - [ - type: "file", - name: "--input_states", - example: "/path/to/input/directory/**/state.yaml", - description: "Path to input directory containing the datasets to be integrated.", - required: true, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--filter", - example: "foo/.*/state.yaml", - description: "Regex to filter state files by path.", - required: false - ], - // to do: make this a yaml blob? - [ - type: "string", - name: "--rename_keys", - example: ["newKey1:oldKey1", "newKey2:oldKey2"], - description: "Rename keys in the detected input files. This is useful if the input files do not match the set of input arguments of the workflow.", - required: false, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--settings", - example: '{"output_dataset": "dataset.h5ad", "k": 10}', - description: "Global arguments as a JSON glob to be passed to all components.", - required: false - ] - ] - if (!(auto_params.containsKey("id"))) { - auto_params["id"] = "auto" - } - - // run auto config through processConfig once more - auto_config = processConfig(auto_config) - - workflow findStatesWf { - helpMessage(auto_config) - - output_ch = - channelFromParams(auto_params, auto_config) - | flatMap { autoId, args -> - - def globalSettings = args.settings ? readYamlBlob(args.settings) : [:] - - // look for state files in input dir - def stateFiles = args.input_states - - // filter state files by regex - if (args.filter) { - stateFiles = stateFiles.findAll{ stateFile -> - def stateFileStr = stateFile.toString() - def matcher = stateFileStr =~ args.filter - matcher.matches()} - } - - // read in states - def states = stateFiles.collect { stateFile -> - def state_ = readTaggedYaml(stateFile) - [state_.id, state_] - } - - // construct renameMap - if (args.rename_keys) { - def renameMap = args.rename_keys.collectEntries{renameString -> - def split = renameString.split(";") - assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey,newKey:oldKey'" - split - } - - // rename keys in state, only let states through which have all keys - // also add global settings - states = states.collectMany{id, state -> - def newState = [:] - - for (key in renameMap.keySet()) { - def origKey = renameMap[key] - if (!(state.containsKey(origKey))) { - return [] - } - newState[key] = state[origKey] - } - - [[id, globalSettings + newState]] - } - } - - states - } - emit: - output_ch - } - - return findStatesWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/joinStates.nf' -def joinStates(Closure apply_) { - workflow joinStatesWf { - take: input_ch - main: - output_ch = input_ch - | toSortedList - | filter{ it.size() > 0 } - | map{ tups -> - def ids = tups.collect{it[0]} - def states = tups.collect{it[1]} - apply_(ids, states) - } - - emit: output_ch - } - return joinStatesWf -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/publishStates.nf' -def collectFiles(obj) { - if (obj instanceof java.io.File || obj instanceof Path) { - return [obj] - } else if (obj instanceof List && obj !instanceof String) { - return obj.collectMany{item -> - collectFiles(item) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectFiles(item) - } - } else { - return [] - } -} - -/** - * Recurse through a state and collect all input files and their target output filenames. - * @param obj The state to recurse through. - * @param prefix The prefix to prepend to the output filenames. - */ -def collectInputOutputPaths(obj, prefix) { - if (obj instanceof File || obj instanceof Path) { - def path = obj instanceof Path ? obj : obj.toPath() - def ext = path.getFileName().toString().find("\\.[^\\.]+\$") ?: "" - def newFilename = prefix + ext - return [[obj, newFilename]] - } else if (obj instanceof List && obj !instanceof String) { - return obj.withIndex().collectMany{item, ix -> - collectInputOutputPaths(item, prefix + "_" + ix) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectInputOutputPaths(item, prefix + "." + key) - } - } else { - return [] - } -} - -def publishStates(Map args) { - def key_ = args.get("key") - def yamlTemplate_ = args.get("output_state", args.get("outputState", '$id.$key.state.yaml')) - - assert key_ != null : "publishStates: key must be specified" - - workflow publishStatesWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] - - // the input files and the target output filenames - def inputoutputFilenames_ = collectInputOutputPaths(state_, id_ + "." + key_).transpose() - def inputFiles_ = inputoutputFilenames_[0] - def outputFilenames_ = inputoutputFilenames_[1] - - def yamlFilename = yamlTemplate_ - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - - // TODO: do the pathnames in state_ match up with the outputFilenames_? - - // convert state to yaml blob - def yamlBlob_ = toRelativeTaggedYamlBlob([id: id_] + state_, java.nio.file.Paths.get(yamlFilename)) - - [id_, yamlBlob_, yamlFilename, inputFiles_, outputFilenames_] - } - | publishStatesProc - emit: input_ch - } - return publishStatesWf -} -process publishStatesProc { - // todo: check publishpath? - publishDir path: "${getPublishDir()}/", mode: "copy" - tag "$id" - input: - tuple val(id), val(yamlBlob), val(yamlFile), path(inputFiles, stageAs: "_inputfile?/*"), val(outputFiles) - output: - tuple val(id), path{[yamlFile] + outputFiles} - script: - def copyCommands = [ - inputFiles instanceof List ? inputFiles : [inputFiles], - outputFiles instanceof List ? outputFiles : [outputFiles] - ] - .transpose() - .collectMany{infile, outfile -> - if (infile.toString() != outfile.toString()) { - [ - "[ -d \"\$(dirname '${outfile.toString()}')\" ] || mkdir -p \"\$(dirname '${outfile.toString()}')\"", - "cp -r '${infile.toString()}' '${outfile.toString()}'" - ] - } else { - // no need to copy if infile is the same as outfile - [] - } - } - """ -mkdir -p "\$(dirname '${yamlFile}')" -echo "Storing state as yaml" -echo '${yamlBlob}' > '${yamlFile}' -echo "Copying output files to destination folder" -${copyCommands.join("\n ")} -""" -} - - -// this assumes that the state contains no other values other than those specified in the config -def publishStatesByConfig(Map args) { - def config = args.get("config") - assert config != null : "publishStatesByConfig: config must be specified" - - def key_ = args.get("key", config.name) - assert key_ != null : "publishStatesByConfig: key must be specified" - - workflow publishStatesSimpleWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] // e.g. [output: new File("myoutput.h5ad"), k: 10] - def origState_ = tup[2] // e.g. [output: '$id.$key.foo.h5ad'] - - // TODO: allow overriding the state.yaml template - // TODO TODO: if auto.publish == "state", add output_state as an argument - def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' - def yamlFilename = yamlTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() - - // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where - // - key is a String - // - value is any object that can be serialized to a Yaml (so a String/Integer/Long/Double/Boolean, a List, a Map, or a Path) - // - inputPath is a List[Path] - // - outputFilename is a List[String] - // - (key, value) are the tuples that will be saved to the state.yaml file - // - (inputPath, outputFilename) are the files that will be copied from src to dest (relative to the state.yaml) - def processedState = - config.allArguments - .findAll { it.direction == "output" } - .collectMany { par -> - def plainName_ = par.plainName - // if the state does not contain the key, it's an - // optional argument for which the component did - // not generate any output - if (!state_.containsKey(plainName_)) { - return [] - } - def value = state_[plainName_] - // if the parameter is not a file, it should be stored - // in the state as-is, but is not something that needs - // to be copied from the source path to the dest path - if (par.type != "file") { - return [[key: plainName_, value: value, inputPath: [], outputFilename: []]] - } - // if the orig state does not contain this filename, - // it's an optional argument for which the user specified - // that it should not be returned as a state - if (!origState_.containsKey(plainName_)) { - return [] - } - def filenameTemplate = origState_[plainName_] - // if the pararameter is multiple: true, fetch the template - if (par.multiple && filenameTemplate instanceof List) { - filenameTemplate = filenameTemplate[0] - } - // instantiate the template - def filename = filenameTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - if (par.multiple) { - // if the parameter is multiple: true, the filename - // should contain a wildcard '*' that is replaced with - // the index of the file - assert filename.contains("*") : "Module '${key_}' id '${id_}': Multiple output files specified, but no wildcard '*' in the filename: ${filename}" - def outputPerFile = value.withIndex().collect{ val, ix -> - def filename_ix = filename.replace("*", ix.toString()) - def value_ = java.nio.file.Paths.get(filename_ix) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = val instanceof File ? val.toPath() : val - [value: value_, inputPath: inputPath, outputFilename: filename_ix] - } - def transposedOutputs = ["value", "inputPath", "outputFilename"].collectEntries{ key -> - [key, outputPerFile.collect{dic -> dic[key]}] - } - return [[key: plainName_] + transposedOutputs] - } else { - def value_ = java.nio.file.Paths.get(filename) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = value instanceof File ? value.toPath() : value - return [[key: plainName_, value: value_, inputPath: [inputPath], outputFilename: [filename]]] - } - } - - def updatedState_ = processedState.collectEntries{[it.key, it.value]} - def inputPaths = processedState.collectMany{it.inputPath} - def outputFilenames = processedState.collectMany{it.outputFilename} - - // convert state to yaml blob - def yamlBlob_ = toTaggedYamlBlob([id: id_] + updatedState_) - - [id_, yamlBlob_, yamlFilename, inputPaths, outputFilenames] - } - | publishStatesProc - emit: input_ch - } - return publishStatesSimpleWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/setState.nf' -def setState(fun) { - assert fun instanceof Closure || fun instanceof Map || fun instanceof List : - "Error in setState: Expected process argument to be a Closure, a Map, or a List. Found: class ${fun.getClass()}" - - // if fun is a List, convert to map - if (fun instanceof List) { - // check whether fun is a list[string] - assert fun.every{it instanceof CharSequence} : "Error in setState: argument is a List, but not all elements are Strings" - fun = fun.collectEntries{[it, it]} - } - - // if fun is a map, convert to closure - if (fun instanceof Map) { - // check whether fun is a map[string, string] - assert fun.values().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all values are Strings" - assert fun.keySet().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all keys are Strings" - def funMap = fun.clone() - // turn the map into a closure to be used later on - fun = { id_, state_ -> - assert state_ instanceof Map : "Error in setState: the state is not a Map" - funMap.collectMany{newkey, origkey -> - if (state_.containsKey(origkey)) { - [[newkey, state_[origkey]]] - } else { - [] - } - }.collectEntries() - } - } - - map { tup -> - def id = tup[0] - def state = tup[1] - def unfilteredState = fun(id, state) - def newState = unfilteredState.findAll{key, val -> val != null} - [id, newState] + tup.drop(2) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processAuto.nf' -// TODO: unit test processAuto -def processAuto(Map auto) { - // remove null values - auto = auto.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = ["simplifyInput", "simplifyOutput", "transcript", "publish"] - def unexpectedKeys = auto.keySet() - expectedKeys - assert unexpectedKeys.isEmpty(), "unexpected keys in auto: '${unexpectedKeys.join("', '")}'" - - // check auto.simplifyInput - assert auto.simplifyInput instanceof Boolean, "auto.simplifyInput must be a boolean" - - // check auto.simplifyOutput - assert auto.simplifyOutput instanceof Boolean, "auto.simplifyOutput must be a boolean" - - // check auto.transcript - assert auto.transcript instanceof Boolean, "auto.transcript must be a boolean" - - // check auto.publish - assert auto.publish instanceof Boolean || auto.publish == "state", "auto.publish must be a boolean or 'state'" - - return auto.subMap(expectedKeys) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processDirectives.nf' -def assertMapKeys(map, expectedKeys, requiredKeys, mapName) { - assert map instanceof Map : "Expected argument '$mapName' to be a Map. Found: class ${map.getClass()}" - map.forEach { key, val -> - assert key in expectedKeys : "Unexpected key '$key' in ${mapName ? mapName + " " : ""}map" - } - requiredKeys.forEach { requiredKey -> - assert map.containsKey(requiredKey) : "Missing required key '$key' in ${mapName ? mapName + " " : ""}map" - } -} - -// TODO: unit test processDirectives -def processDirectives(Map drctv) { - // remove null values - drctv = drctv.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = [ - "accelerator", "afterScript", "beforeScript", "cache", "conda", "container", "containerOptions", "cpus", "disk", "echo", "errorStrategy", "executor", "machineType", "maxErrors", "maxForks", "maxRetries", "memory", "module", "penv", "pod", "publishDir", "queue", "label", "scratch", "storeDir", "stageInMode", "stageOutMode", "tag", "time" - ] - def unexpectedKeys = drctv.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Unexpected keys in process directive: '${unexpectedKeys.join("', '")}'" - - /* DIRECTIVE accelerator - accepted examples: - - [ limit: 4, type: "nvidia-tesla-k80" ] - */ - if (drctv.containsKey("accelerator")) { - assertMapKeys(drctv["accelerator"], ["type", "limit", "request", "runtime"], [], "accelerator") - } - - /* DIRECTIVE afterScript - accepted examples: - - "source /cluster/bin/cleanup" - */ - if (drctv.containsKey("afterScript")) { - assert drctv["afterScript"] instanceof CharSequence - } - - /* DIRECTIVE beforeScript - accepted examples: - - "source /cluster/bin/setup" - */ - if (drctv.containsKey("beforeScript")) { - assert drctv["beforeScript"] instanceof CharSequence - } - - /* DIRECTIVE cache - accepted examples: - - true - - false - - "deep" - - "lenient" - */ - if (drctv.containsKey("cache")) { - assert drctv["cache"] instanceof CharSequence || drctv["cache"] instanceof Boolean - if (drctv["cache"] instanceof CharSequence) { - assert drctv["cache"] in ["deep", "lenient"] : "Unexpected value for cache" - } - } - - /* DIRECTIVE conda - accepted examples: - - "bwa=0.7.15" - - "bwa=0.7.15 fastqc=0.11.5" - - ["bwa=0.7.15", "fastqc=0.11.5"] - */ - if (drctv.containsKey("conda")) { - if (drctv["conda"] instanceof List) { - drctv["conda"] = drctv["conda"].join(" ") - } - assert drctv["conda"] instanceof CharSequence - } - - /* DIRECTIVE container - accepted examples: - - "foo/bar:tag" - - [ registry: "reg", image: "im", tag: "ta" ] - is transformed to "reg/im:ta" - - [ image: "im" ] - is transformed to "im:latest" - */ - if (drctv.containsKey("container")) { - assert drctv["container"] instanceof Map || drctv["container"] instanceof CharSequence - if (drctv["container"] instanceof Map) { - def m = drctv["container"] - assertMapKeys(m, [ "registry", "image", "tag" ], ["image"], "container") - def part1 = - System.getenv('OVERRIDE_CONTAINER_REGISTRY') ? System.getenv('OVERRIDE_CONTAINER_REGISTRY') + "/" : - params.containsKey("override_container_registry") ? params["override_container_registry"] + "/" : // todo: remove? - m.registry ? m.registry + "/" : - "" - def part2 = m.image - def part3 = m.tag ? ":" + m.tag : ":latest" - drctv["container"] = part1 + part2 + part3 - } - } - - /* DIRECTIVE containerOptions - accepted examples: - - "--foo bar" - - ["--foo bar", "-f b"] - */ - if (drctv.containsKey("containerOptions")) { - if (drctv["containerOptions"] instanceof List) { - drctv["containerOptions"] = drctv["containerOptions"].join(" ") - } - assert drctv["containerOptions"] instanceof CharSequence - } - - /* DIRECTIVE cpus - accepted examples: - - 1 - - 10 - */ - if (drctv.containsKey("cpus")) { - assert drctv["cpus"] instanceof Integer - } - - /* DIRECTIVE disk - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("disk")) { - assert drctv["disk"] instanceof CharSequence - // assert drctv["disk"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE echo - accepted examples: - - true - - false - */ - if (drctv.containsKey("echo")) { - assert drctv["echo"] instanceof Boolean - } - - /* DIRECTIVE errorStrategy - accepted examples: - - "terminate" - - "finish" - */ - if (drctv.containsKey("errorStrategy")) { - assert drctv["errorStrategy"] instanceof CharSequence - assert drctv["errorStrategy"] in ["terminate", "finish", "ignore", "retry"] : "Unexpected value for errorStrategy" - } - - /* DIRECTIVE executor - accepted examples: - - "local" - - "sge" - */ - if (drctv.containsKey("executor")) { - assert drctv["executor"] instanceof CharSequence - assert drctv["executor"] in ["local", "sge", "uge", "lsf", "slurm", "pbs", "pbspro", "moab", "condor", "nqsii", "ignite", "k8s", "awsbatch", "google-pipelines"] : "Unexpected value for executor" - } - - /* DIRECTIVE machineType - accepted examples: - - "n1-highmem-8" - */ - if (drctv.containsKey("machineType")) { - assert drctv["machineType"] instanceof CharSequence - } - - /* DIRECTIVE maxErrors - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxErrors")) { - assert drctv["maxErrors"] instanceof Integer - } - - /* DIRECTIVE maxForks - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxForks")) { - assert drctv["maxForks"] instanceof Integer - } - - /* DIRECTIVE maxRetries - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxRetries")) { - assert drctv["maxRetries"] instanceof Integer - } - - /* DIRECTIVE memory - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("memory")) { - assert drctv["memory"] instanceof CharSequence - // assert drctv["memory"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE module - accepted examples: - - "ncbi-blast/2.2.27" - - "ncbi-blast/2.2.27:t_coffee/10.0" - - ["ncbi-blast/2.2.27", "t_coffee/10.0"] - */ - if (drctv.containsKey("module")) { - if (drctv["module"] instanceof List) { - drctv["module"] = drctv["module"].join(":") - } - assert drctv["module"] instanceof CharSequence - } - - /* DIRECTIVE penv - accepted examples: - - "smp" - */ - if (drctv.containsKey("penv")) { - assert drctv["penv"] instanceof CharSequence - } - - /* DIRECTIVE pod - accepted examples: - - [ label: "key", value: "val" ] - - [ annotation: "key", value: "val" ] - - [ env: "key", value: "val" ] - - [ [label: "l", value: "v"], [env: "e", value: "v"]] - */ - if (drctv.containsKey("pod")) { - if (drctv["pod"] instanceof Map) { - drctv["pod"] = [ drctv["pod"] ] - } - assert drctv["pod"] instanceof List - drctv["pod"].forEach { pod -> - assert pod instanceof Map - // TODO: should more checks be added? - // See https://www.nextflow.io/docs/latest/process.html?highlight=directives#pod - // e.g. does it contain 'label' and 'value', or 'annotation' and 'value', or ...? - } - } - - /* DIRECTIVE publishDir - accepted examples: - - [] - - [ [ path: "foo", enabled: true ], [ path: "bar", enabled: false ] ] - - "/path/to/dir" - is transformed to [[ path: "/path/to/dir" ]] - - [ path: "/path/to/dir", mode: "cache" ] - is transformed to [[ path: "/path/to/dir", mode: "cache" ]] - */ - // TODO: should we also look at params["publishDir"]? - if (drctv.containsKey("publishDir")) { - def pblsh = drctv["publishDir"] - - // check different options - assert pblsh instanceof List || pblsh instanceof Map || pblsh instanceof CharSequence - - // turn into list if not already so - // for some reason, 'if (!pblsh instanceof List) pblsh = [ pblsh ]' doesn't work. - pblsh = pblsh instanceof List ? pblsh : [ pblsh ] - - // check elements of publishDir - pblsh = pblsh.collect{ elem -> - // turn into map if not already so - elem = elem instanceof CharSequence ? [ path: elem ] : elem - - // check types and keys - assert elem instanceof Map : "Expected publish argument '$elem' to be a String or a Map. Found: class ${elem.getClass()}" - assertMapKeys(elem, [ "path", "mode", "overwrite", "pattern", "saveAs", "enabled" ], ["path"], "publishDir") - - // check elements in map - assert elem.containsKey("path") - assert elem["path"] instanceof CharSequence - if (elem.containsKey("mode")) { - assert elem["mode"] instanceof CharSequence - assert elem["mode"] in [ "symlink", "rellink", "link", "copy", "copyNoFollow", "move" ] - } - if (elem.containsKey("overwrite")) { - assert elem["overwrite"] instanceof Boolean - } - if (elem.containsKey("pattern")) { - assert elem["pattern"] instanceof CharSequence - } - if (elem.containsKey("saveAs")) { - assert elem["saveAs"] instanceof CharSequence //: "saveAs as a Closure is currently not supported. Surround your closure with single quotes to get the desired effect. Example: '\{ foo \}'" - } - if (elem.containsKey("enabled")) { - assert elem["enabled"] instanceof Boolean - } - - // return final result - elem - } - // store final directive - drctv["publishDir"] = pblsh - } - - /* DIRECTIVE queue - accepted examples: - - "long" - - "short,long" - - ["short", "long"] - */ - if (drctv.containsKey("queue")) { - if (drctv["queue"] instanceof List) { - drctv["queue"] = drctv["queue"].join(",") - } - assert drctv["queue"] instanceof CharSequence - } - - /* DIRECTIVE label - accepted examples: - - "big_mem" - - "big_cpu" - - ["big_mem", "big_cpu"] - */ - if (drctv.containsKey("label")) { - if (drctv["label"] instanceof CharSequence) { - drctv["label"] = [ drctv["label"] ] - } - assert drctv["label"] instanceof List - drctv["label"].forEach { label -> - assert label instanceof CharSequence - // assert label.matches("[a-zA-Z0-9]([a-zA-Z0-9_]*[a-zA-Z0-9])?") - // ^ does not allow closures - } - } - - /* DIRECTIVE scratch - accepted examples: - - true - - "/path/to/scratch" - - '$MY_PATH_TO_SCRATCH' - - "ram-disk" - */ - if (drctv.containsKey("scratch")) { - assert drctv["scratch"] == true || drctv["scratch"] instanceof CharSequence - } - - /* DIRECTIVE storeDir - accepted examples: - - "/path/to/storeDir" - */ - if (drctv.containsKey("storeDir")) { - assert drctv["storeDir"] instanceof CharSequence - } - - /* DIRECTIVE stageInMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageInMode")) { - assert drctv["stageInMode"] instanceof CharSequence - assert drctv["stageInMode"] in ["copy", "link", "symlink", "rellink"] - } - - /* DIRECTIVE stageOutMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageOutMode")) { - assert drctv["stageOutMode"] instanceof CharSequence - assert drctv["stageOutMode"] in ["copy", "move", "rsync"] - } - - /* DIRECTIVE tag - accepted examples: - - "foo" - - '$id' - */ - if (drctv.containsKey("tag")) { - assert drctv["tag"] instanceof CharSequence - } - - /* DIRECTIVE time - accepted examples: - - "1h" - - "2days" - - "1day 6hours 3minutes 30seconds" - */ - if (drctv.containsKey("time")) { - assert drctv["time"] instanceof CharSequence - // todo: validation regex? - } - - return drctv -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf' -def processWorkflowArgs(Map args, Map defaultWfArgs, Map meta) { - // override defaults with args - def workflowArgs = defaultWfArgs + args - - // check whether 'key' exists - assert workflowArgs.containsKey("key") : "Error in module '${meta.config.name}': key is a required argument" - - // if 'key' is a closure, apply it to the original key - if (workflowArgs["key"] instanceof Closure) { - workflowArgs["key"] = workflowArgs["key"](meta.config.name) - } - def key = workflowArgs["key"] - assert key instanceof CharSequence : "Expected process argument 'key' to be a String. Found: class ${key.getClass()}" - assert key ==~ /^[a-zA-Z_]\w*$/ : "Error in module '$key': Expected process argument 'key' to consist of only letters, digits or underscores. Found: ${key}" - - // check for any unexpected keys - def expectedKeys = ["key", "directives", "auto", "map", "mapId", "mapData", "mapPassthrough", "filter", "runIf", "fromState", "toState", "args", "renameKeys", "debug"] - def unexpectedKeys = workflowArgs.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Error in module '$key': unexpected arguments to the '.run()' function: '${unexpectedKeys.join("', '")}'" - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("directives") : "Error in module '$key': directives is a required argument" - assert workflowArgs["directives"] instanceof Map : "Error in module '$key': Expected process argument 'directives' to be a Map. Found: class ${workflowArgs['directives'].getClass()}" - workflowArgs["directives"] = processDirectives(defaultWfArgs.directives + workflowArgs["directives"]) - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("auto") : "Error in module '$key': auto is a required argument" - assert workflowArgs["auto"] instanceof Map : "Error in module '$key': Expected process argument 'auto' to be a Map. Found: class ${workflowArgs['auto'].getClass()}" - workflowArgs["auto"] = processAuto(defaultWfArgs.auto + workflowArgs["auto"]) - - // auto define publish, if so desired - if (workflowArgs.auto.publish == true && (workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : [:]).isEmpty()) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.publish is true, params.publish_dir needs to be defined.\n" + - // " Example: params.publish_dir = \"./output/\"" - def publishDir = getPublishDir() - - if (publishDir != null) { - workflowArgs.directives.publishDir = [[ - path: publishDir, - saveAs: "{ it.startsWith('.') ? null : it }", // don't publish hidden files, by default - mode: "copy" - ]] - } - } - - // auto define transcript, if so desired - if (workflowArgs.auto.transcript == true) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("transcriptsDir") || params.containsKey("transcripts_dir") || params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.transcript is true, either params.transcripts_dir or params.publish_dir needs to be defined.\n" + - // " Example: params.transcripts_dir = \"./transcripts/\"" - def transcriptsDir = - params.containsKey("transcripts_dir") ? params.transcripts_dir : - params.containsKey("transcriptsDir") ? params.transcriptsDir : - params.containsKey("publish_dir") ? params.publish_dir + "/_transcripts" : - params.containsKey("publishDir") ? params.publishDir + "/_transcripts" : - null - if (transcriptsDir != null) { - def timestamp = nextflow.Nextflow.getSession().getWorkflowMetadata().start.format('yyyy-MM-dd_HH-mm-ss') - def transcriptsPublishDir = [ - path: "$transcriptsDir/$timestamp/\${task.process.replaceAll(':', '-')}/\${id}/", - saveAs: "{ it.startsWith('.') ? it.replaceAll('^.', '') : null }", - mode: "copy" - ] - def publishDirs = workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : null ? workflowArgs.directives.publishDir : [] - workflowArgs.directives.publishDir = publishDirs + transcriptsPublishDir - } - } - - // if this is a stubrun, remove certain directives? - if (workflow.stubRun) { - workflowArgs.directives.keySet().removeAll(["publishDir", "cpus", "memory", "label"]) - } - - for (nam in ["map", "mapId", "mapData", "mapPassthrough", "filter", "runIf"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam]) { - assert workflowArgs[nam] instanceof Closure : "Error in module '$key': Expected process argument '$nam' to be null or a Closure. Found: class ${workflowArgs[nam].getClass()}" - } - } - - // TODO: should functions like 'map', 'mapId', 'mapData', 'mapPassthrough' be deprecated as well? - for (nam in ["map", "mapData", "mapPassthrough", "renameKeys"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam] != null) { - log.warn "module '$key': workflow argument '$nam' is deprecated and will be removed in Viash 0.9.0. Please use 'fromState' and 'toState' instead." - } - } - - // check fromState - workflowArgs["fromState"] = _processFromState(workflowArgs.get("fromState"), key, meta.config) - - // check toState - workflowArgs["toState"] = _processToState(workflowArgs.get("toState"), key, meta.config) - - // return output - return workflowArgs -} - -def _processFromState(fromState, key_, config_) { - assert fromState == null || fromState instanceof Closure || fromState instanceof Map || fromState instanceof List : - "Error in module '$key_': Expected process argument 'fromState' to be null, a Closure, a Map, or a List. Found: class ${fromState.getClass()}" - if (fromState == null) { - return null - } - - // if fromState is a List, convert to map - if (fromState instanceof List) { - // check whether fromstate is a list[string] - assert fromState.every{it instanceof CharSequence} : "Error in module '$key_': fromState is a List, but not all elements are Strings" - fromState = fromState.collectEntries{[it, it]} - } - - // if fromState is a map, convert to closure - if (fromState instanceof Map) { - // check whether fromstate is a map[string, string] - assert fromState.values().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all values are Strings" - assert fromState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all keys are Strings" - def fromStateMap = fromState.clone() - def requiredInputNames = meta.config.allArguments.findAll{it.required && it.direction == "Input"}.collect{it.plainName} - // turn the map into a closure to be used later on - fromState = { it -> - def state = it[1] - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def data = fromStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (state.containsKey(origkey)) { - [[newkey, state[origkey]]] - } else if (!requiredInputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': fromState key '$origkey' not found in current state") - } - }.collectEntries() - data - } - } - - return fromState -} - -def _processToState(toState, key_, config_) { - if (toState == null) { - toState = { tup -> tup[1] } - } - - // toState should be a closure, map[string, string], or list[string] - assert toState instanceof Closure || toState instanceof Map || toState instanceof List : - "Error in module '$key_': Expected process argument 'toState' to be a Closure, a Map, or a List. Found: class ${toState.getClass()}" - - // if toState is a List, convert to map - if (toState instanceof List) { - // check whether toState is a list[string] - assert toState.every{it instanceof CharSequence} : "Error in module '$key_': toState is a List, but not all elements are Strings" - toState = toState.collectEntries{[it, it]} - } - - // if toState is a map, convert to closure - if (toState instanceof Map) { - // check whether toState is a map[string, string] - assert toState.values().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all values are Strings" - assert toState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all keys are Strings" - def toStateMap = toState.clone() - def requiredOutputNames = config_.allArguments.findAll{it.required && it.direction == "Output"}.collect{it.plainName} - // turn the map into a closure to be used later on - toState = { it -> - def output = it[1] - def state = it[2] - assert output instanceof Map : "Error in module '$key_': the output is not a Map" - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def extraEntries = toStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (output.containsKey(origkey)) { - [[newkey, output[origkey]]] - } else if (!requiredOutputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': toState key '$origkey' not found in current output") - } - }.collectEntries() - state + extraEntries - } - } - - return toState -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/workflowFactory.nf' -def _debug(workflowArgs, debugKey) { - if (workflowArgs.debug) { - view { "process '${workflowArgs.key}' $debugKey tuple: $it" } - } else { - map { it } - } -} - -// depends on: innerWorkflowFactory -def workflowFactory(Map args, Map defaultWfArgs, Map meta) { - def workflowArgs = processWorkflowArgs(args, defaultWfArgs, meta) - def key_ = workflowArgs["key"] - - workflow workflowInstance { - take: input_ - - main: - def chModified = input_ - | checkUniqueIds([:]) - | _debug(workflowArgs, "input") - | map { tuple -> - tuple = deepClone(tuple) - - if (workflowArgs.map) { - tuple = workflowArgs.map(tuple) - } - if (workflowArgs.mapId) { - tuple[0] = workflowArgs.mapId(tuple[0]) - } - if (workflowArgs.mapData) { - tuple[1] = workflowArgs.mapData(tuple[1]) - } - if (workflowArgs.mapPassthrough) { - tuple = tuple.take(2) + workflowArgs.mapPassthrough(tuple.drop(2)) - } - - // check tuple - assert tuple instanceof List : - "Error in module '${key_}': element in channel should be a tuple [id, data, ...otherargs...]\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: List. Found: tuple.getClass() is ${tuple.getClass()}" - assert tuple.size() >= 2 : - "Error in module '${key_}': expected length of tuple in input channel to be two or greater.\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: tuple.size() == ${tuple.size()}" - - // check id field - if (tuple[0] instanceof GString) { - tuple[0] = tuple[0].toString() - } - assert tuple[0] instanceof CharSequence : - "Error in module '${key_}': first element of tuple in channel should be a String\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: ${tuple[0]}" - - // match file to input file - if (workflowArgs.auto.simplifyInput && (tuple[1] instanceof Path || tuple[1] instanceof List)) { - def inputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - - assert inputFiles.size() == 1 : - "Error in module '${key_}' id '${tuple[0]}'.\n" + - " Anonymous file inputs are only allowed when the process has exactly one file input.\n" + - " Expected: inputFiles.size() == 1. Found: inputFiles.size() is ${inputFiles.size()}" - - tuple[1] = [[ inputFiles[0].plainName, tuple[1] ]].collectEntries() - } - - // check data field - assert tuple[1] instanceof Map : - "Error in module '${key_}' id '${tuple[0]}': second element of tuple in channel should be a Map\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // rename keys of data field in tuple - if (workflowArgs.renameKeys) { - assert workflowArgs.renameKeys instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class: Map. Found: renameKeys.getClass() is ${workflowArgs.renameKeys.getClass()}" - assert tuple[1] instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // TODO: allow renameKeys to be a function? - workflowArgs.renameKeys.each { newKey, oldKey -> - assert newKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of newKey: String. Found: newKey.getClass() is ${newKey.getClass()}" - assert oldKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of oldKey: String. Found: oldKey.getClass() is ${oldKey.getClass()}" - assert tuple[1].containsKey(oldKey) : - "Error renaming data keys in module '${key}' id '${tuple[0]}'.\n" + - " Key '$oldKey' is missing in the data map. tuple[1].keySet() is '${tuple[1].keySet()}'" - tuple[1].put(newKey, tuple[1][oldKey]) - } - tuple[1].keySet().removeAll(workflowArgs.renameKeys.collect{ newKey, oldKey -> oldKey }) - } - tuple - } - - def chModifiedFiltered = workflowArgs.filter ? - chModified | filter{workflowArgs.filter(it)} : - chModified - - def chRun = null - def chPassthrough = null - if (workflowArgs.runIf) { - def runIfBranch = chModifiedFiltered.branch{ tup -> - run: workflowArgs.runIf(tup[0], tup[1]) - passthrough: true - } - chRun = runIfBranch.run - chPassthrough = runIfBranch.passthrough - } else { - chRun = chModifiedFiltered - chPassthrough = Channel.empty() - } - - def chArgs = workflowArgs.fromState ? - chRun | map{ - def new_data = workflowArgs.fromState(it.take(2)) - [it[0], new_data] - } : - chRun | map {tup -> tup.take(2)} - - // fill in defaults - def chArgsWithDefaults = chArgs - | map { tuple -> - def id_ = tuple[0] - def data_ = tuple[1] - - // TODO: could move fromState to here - - // fetch default params from functionality - def defaultArgs = meta.config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - // fetch overrides in params - def paramArgs = meta.config.allArguments - .findAll { par -> - def argKey = key_ + "__" + par.plainName - params.containsKey(argKey) - } - .collectEntries { [ it.plainName, params[key_ + "__" + it.plainName] ] } - - // fetch overrides in data - def dataArgs = meta.config.allArguments - .findAll { data_.containsKey(it.plainName) } - .collectEntries { [ it.plainName, data_[it.plainName] ] } - - // combine params - def combinedArgs = defaultArgs + paramArgs + workflowArgs.args + dataArgs - - // remove arguments with explicit null values - combinedArgs - .removeAll{_, val -> val == null || val == "viash_no_value" || val == "force_null"} - - combinedArgs = _processInputValues(combinedArgs, meta.config, id_, key_) - - [id_, combinedArgs] + tuple.drop(2) - } - - // TODO: move some of the _meta.join_id wrangling to the safeJoin() function. - def chInitialOutput = chArgsWithDefaults - | _debug(workflowArgs, "processed") - // run workflow - | innerWorkflowFactory(workflowArgs) - // check output tuple - | map { id_, output_ -> - - // see if output map contains metadata - def meta_ = - output_ instanceof Map && output_.containsKey("_meta") ? - output_["_meta"] : - [:] - def join_id = meta_.join_id ?: id_ - - // remove metadata - output_ = output_.findAll{k, v -> k != "_meta"} - - // check value types - output_ = _processOutputValues(output_, meta.config, id_, key_) - - // simplify output if need be - if (workflowArgs.auto.simplifyOutput && output_.size() == 1) { - output_ = output_.values()[0] - } - - [join_id, id_, output_] - } - // | view{"chInitialOutput: ${it.take(3)}"} - - // join the output [prev_id, new_id, output] with the previous state [prev_id, state, ...] - def chNewState = safeJoin(chInitialOutput, chModifiedFiltered, key_) - // input tuple format: [join_id, id, output, prev_state, ...] - // output tuple format: [join_id, id, new_state, ...] - | map{ tup -> - def new_state = workflowArgs.toState(tup.drop(1).take(3)) - tup.take(2) + [new_state] + tup.drop(4) - } - - if (workflowArgs.auto.publish == "state") { - def chPublish = chNewState - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [join_id, id, new_state] - | map{ tup -> - tup.take(3) - } - - safeJoin(chPublish, chArgsWithDefaults, key_) - // input tuple format: [join_id, id, new_state, orig_state, ...] - // output tuple format: [id, new_state, orig_state] - | map { tup -> - tup.drop(1).take(3) - } - | publishStatesByConfig(key: key_, config: meta.config) - } - - // remove join_id and meta - chReturn = chNewState - | map { tup -> - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [id, new_state, ...] - tup.drop(1) - } - | _debug(workflowArgs, "output") - | concat(chPassthrough) - - emit: chReturn - } - - def wf = workflowInstance.cloneWithName(key_) - - // add factory function - wf.metaClass.run = { runArgs -> - workflowFactory(runArgs, workflowArgs, meta) - } - // add config to module for later introspection - wf.metaClass.config = meta.config - - return wf -} - -nextflow.enable.dsl=2 - -// START COMPONENT-SPECIFIC CODE - -// create meta object -meta = [ - "resources_dir": moduleDir.toRealPath().normalize(), - "config": processConfig(readJsonBlob('''{ - "name" : "samtools_flagstat", - "namespace" : "samtools", - "version" : "v0.1.0", - "argument_groups" : [ - { - "name" : "Inputs", - "arguments" : [ - { - "type" : "file", - "name" : "--bam", - "description" : "BAM input files.\n", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--bai", - "description" : "BAM index file.\n", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Outputs", - "arguments" : [ - { - "type" : "file", - "name" : "--output", - "description" : "File containing samtools stats output.\n", - "example" : [ - "output.flagstat" - ], - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "output", - "multiple" : false, - "multiple_sep" : ";" - } - ] - } - ], - "resources" : [ - { - "type" : "bash_script", - "path" : "script.sh", - "is_executable" : true - } - ], - "description" : "Counts the number of alignments in SAM/BAM/CRAM files for each FLAG type.", - "test_resources" : [ - { - "type" : "bash_script", - "path" : "test.sh", - "is_executable" : true - }, - { - "type" : "file", - "path" : "test_data" - } - ], - "status" : "enabled", - "requirements" : { - "commands" : [ - "ps" - ] - }, - "keywords" : [ - "stats", - "mapping", - "counts", - "bam", - "sam", - "cram" - ], - "license" : "MIT/Expat", - "references" : { - "doi" : [ - "10.1093/bioinformatics/btp352", - "10.1093/gigascience/giab008" - ] - }, - "links" : { - "repository" : "https://github.com/samtools/samtools", - "homepage" : "https://www.htslib.org/", - "documentation" : "https://www.htslib.org/doc/samtools-flagstat.html" - }, - "runners" : [ - { - "type" : "executable", - "id" : "executable", - "docker_setup_strategy" : "ifneedbepullelsecachedbuild" - }, - { - "type" : "nextflow", - "id" : "nextflow", - "directives" : { - "tag" : "$id" - }, - "auto" : { - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false - }, - "config" : { - "labels" : { - "mem1gb" : "memory = 1000000000.B", - "mem2gb" : "memory = 2000000000.B", - "mem5gb" : "memory = 5000000000.B", - "mem10gb" : "memory = 10000000000.B", - "mem20gb" : "memory = 20000000000.B", - "mem50gb" : "memory = 50000000000.B", - "mem100gb" : "memory = 100000000000.B", - "mem200gb" : "memory = 200000000000.B", - "mem500gb" : "memory = 500000000000.B", - "mem1tb" : "memory = 1000000000000.B", - "mem2tb" : "memory = 2000000000000.B", - "mem5tb" : "memory = 5000000000000.B", - "mem10tb" : "memory = 10000000000000.B", - "mem20tb" : "memory = 20000000000000.B", - "mem50tb" : "memory = 50000000000000.B", - "mem100tb" : "memory = 100000000000000.B", - "mem200tb" : "memory = 200000000000000.B", - "mem500tb" : "memory = 500000000000000.B", - "mem1gib" : "memory = 1073741824.B", - "mem2gib" : "memory = 2147483648.B", - "mem4gib" : "memory = 4294967296.B", - "mem8gib" : "memory = 8589934592.B", - "mem16gib" : "memory = 17179869184.B", - "mem32gib" : "memory = 34359738368.B", - "mem64gib" : "memory = 68719476736.B", - "mem128gib" : "memory = 137438953472.B", - "mem256gib" : "memory = 274877906944.B", - "mem512gib" : "memory = 549755813888.B", - "mem1tib" : "memory = 1099511627776.B", - "mem2tib" : "memory = 2199023255552.B", - "mem4tib" : "memory = 4398046511104.B", - "mem8tib" : "memory = 8796093022208.B", - "mem16tib" : "memory = 17592186044416.B", - "mem32tib" : "memory = 35184372088832.B", - "mem64tib" : "memory = 70368744177664.B", - "mem128tib" : "memory = 140737488355328.B", - "mem256tib" : "memory = 281474976710656.B", - "mem512tib" : "memory = 562949953421312.B", - "cpu1" : "cpus = 1", - "cpu2" : "cpus = 2", - "cpu5" : "cpus = 5", - "cpu10" : "cpus = 10", - "cpu20" : "cpus = 20", - "cpu50" : "cpus = 50", - "cpu100" : "cpus = 100", - "cpu200" : "cpus = 200", - "cpu500" : "cpus = 500", - "cpu1000" : "cpus = 1000" - } - }, - "debug" : false, - "container" : "docker" - } - ], - "engines" : [ - { - "type" : "docker", - "id" : "docker", - "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", - "target_registry" : "images.viash-hub.com", - "target_tag" : "v0.1.0", - "namespace_separator" : "/", - "setup" : [ - { - "type" : "docker", - "run" : [ - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\\\nsed 's#Using ##;s# \\\\([0-9\\\\.]*\\\\)$#: \\\\1#' > /var/software_versions.txt\n" - ] - } - ] - }, - { - "type" : "native", - "id" : "native" - } - ], - "build_info" : { - "config" : "/workdir/root/repo/src/samtools/samtools_flagstat/config.vsh.yaml", - "runner" : "nextflow", - "engine" : "docker|native", - "output" : "target/nextflow/samtools/samtools_flagstat", - "viash_version" : "0.9.0-RC6", - "git_commit" : "b84b29747d0635f2ac83ea63b496be9a9edb6724", - "git_remote" : "https://github.com/viash-hub/biobox" - }, - "package_config" : { - "name" : "biobox", - "version" : "v0.1.0", - "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC6", - "source" : "src", - "target" : "target", - "config_mods" : [ - ".requirements.commands := ['ps']\n", - ".engines += { type: \\"native\\" }", - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - ], - "keywords" : [ - "bioinformatics", - "modules", - "sequencing" - ], - "license" : "MIT", - "organization" : "vsh", - "links" : { - "repository" : "https://github.com/viash-hub/biobox", - "issue_tracker" : "https://github.com/viash-hub/biobox/issues" - } - } -}''')) -] - -// resolve dependencies dependencies (if any) - - -// inner workflow -// inner workflow hook -def innerWorkflowFactory(args) { - def rawScript = '''set -e -tempscript=".viash_script.sh" -cat > "$tempscript" << VIASHMAIN -#!/bin/bash - -## VIASH START -# The following code has been auto-generated by Viash. -$( if [ ! -z ${VIASH_PAR_BAM+x} ]; then echo "${VIASH_PAR_BAM}" | sed "s#'#'\\"'\\"'#g;s#.*#par_bam='&'#" ; else echo "# par_bam="; fi ) -$( if [ ! -z ${VIASH_PAR_BAI+x} ]; then echo "${VIASH_PAR_BAI}" | sed "s#'#'\\"'\\"'#g;s#.*#par_bai='&'#" ; else echo "# par_bai="; fi ) -$( if [ ! -z ${VIASH_PAR_OUTPUT+x} ]; then echo "${VIASH_PAR_OUTPUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_output='&'#" ; else echo "# par_output="; fi ) -$( if [ ! -z ${VIASH_META_NAME+x} ]; then echo "${VIASH_META_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_name='&'#" ; else echo "# meta_name="; fi ) -$( if [ ! -z ${VIASH_META_FUNCTIONALITY_NAME+x} ]; then echo "${VIASH_META_FUNCTIONALITY_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_functionality_name='&'#" ; else echo "# meta_functionality_name="; fi ) -$( if [ ! -z ${VIASH_META_RESOURCES_DIR+x} ]; then echo "${VIASH_META_RESOURCES_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_resources_dir='&'#" ; else echo "# meta_resources_dir="; fi ) -$( if [ ! -z ${VIASH_META_EXECUTABLE+x} ]; then echo "${VIASH_META_EXECUTABLE}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_executable='&'#" ; else echo "# meta_executable="; fi ) -$( if [ ! -z ${VIASH_META_CONFIG+x} ]; then echo "${VIASH_META_CONFIG}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_config='&'#" ; else echo "# meta_config="; fi ) -$( if [ ! -z ${VIASH_META_TEMP_DIR+x} ]; then echo "${VIASH_META_TEMP_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_temp_dir='&'#" ; else echo "# meta_temp_dir="; fi ) -$( if [ ! -z ${VIASH_META_CPUS+x} ]; then echo "${VIASH_META_CPUS}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_cpus='&'#" ; else echo "# meta_cpus="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_B+x} ]; then echo "${VIASH_META_MEMORY_B}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_b='&'#" ; else echo "# meta_memory_b="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KB+x} ]; then echo "${VIASH_META_MEMORY_KB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kb='&'#" ; else echo "# meta_memory_kb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MB+x} ]; then echo "${VIASH_META_MEMORY_MB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mb='&'#" ; else echo "# meta_memory_mb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GB+x} ]; then echo "${VIASH_META_MEMORY_GB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gb='&'#" ; else echo "# meta_memory_gb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TB+x} ]; then echo "${VIASH_META_MEMORY_TB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tb='&'#" ; else echo "# meta_memory_tb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PB+x} ]; then echo "${VIASH_META_MEMORY_PB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pb='&'#" ; else echo "# meta_memory_pb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KIB+x} ]; then echo "${VIASH_META_MEMORY_KIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kib='&'#" ; else echo "# meta_memory_kib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MIB+x} ]; then echo "${VIASH_META_MEMORY_MIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mib='&'#" ; else echo "# meta_memory_mib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GIB+x} ]; then echo "${VIASH_META_MEMORY_GIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gib='&'#" ; else echo "# meta_memory_gib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TIB+x} ]; then echo "${VIASH_META_MEMORY_TIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tib='&'#" ; else echo "# meta_memory_tib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PIB+x} ]; then echo "${VIASH_META_MEMORY_PIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pib='&'#" ; else echo "# meta_memory_pib="; fi ) - -## VIASH END - -set -e - -samtools flagstat \\\\ - "\\$par_bam" \\\\ - > "\\$par_output" - -VIASHMAIN -bash "$tempscript" -''' - - return vdsl3WorkflowFactory(args, meta, rawScript) -} - - - -/** - * Generate a workflow for VDSL3 modules. - * - * This function is called by the workflowFactory() function. - * - * Input channel: [id, input_map] - * Output channel: [id, output_map] - * - * Internally, this workflow will convert the input channel - * to a format which the Nextflow module will be able to handle. - */ -def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { - def key = args["key"] - def processObj = null - - workflow processWf { - take: input_ - main: - - if (processObj == null) { - processObj = _vdsl3ProcessFactory(args, meta, rawScript) - } - - output_ = input_ - | map { tuple -> - def id = tuple[0] - def data_ = tuple[1] - - if (workflow.stubRun) { - // add id if missing - data_ = [id: 'stub'] + data_ - } - - // process input files separately - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { par -> - def val = data_.containsKey(par.plainName) ? data_[par.plainName] : [] - def inputFiles = [] - if (val == null) { - inputFiles = [] - } else if (val instanceof List) { - inputFiles = val - } else if (val instanceof Path) { - inputFiles = [ val ] - } else { - inputFiles = [] - } - if (!workflow.stubRun) { - // throw error when an input file doesn't exist - inputFiles.each{ file -> - assert file.exists() : - "Error in module '${key}' id '${id}' argument '${par.plainName}'.\n" + - " Required input file does not exist.\n" + - " Path: '$file'.\n" + - " Expected input file to exist" - } - } - inputFiles - } - - // remove input files - def argsExclInputFiles = meta.config.allArguments - .findAll { (it.type != "file" || it.direction != "input") && data_.containsKey(it.plainName) } - .collectEntries { par -> - def parName = par.plainName - def val = data_[parName] - if (par.multiple && val instanceof Collection) { - val = val.join(par.multiple_sep) - } - if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) - } - [parName, val] - } - - [ id ] + inputPaths + [ argsExclInputFiles, meta.resources_dir ] - } - | processObj - | map { output -> - def outputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .indexed() - .collectEntries{ index, par -> - def out = output[index + 1] - // strip dummy '.exitcode' file from output (see nextflow-io/nextflow#2678) - if (!out instanceof List || out.size() <= 1) { - if (par.multiple) { - out = [] - } else { - assert !par.required : - "Error in module '${key}' id '${output[0]}' argument '${par.plainName}'.\n" + - " Required output file is missing" - out = null - } - } else if (out.size() == 2 && !par.multiple) { - out = out[1] - } else { - out = out.drop(1) - } - [ par.plainName, out ] - } - - // drop null outputs - outputFiles.removeAll{it.value == null} - - [ output[0], outputFiles ] - } - emit: output_ - } - - return processWf -} - -// depends on: session? -def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { - // autodetect process key - def wfKey = workflowArgs["key"] - def procKeyPrefix = "${wfKey}_process" - def scriptMeta = nextflow.script.ScriptMeta.current() - def existing = scriptMeta.getProcessNames().findAll{it.startsWith(procKeyPrefix)} - def numbers = existing.collect{it.replace(procKeyPrefix, "0").toInteger()} - def newNumber = (numbers + [-1]).max() + 1 - - def procKey = newNumber == 0 ? procKeyPrefix : "$procKeyPrefix$newNumber" - - if (newNumber > 0) { - log.warn "Key for module '${wfKey}' is duplicated.\n", - "If you run a component multiple times in the same workflow,\n" + - "it's recommended you set a unique key for every call,\n" + - "for example: ${wfKey}.run(key: \"foo\")." - } - - // subset directives and convert to list of tuples - def drctv = workflowArgs.directives - - // TODO: unit test the two commands below - // convert publish array into tags - def valueToStr = { val -> - // ignore closures - if (val instanceof CharSequence) { - if (!val.matches('^[{].*[}]$')) { - '"' + val + '"' - } else { - val - } - } else if (val instanceof List) { - "[" + val.collect{valueToStr(it)}.join(", ") + "]" - } else if (val instanceof Map) { - "[" + val.collect{k, v -> k + ": " + valueToStr(v)}.join(", ") + "]" - } else { - val.inspect() - } - } - - // multiple entries allowed: label, publishdir - def drctvStrs = drctv.collect { key, value -> - if (key in ["label", "publishDir"]) { - value.collect{ val -> - if (val instanceof Map) { - "\n$key " + val.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else if (val == null) { - "" - } else { - "\n$key " + valueToStr(val) - } - }.join() - } else if (value instanceof Map) { - "\n$key " + value.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else { - "\n$key " + valueToStr(value) - } - }.join() - - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { ', path(viash_par_' + it.plainName + ', stageAs: "_viash_par/' + it.plainName + '_?/*")' } - .join() - - def outputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - // insert dummy into every output (see nextflow-io/nextflow#2678) - if (!par.multiple) { - ', path{[".exitcode", args.' + par.plainName + ']}' - } else { - ', path{[".exitcode"] + args.' + par.plainName + '}' - } - } - .join() - - // TODO: move this functionality somewhere else? - if (workflowArgs.auto.transcript) { - outputPaths = outputPaths + ', path{[".exitcode", ".command*"]}' - } else { - outputPaths = outputPaths + ', path{[".exitcode"]}' - } - - // create dirs for output files (based on BashWrapper.createParentFiles) - def createParentStr = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" && it.create_parent } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // construct inputFileExports - def inputFileExports = meta.config.allArguments - .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } - .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" - } - - // NOTE: if using docker, use /tmp instead of tmpDir! - def tmpDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('VIASH_TMPDIR') ?: - System.getenv('VIASH_TEMPDIR') ?: - System.getenv('VIASH_TMP') ?: - System.getenv('TEMP') ?: - System.getenv('TMPDIR') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMP') ?: - '/tmp' - ).toAbsolutePath() - - // construct stub - def stub = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"touch2 \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"].replace(\"_*\", \"_0\") : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // escape script - def escapedScript = rawScript.replace('\\', '\\\\').replace('$', '\\$').replace('"""', '\\"\\"\\"') - - // publishdir assert - def assertStr = (workflowArgs.auto.publish == true) || workflowArgs.auto.transcript ? - """\nassert task.publishDir.size() > 0: "if auto.publish is true, params.publish_dir needs to be defined.\\n Example: --publish_dir './output/'" """ : - "" - - // generate process string - def procStr = - """nextflow.enable.dsl=2 - | - |process $procKey {$drctvStrs - |input: - | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") - |output: - | tuple val("\$id")$outputPaths, optional: true - |stub: - |\"\"\" - |touch2() { mkdir -p "\\\$(dirname "\\\$1")" && touch "\\\$1" ; } - |$stub - |\"\"\" - |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } - |def parInject = args - | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} - | .join("\\n") - |\"\"\" - |# meta exports - |export VIASH_META_RESOURCES_DIR="\${resourcesDir}" - |export VIASH_META_TEMP_DIR="${['docker', 'podman', 'charliecloud'].any{ it == workflow.containerEngine } ? '/tmp' : tmpDir}" - |export VIASH_META_NAME="${meta.config.name}" - |# export VIASH_META_EXECUTABLE="\\\$VIASH_META_RESOURCES_DIR/\\\$VIASH_META_NAME" - |export VIASH_META_CONFIG="\\\$VIASH_META_RESOURCES_DIR/.config.vsh.yaml" - |\${task.cpus ? "export VIASH_META_CPUS=\$task.cpus" : "" } - |\${task.memory?.bytes != null ? "export VIASH_META_MEMORY_B=\$task.memory.bytes" : "" } - |if [ ! -z \\\${VIASH_META_MEMORY_B+x} ]; then - | export VIASH_META_MEMORY_KB=\\\$(( (\\\$VIASH_META_MEMORY_B+999) / 1000 )) - | export VIASH_META_MEMORY_MB=\\\$(( (\\\$VIASH_META_MEMORY_KB+999) / 1000 )) - | export VIASH_META_MEMORY_GB=\\\$(( (\\\$VIASH_META_MEMORY_MB+999) / 1000 )) - | export VIASH_META_MEMORY_TB=\\\$(( (\\\$VIASH_META_MEMORY_GB+999) / 1000 )) - | export VIASH_META_MEMORY_PB=\\\$(( (\\\$VIASH_META_MEMORY_TB+999) / 1000 )) - | export VIASH_META_MEMORY_KIB=\\\$(( (\\\$VIASH_META_MEMORY_B+1023) / 1024 )) - | export VIASH_META_MEMORY_MIB=\\\$(( (\\\$VIASH_META_MEMORY_KIB+1023) / 1024 )) - | export VIASH_META_MEMORY_GIB=\\\$(( (\\\$VIASH_META_MEMORY_MIB+1023) / 1024 )) - | export VIASH_META_MEMORY_TIB=\\\$(( (\\\$VIASH_META_MEMORY_GIB+1023) / 1024 )) - | export VIASH_META_MEMORY_PIB=\\\$(( (\\\$VIASH_META_MEMORY_TIB+1023) / 1024 )) - |fi - | - |# meta synonyms - |export VIASH_TEMP="\\\$VIASH_META_TEMP_DIR" - |export TEMP_DIR="\\\$VIASH_META_TEMP_DIR" - | - |# create output dirs if need be - |function mkdir_parent { - | for file in "\\\$@"; do - | mkdir -p "\\\$(dirname "\\\$file")" - | done - |} - |$createParentStr - | - |# argument exports${inputFileExports.join()} - |\$parInject - | - |# process script - |${escapedScript} - |\"\"\" - |} - |""".stripMargin() - - // TODO: print on debug - // if (workflowArgs.debug == true) { - // println("######################\n$procStr\n######################") - // } - - // write process to temp file - def tempFile = java.nio.file.Files.createTempFile("viash-process-${procKey}-", ".nf") - addShutdownHook { java.nio.file.Files.deleteIfExists(tempFile) } - tempFile.text = procStr - - // create process from temp file - def binding = new nextflow.script.ScriptBinding([:]) - def session = nextflow.Nextflow.getSession() - def parser = new nextflow.script.ScriptParser(session) - .setModule(true) - .setBinding(binding) - def moduleScript = parser.runScript(tempFile) - .getScript() - - // register module in meta - def module = new nextflow.script.IncludeDef.Module(name: procKey) - scriptMeta.addModule(moduleScript, module.name, module.alias) - - // retrieve and return process from meta - return scriptMeta.getProcess(procKey) -} - -// defaults -meta["defaults"] = [ - // key to be used to trace the process and determine output names - key: null, - - // fixed arguments to be passed to script - args: [:], - - // default directives - directives: readJsonBlob('''{ - "container" : { - "registry" : "images.viash-hub.com", - "image" : "vsh/biobox/samtools/samtools_flagstat", - "tag" : "v0.1.0" - }, - "tag" : "$id" -}'''), - - // auto settings - auto: readJsonBlob('''{ - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false -}'''), - - // Apply a map over the incoming tuple - // Example: `{ tup -> [ tup[0], [input: tup[1].output] ] + tup.drop(2) }` - map: null, - - // Apply a map over the ID element of a tuple (i.e. the first element) - // Example: `{ id -> id + "_foo" }` - mapId: null, - - // Apply a map over the data element of a tuple (i.e. the second element) - // Example: `{ data -> [ input: data.output ] }` - mapData: null, - - // Apply a map over the passthrough elements of a tuple (i.e. the tuple excl. the first two elements) - // Example: `{ pt -> pt.drop(1) }` - mapPassthrough: null, - - // Filter the channel - // Example: `{ tup -> tup[0] == "foo" }` - filter: null, - - // Choose whether or not to run the component on the tuple if the condition is true. - // Otherwise, the tuple will be passed through. - // Example: `{ tup -> tup[0] != "skip_this" }` - runIf: null, - - // Rename keys in the data field of the tuple (i.e. the second element) - // Will likely be deprecated in favour of `fromState`. - // Example: `[ "new_key": "old_key" ]` - renameKeys: null, - - // Fetch data from the state and pass it to the module without altering the current state. - // - // `fromState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be passed to the module as is. - // - If it is a `List[String]`, the data will be the values of the state at the given keys. - // - If it is a `Map[String, String]`, the data will be the values of the state at the given keys, with the keys renamed according to the map. - // - If it is a function, the tuple (`[id, state]`) in the channel will be passed to the function, and the result will be used as the data. - // - // Example: `{ id, state -> [input: state.fastq_file] }` - // Default: `null` - fromState: null, - - // Determine how the state should be updated after the module has been run. - // - // `toState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be replaced with the output of the module. - // - If it is a `List[String]`, the state will be updated with the values of the data at the given keys. - // - If it is a `Map[String, String]`, the state will be updated with the values of the data at the given keys, with the keys renamed according to the map. - // - If it is a function, a tuple (`[id, output, state]`) will be passed to the function, and the result will be used as the new state. - // - // Example: `{ id, output, state -> state + [counts: state.output] }` - // Default: `{ id, output, state -> output }` - toState: null, - - // Whether or not to print debug messages - // Default: `false` - debug: false -] - -// initialise default workflow -meta["workflow"] = workflowFactory([key: meta.config.name], meta.defaults, meta) - -// add workflow to environment -nextflow.script.ScriptMeta.current().addDefinition(meta.workflow) - -// anonymous workflow for running this module as a standalone -workflow { - // add id argument if it's not already in the config - // TODO: deep copy - def newConfig = deepClone(meta.config) - def newParams = deepClone(params) - - def argsContainsId = newConfig.allArguments.any{it.plainName == "id"} - if (!argsContainsId) { - def idArg = [ - 'name': '--id', - 'required': false, - 'type': 'string', - 'description': 'A unique id for every entry.', - 'multiple': false - ] - newConfig.arguments.add(0, idArg) - newConfig = processConfig(newConfig) - } - if (!newParams.containsKey("id")) { - newParams.id = "run" - } - - helpMessage(newConfig) - - channelFromParams(newParams, newConfig) - // make sure id is not in the state if id is not in the args - | map {id, state -> - if (!argsContainsId) { - [id, state.findAll{k, v -> k != "id"}] - } else { - [id, state] - } - } - | meta.workflow.run( - auto: [ publish: "state" ] - ) -} - -// END COMPONENT-SPECIFIC CODE diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/nextflow.config deleted file mode 100644 index 5f257fe..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/nextflow.config +++ /dev/null @@ -1,125 +0,0 @@ -manifest { - name = 'samtools/samtools_flagstat' - mainScript = 'main.nf' - nextflowVersion = '!>=20.12.1-edge' - version = 'v0.1.0' - description = 'Counts the number of alignments in SAM/BAM/CRAM files for each FLAG type.' -} - -process.container = 'nextflow/bash:latest' - -// detect tempdir -tempDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMPDIR') ?: - '/tmp' -).toAbsolutePath() - -profiles { - no_publish { - process { - withName: '.*' { - publishDir = [ - enabled: false - ] - } - } - } - mount_temp { - docker.temp = tempDir - podman.temp = tempDir - charliecloud.temp = tempDir - } - docker { - docker.enabled = true - // docker.userEmulation = true - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - singularity { - singularity.enabled = true - singularity.autoMounts = true - docker.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - podman { - podman.enabled = true - docker.enabled = false - singularity.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - shifter { - shifter.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - charliecloud.enabled = false - } - charliecloud { - charliecloud.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - } -} - -process{ - withLabel: mem1gb { memory = 1000000000.B } - withLabel: mem2gb { memory = 2000000000.B } - withLabel: mem5gb { memory = 5000000000.B } - withLabel: mem10gb { memory = 10000000000.B } - withLabel: mem20gb { memory = 20000000000.B } - withLabel: mem50gb { memory = 50000000000.B } - withLabel: mem100gb { memory = 100000000000.B } - withLabel: mem200gb { memory = 200000000000.B } - withLabel: mem500gb { memory = 500000000000.B } - withLabel: mem1tb { memory = 1000000000000.B } - withLabel: mem2tb { memory = 2000000000000.B } - withLabel: mem5tb { memory = 5000000000000.B } - withLabel: mem10tb { memory = 10000000000000.B } - withLabel: mem20tb { memory = 20000000000000.B } - withLabel: mem50tb { memory = 50000000000000.B } - withLabel: mem100tb { memory = 100000000000000.B } - withLabel: mem200tb { memory = 200000000000000.B } - withLabel: mem500tb { memory = 500000000000000.B } - withLabel: mem1gib { memory = 1073741824.B } - withLabel: mem2gib { memory = 2147483648.B } - withLabel: mem4gib { memory = 4294967296.B } - withLabel: mem8gib { memory = 8589934592.B } - withLabel: mem16gib { memory = 17179869184.B } - withLabel: mem32gib { memory = 34359738368.B } - withLabel: mem64gib { memory = 68719476736.B } - withLabel: mem128gib { memory = 137438953472.B } - withLabel: mem256gib { memory = 274877906944.B } - withLabel: mem512gib { memory = 549755813888.B } - withLabel: mem1tib { memory = 1099511627776.B } - withLabel: mem2tib { memory = 2199023255552.B } - withLabel: mem4tib { memory = 4398046511104.B } - withLabel: mem8tib { memory = 8796093022208.B } - withLabel: mem16tib { memory = 17592186044416.B } - withLabel: mem32tib { memory = 35184372088832.B } - withLabel: mem64tib { memory = 70368744177664.B } - withLabel: mem128tib { memory = 140737488355328.B } - withLabel: mem256tib { memory = 281474976710656.B } - withLabel: mem512tib { memory = 562949953421312.B } - withLabel: cpu1 { cpus = 1 } - withLabel: cpu2 { cpus = 2 } - withLabel: cpu5 { cpus = 5 } - withLabel: cpu10 { cpus = 10 } - withLabel: cpu20 { cpus = 20 } - withLabel: cpu50 { cpus = 50 } - withLabel: cpu100 { cpus = 100 } - withLabel: cpu200 { cpus = 200 } - withLabel: cpu500 { cpus = 500 } - withLabel: cpu1000 { cpus = 1000 } -} - - diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/nextflow_schema.json deleted file mode 100644 index 6c3cfd0..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/nextflow_schema.json +++ /dev/null @@ -1,105 +0,0 @@ -{ -"$schema": "http://json-schema.org/draft-07/schema", -"title": "samtools_flagstat", -"description": "Counts the number of alignments in SAM/BAM/CRAM files for each FLAG type.", -"type": "object", -"definitions": { - - - - "inputs" : { - "title": "Inputs", - "type": "object", - "description": "No description", - "properties": { - - - "bam": { - "type": - "string", - "description": "Type: `file`. BAM input files", - "help_text": "Type: `file`. BAM input files.\n" - - } - - - , - "bai": { - "type": - "string", - "description": "Type: `file`. BAM index file", - "help_text": "Type: `file`. BAM index file.\n" - - } - - -} -}, - - - "outputs" : { - "title": "Outputs", - "type": "object", - "description": "No description", - "properties": { - - - "output": { - "type": - "string", - "description": "Type: `file`, required, default: `$id.$key.output.flagstat`, example: `output.flagstat`. File containing samtools stats output", - "help_text": "Type: `file`, required, default: `$id.$key.output.flagstat`, example: `output.flagstat`. File containing samtools stats output.\n" - , - "default": "$id.$key.output.flagstat" - } - - -} -}, - - - "nextflow input-output arguments" : { - "title": "Nextflow input-output arguments", - "type": "object", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "properties": { - - - "publish_dir": { - "type": - "string", - "description": "Type: `string`, required, example: `output/`. Path to an output directory", - "help_text": "Type: `string`, required, example: `output/`. Path to an output directory." - - } - - - , - "param_list": { - "type": - "string", - "description": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel", - "help_text": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob.\n\n* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ [\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027], [\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027] ]`.\n* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`.\n* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]`.\n* A yaml blob can also be passed directly as a string. Example: `--param_list \"[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]\"`.\n\nWhen passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.", - "hidden": true - - } - - -} -} -}, -"allOf": [ - - { - "$ref": "#/definitions/inputs" - }, - - { - "$ref": "#/definitions/outputs" - }, - - { - "$ref": "#/definitions/nextflow input-output arguments" - } -] -} diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/.config.vsh.yaml deleted file mode 100644 index b719c40..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/.config.vsh.yaml +++ /dev/null @@ -1,195 +0,0 @@ -name: "samtools_idxstats" -namespace: "samtools" -version: "v0.1.0" -argument_groups: -- name: "Inputs" - arguments: - - type: "file" - name: "--bam" - description: "BAM input file." - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--bai" - description: "BAM index file." - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--fasta" - description: "Reference file the CRAM was created with (optional)." - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" -- name: "Outputs" - arguments: - - type: "file" - name: "--output" - description: "File containing samtools stats output in tab-delimited format.\n" - info: null - example: - - "output.idxstats" - must_exist: true - create_parent: true - required: true - direction: "output" - multiple: false - multiple_sep: ";" -resources: -- type: "bash_script" - path: "script.sh" - is_executable: true -description: "Reports alignment summary statistics for a BAM file." -test_resources: -- type: "bash_script" - path: "test.sh" - is_executable: true -- type: "file" - path: "test_data" -info: null -status: "enabled" -requirements: - commands: - - "ps" -keywords: -- "stats" -- "mapping" -- "counts" -- "chromosome" -- "bam" -- "sam" -- "cram" -license: "MIT/Expat" -references: - doi: - - "10.1093/bioinformatics/btp352" - - "10.1093/gigascience/giab008" -links: - repository: "https://github.com/samtools/samtools" - homepage: "https://www.htslib.org/" - documentation: "https://www.htslib.org/doc/samtools-idxstats.html" -runners: -- type: "executable" - id: "executable" - docker_setup_strategy: "ifneedbepullelsecachedbuild" -- type: "nextflow" - id: "nextflow" - directives: - tag: "$id" - auto: - simplifyInput: true - simplifyOutput: false - transcript: false - publish: false - config: - labels: - mem1gb: "memory = 1000000000.B" - mem2gb: "memory = 2000000000.B" - mem5gb: "memory = 5000000000.B" - mem10gb: "memory = 10000000000.B" - mem20gb: "memory = 20000000000.B" - mem50gb: "memory = 50000000000.B" - mem100gb: "memory = 100000000000.B" - mem200gb: "memory = 200000000000.B" - mem500gb: "memory = 500000000000.B" - mem1tb: "memory = 1000000000000.B" - mem2tb: "memory = 2000000000000.B" - mem5tb: "memory = 5000000000000.B" - mem10tb: "memory = 10000000000000.B" - mem20tb: "memory = 20000000000000.B" - mem50tb: "memory = 50000000000000.B" - mem100tb: "memory = 100000000000000.B" - mem200tb: "memory = 200000000000000.B" - mem500tb: "memory = 500000000000000.B" - mem1gib: "memory = 1073741824.B" - mem2gib: "memory = 2147483648.B" - mem4gib: "memory = 4294967296.B" - mem8gib: "memory = 8589934592.B" - mem16gib: "memory = 17179869184.B" - mem32gib: "memory = 34359738368.B" - mem64gib: "memory = 68719476736.B" - mem128gib: "memory = 137438953472.B" - mem256gib: "memory = 274877906944.B" - mem512gib: "memory = 549755813888.B" - mem1tib: "memory = 1099511627776.B" - mem2tib: "memory = 2199023255552.B" - mem4tib: "memory = 4398046511104.B" - mem8tib: "memory = 8796093022208.B" - mem16tib: "memory = 17592186044416.B" - mem32tib: "memory = 35184372088832.B" - mem64tib: "memory = 70368744177664.B" - mem128tib: "memory = 140737488355328.B" - mem256tib: "memory = 281474976710656.B" - mem512tib: "memory = 562949953421312.B" - cpu1: "cpus = 1" - cpu2: "cpus = 2" - cpu5: "cpus = 5" - cpu10: "cpus = 10" - cpu20: "cpus = 20" - cpu50: "cpus = 50" - cpu100: "cpus = 100" - cpu200: "cpus = 200" - cpu500: "cpus = 500" - cpu1000: "cpus = 1000" - debug: false - container: "docker" -engines: -- type: "docker" - id: "docker" - image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" - target_registry: "images.viash-hub.com" - target_tag: "v0.1.0" - namespace_separator: "/" - setup: - - type: "docker" - run: - - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\nsed 's#Using\ - \ ##;s# \\([0-9\\.]*\\)$#: \\1#' > /var/software_versions.txt\n" - entrypoint: [] - cmd: null -- type: "native" - id: "native" -build_info: - config: "src/samtools/samtools_idxstats/config.vsh.yaml" - runner: "nextflow" - engine: "docker|native" - output: "target/nextflow/samtools/samtools_idxstats" - executable: "target/nextflow/samtools/samtools_idxstats/main.nf" - viash_version: "0.9.0-RC6" - git_commit: "b84b29747d0635f2ac83ea63b496be9a9edb6724" - git_remote: "https://github.com/viash-hub/biobox" -package_config: - name: "biobox" - version: "v0.1.0" - description: "A collection of bioinformatics tools for working with sequence data.\n" - info: null - viash_version: "0.9.0-RC6" - source: "src" - target: "target" - config_mods: - - ".requirements.commands := ['ps']\n" - - ".engines += { type: \"native\" }" - - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - keywords: - - "bioinformatics" - - "modules" - - "sequencing" - license: "MIT" - organization: "vsh" - links: - repository: "https://github.com/viash-hub/biobox" - issue_tracker: "https://github.com/viash-hub/biobox/issues" diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/main.nf b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/main.nf deleted file mode 100644 index 14bc7da..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/main.nf +++ /dev/null @@ -1,3538 +0,0 @@ -// samtools_idxstats v0.1.0 -// -// This wrapper script is auto-generated by viash 0.9.0-RC6 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. -// -// The component may contain files which fall under a different license. The -// authors of this component should specify the license in the header of such -// files, or include a separate license file detailing the licenses of all included -// files. - -//////////////////////////// -// VDSL3 helper functions // -//////////////////////////// - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_checkArgumentType.nf' -class UnexpectedArgumentTypeException extends Exception { - String errorIdentifier - String stage - String plainName - String expectedClass - String foundClass - - // ${key ? " in module '$key'" : ""}${id ? " id '$id'" : ""} - UnexpectedArgumentTypeException(String errorIdentifier, String stage, String plainName, String expectedClass, String foundClass) { - super("Error${errorIdentifier ? " $errorIdentifier" : ""}:${stage ? " $stage" : "" } argument '${plainName}' has the wrong type. " + - "Expected type: ${expectedClass}. Found type: ${foundClass}") - this.errorIdentifier = errorIdentifier - this.stage = stage - this.plainName = plainName - this.expectedClass = expectedClass - this.foundClass = foundClass - } -} - -/** - * Checks if the given value is of the expected type. If not, an exception is thrown. - * - * @param stage The stage of the argument (input or output) - * @param par The parameter definition - * @param value The value to check - * @param errorIdentifier The identifier to use in the error message - * @return The value, if it is of the expected type - * @throws UnexpectedArgumentTypeException If the value is not of the expected type -*/ -def _checkArgumentType(String stage, Map par, Object value, String errorIdentifier) { - // expectedClass will only be != null if value is not of the expected type - def expectedClass = null - def foundClass = null - - // todo: split if need be - - if (!par.required && value == null) { - expectedClass = null - } else if (par.multiple) { - if (value !instanceof Collection) { - value = [value] - } - - // split strings - value = value.collectMany{ val -> - if (val instanceof String) { - // collect() to ensure that the result is a List and not simply an array - val.split(par.multiple_sep).collect() - } else { - [val] - } - } - - // process globs - if (par.type == "file" && par.direction == "input") { - value = value.collect{ it instanceof String ? file(it, hidden: true) : it }.flatten() - } - - // check types of elements in list - try { - value = value.collect { listVal -> - _checkArgumentType(stage, par + [multiple: false], listVal, errorIdentifier) - } - } catch (UnexpectedArgumentTypeException e) { - expectedClass = "List[${e.expectedClass}]" - foundClass = "List[${e.foundClass}]" - } - } else if (par.type == "string") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else if (par.type == "integer") { - // cast to integer if need be - if (value instanceof String) { - try { - value = value.toInteger() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigInteger) { - value = value.intValue() - } - expectedClass = value instanceof Integer ? null : "Integer" - } else if (par.type == "long") { - // cast to long if need be - if (value instanceof String) { - try { - value = value.toLong() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof Integer) { - value = value.toLong() - } - expectedClass = value instanceof Long ? null : "Long" - } else if (par.type == "double") { - // cast to double if need be - if (value instanceof String) { - try { - value = value.toDouble() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigDecimal) { - value = value.doubleValue() - } - if (value instanceof Float) { - value = value.toDouble() - } - expectedClass = value instanceof Double ? null : "Double" - } else if (par.type == "boolean" | par.type == "boolean_true" | par.type == "boolean_false") { - // cast to boolean if need be - if (value instanceof String) { - def valueLower = value.toLowerCase() - if (valueLower == "true") { - value = true - } else if (valueLower == "false") { - value = false - } - } - expectedClass = value instanceof Boolean ? null : "Boolean" - } else if (par.type == "file" && (par.direction == "input" || stage == "output")) { - // cast to path if need be - if (value instanceof String) { - value = file(value, hidden: true) - } - if (value instanceof File) { - value = value.toPath() - } - expectedClass = value instanceof Path ? null : "Path" - } else if (par.type == "file" && stage == "input" && par.direction == "output") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else { - // didn't find a match for par.type - expectedClass = par.type - } - - if (expectedClass != null) { - if (foundClass == null) { - foundClass = value.getClass().getName() - } - throw new UnexpectedArgumentTypeException(errorIdentifier, stage, par.plainName, expectedClass, foundClass) - } - - return value -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processInputValues.nf' -Map _processInputValues(Map inputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.required) { - assert inputs.containsKey(arg.plainName) && inputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required input argument '${arg.plainName}' is missing" - } - } - - inputs = inputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid input argument" - - value = _checkArgumentType("input", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return inputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processOutputValues.nf' -Map _processOutputValues(Map outputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.direction == "output" && arg.required) { - assert outputs.containsKey(arg.plainName) && outputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required output argument '${arg.plainName}' is missing" - } - } - - outputs = outputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && it.direction == "output" } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid output argument" - - value = _checkArgumentType("output", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return outputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/IDChecker.nf' -class IDChecker { - final def items = [] as Set - - @groovy.transform.WithWriteLock - boolean observe(String item) { - if (items.contains(item)) { - return false - } else { - items << item - return true - } - } - - @groovy.transform.WithReadLock - boolean contains(String item) { - return items.contains(item) - } - - @groovy.transform.WithReadLock - Set getItems() { - return items.clone() - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_checkUniqueIds.nf' - -/** - * Check if the ids are unique across parameter sets - * - * @param parameterSets a list of parameter sets. - */ -private void _checkUniqueIds(List>> parameterSets) { - def ppIds = parameterSets.collect{it[0]} - assert ppIds.size() == ppIds.unique().size() : "All argument sets should have unique ids. Detected ids: $ppIds" -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_getChild.nf' - -// helper functions for reading params from file // -def _getChild(parent, child) { - if (child.contains("://") || java.nio.file.Paths.get(child).isAbsolute()) { - child - } else { - def parentAbsolute = java.nio.file.Paths.get(parent).toAbsolutePath().toString() - parentAbsolute.replaceAll('/[^/]*$', "/") + child - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_parseParamList.nf' -/** - * Figure out the param list format based on the file extension - * - * @param param_list A String containing the path to the parameter list file. - * - * @return A String containing the format of the parameter list file. - */ -def _paramListGuessFormat(param_list) { - if (param_list !instanceof String) { - "asis" - } else if (param_list.endsWith(".csv")) { - "csv" - } else if (param_list.endsWith(".json") || param_list.endsWith(".jsn")) { - "json" - } else if (param_list.endsWith(".yaml") || param_list.endsWith(".yml")) { - "yaml" - } else { - "yaml_blob" - } -} - - -/** - * Read the param list - * - * @param param_list One of the following: - * - A String containing the path to the parameter list file (csv, json or yaml), - * - A yaml blob of a list of maps (yaml_blob), - * - Or a groovy list of maps (asis). - * @param config A Map of the Viash configuration. - * - * @return A List of Maps containing the parameters. - */ -def _parseParamList(param_list, Map config) { - // first determine format by extension - def paramListFormat = _paramListGuessFormat(param_list) - - def paramListPath = (paramListFormat != "asis" && paramListFormat != "yaml_blob") ? - file(param_list, hidden: true) : - null - - // get the correct parser function for the detected params_list format - def paramSets = [] - if (paramListFormat == "asis") { - paramSets = param_list - } else if (paramListFormat == "yaml_blob") { - paramSets = readYamlBlob(param_list) - } else if (paramListFormat == "yaml") { - paramSets = readYaml(paramListPath) - } else if (paramListFormat == "json") { - paramSets = readJson(paramListPath) - } else if (paramListFormat == "csv") { - paramSets = readCsv(paramListPath) - } else { - error "Format of provided --param_list not recognised.\n" + - "Found: '$paramListFormat'.\n" + - "Expected: a csv file, a json file, a yaml file,\n" + - "a yaml blob or a groovy list of maps." - } - - // data checks - assert paramSets instanceof List: "--param_list should contain a list of maps" - for (value in paramSets) { - assert value instanceof Map: "--param_list should contain a list of maps" - } - - // id is argument - def idIsArgument = config.allArguments.any{it.plainName == "id"} - - // Reformat from List to List> by adding the ID as first element of a Tuple2 - paramSets = paramSets.collect({ data -> - def id = data.id - if (!idIsArgument) { - data = data.findAll{k, v -> k != "id"} - } - [id, data] - }) - - // Split parameters with 'multiple: true' - paramSets = paramSets.collect({ id, data -> - data = _splitParams(data, config) - [id, data] - }) - - // The paths of input files inside a param_list file may have been specified relatively to the - // location of the param_list file. These paths must be made absolute. - if (paramListPath) { - paramSets = paramSets.collect({ id, data -> - def new_data = data.collectEntries{ parName, parValue -> - def par = config.allArguments.find{it.plainName == parName} - if (par && par.type == "file" && par.direction == "input") { - if (parValue instanceof Collection) { - parValue = parValue.collectMany{path -> - def x = _resolveSiblingIfNotAbsolute(path, paramListPath) - x instanceof Collection ? x : [x] - } - } else { - parValue = _resolveSiblingIfNotAbsolute(parValue, paramListPath) - } - } - [parName, parValue] - } - [id, new_data] - }) - } - - return paramSets -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_splitParams.nf' -/** - * Split parameters for arguments that accept multiple values using their separator - * - * @param paramList A Map containing parameters to split. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A Map of parameters where the parameter values have been split into a list using - * their seperator. - */ -Map _splitParams(Map parValues, Map config){ - def parsedParamValues = parValues.collectEntries { parName, parValue -> - def parameterSettings = config.allArguments.find({it.plainName == parName}) - - if (!parameterSettings) { - // if argument is not found, do not alter - return [parName, parValue] - } - if (parameterSettings.multiple) { // Check if parameter can accept multiple values - if (parValue instanceof Collection) { - parValue = parValue.collect{it instanceof String ? it.split(parameterSettings.multiple_sep) : it } - } else if (parValue instanceof String) { - parValue = parValue.split(parameterSettings.multiple_sep) - } else if (parValue == null) { - parValue = [] - } else { - parValue = [ parValue ] - } - parValue = parValue.flatten() - } - // For all parameters check if multiple values are only passed for - // arguments that allow it. Quietly simplify lists of length 1. - if (!parameterSettings.multiple && parValue instanceof Collection) { - assert parValue.size() == 1 : - "Error: argument ${parName} has too many values.\n" + - " Expected amount: 1. Found: ${parValue.size()}" - parValue = parValue[0] - } - [parName, parValue] - } - return parsedParamValues -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/channelFromParams.nf' -/** - * Parse nextflow parameters based on settings defined in a viash config. - * Return a list of parameter sets, each parameter set corresponding to - * an event in a nextflow channel. The output from this function can be used - * with Channel.fromList to create a nextflow channel with Vdsl3 formatted - * events. - * - * This function performs: - * - A filtering of the params which can be found in the config file. - * - Process the params_list argument which allows a user to to initialise - * a Vsdl3 channel with multiple parameter sets. Possible formats are - * csv, json, yaml, or simply a yaml_blob. A csv should have column names - * which correspond to the different arguments of this pipeline. A json or a yaml - * file should be a list of maps, each of which has keys corresponding to the - * arguments of the pipeline. A yaml blob can also be passed directly as a parameter. - * When passing a csv, json or yaml, relative path names are relativized to the - * location of the parameter file. - * - Combine the parameter sets into a vdsl3 Channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A list of parameters with the first element of the event being - * the event ID and the second element containing a map of the parsed parameters. - */ - -private List>> _paramsToParamSets(Map params, Map config){ - // todo: fetch key from run args - def key_ = config.name - - /* parse regular parameters (not in param_list) */ - /*************************************************/ - def globalParams = config.allArguments - .findAll { params.containsKey(it.plainName) } - .collectEntries { [ it.plainName, params[it.plainName] ] } - def globalID = params.get("id", null) - - /* process params_list arguments */ - /*********************************/ - def paramList = params.containsKey("param_list") && params.param_list != null ? - params.param_list : [] - // if (paramList instanceof String) { - // paramList = [paramList] - // } - // def paramSets = paramList.collectMany{ _parseParamList(it, config) } - // TODO: be able to process param_list when it is a list of strings - def paramSets = _parseParamList(paramList, config) - if (paramSets.isEmpty()) { - paramSets = [[null, [:]]] - } - - /* combine arguments into channel */ - /**********************************/ - def processedParams = paramSets.indexed().collect{ index, tup -> - // Process ID - def id = tup[0] ?: globalID - - if (workflow.stubRun && !id) { - // if stub run, explicitly add an id if missing - id = "stub${index}" - } - assert id != null: "Each parameter set should have at least an 'id'" - - // Process params - def parValues = globalParams + tup[1] - // // Remove parameters which are null, if the default is also null - // parValues = parValues.collectEntries{paramName, paramValue -> - // parameterSettings = config.functionality.allArguments.find({it.plainName == paramName}) - // if ( paramValue != null || parameterSettings.get("default", null) != null ) { - // [paramName, paramValue] - // } - // } - parValues = parValues.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key_}' id '${id}': '${name}' is not a valid input argument" - - if (par == null) { - return [:] - } - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - - [ name, value ] - } - - [id, parValues] - } - - // Check if ids (first element of each list) is unique - _checkUniqueIds(processedParams) - return processedParams -} - -/** - * Parse nextflow parameters based on settings defined in a viash config - * and return a nextflow channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A nextflow Channel with events. Events are formatted as a tuple that contains - * first contains the ID of the event and as second element holds a parameter map. - * - * - */ -def channelFromParams(Map params, Map config) { - def processedParams = _paramsToParamSets(params, config) - return Channel.fromList(processedParams) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/checkUniqueIds.nf' -def checkUniqueIds(Map args) { - def stopOnError = args.stopOnError == null ? args.stopOnError : true - - def idChecker = new IDChecker() - - return filter { tup -> - if (!idChecker.observe(tup[0])) { - if (stopOnError) { - error "Duplicate id: ${tup[0]}" - } else { - log.warn "Duplicate id: ${tup[0]}, removing duplicate entry" - return false - } - } - return true - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/preprocessInputs.nf' -// This helper file will be deprecated soon -preprocessInputsDeprecationWarningPrinted = false - -def preprocessInputsDeprecationWarning() { - if (!preprocessInputsDeprecationWarningPrinted) { - preprocessInputsDeprecationWarningPrinted = true - System.err.println("Warning: preprocessInputs() is deprecated and will be removed in Viash 0.9.0.") - } -} - -/** - * Generate a nextflow Workflow that allows processing a channel of - * Vdsl3 formatted events and apply a Viash config to them: - * - Gather default parameters from the Viash config and make - * sure that they are correctly formatted (see applyConfig method). - * - Format the input parameters (also using the applyConfig method). - * - Apply the default parameter to the input parameters. - * - Do some assertions: - * ~ Check if the event IDs in the channel are unique. - * - * The events in the channel are formatted as tuples, with the - * first element of the tuples being a unique id of the parameter set, - * and the second element containg the the parameters themselves. - * Optional extra elements of the tuples will be passed to the output as is. - * - * @param args A map that must contain a 'config' key that points - * to a parsed config (see readConfig()). Optionally, a - * 'key' key can be provided which can be used to create a unique - * name for the workflow process. - * - * @return A workflow that allows processing a channel of Vdsl3 formatted events - * and apply a Viash config to them. - */ -def preprocessInputs(Map args) { - preprocessInputsDeprecationWarning() - - def config = args.config - assert config instanceof Map : - "Error in preprocessInputs: config must be a map. " + - "Expected class: Map. Found: config.getClass() is ${config.getClass()}" - def key_ = args.key ?: config.name - - // Get different parameter types (used throughout this function) - def defaultArgs = config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - map { tup -> - def id = tup[0] - def data = tup[1] - def passthrough = tup.drop(2) - - def new_data = (defaultArgs + data).collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - - if (par != null) { - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - } - - [ name, value ] - } - - [ id, new_data ] + passthrough - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runComponents.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component config. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component config. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component config. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component config. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runComponents(Map args) { - log.warn("runComponents is deprecated, use runEach instead") - assert args.components: "runComponents should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runComponents" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runComponentsWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def comp_config = comp_.config - - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_config) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - // def new_id = id_(tup[0], tup[1], comp_config) - def new_id = tup[0] - if (id_ instanceof String) { - new_id = id_ - } else if (id_ instanceof Closure) { - new_id = id_(new_id, tup[1], comp_config) - } - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_config) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_config) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runComponentsWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runEach.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component itself. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component itself. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component itself. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component itself. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runEach(Map args) { - assert args.components: "runEach should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runEach" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runEachWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - def new_id = id_ - if (new_id instanceof Closure) { - new_id = new_id(tup[0], tup[1], comp_) - } - assert new_id instanceof String : "Error in runEach: id should be a String or a Closure that returns a String. Expected: id instanceof String. Found: ${new_id.getClass()}" - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runEachWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/safeJoin.nf' -/** - * Join sourceChannel to targetChannel - * - * This function joins the sourceChannel to the targetChannel. - * However, each id in the targetChannel must be present in the - * sourceChannel. If _meta.join_id exists in the targetChannel, that is - * used as an id instead. If the id doesn't match any id in the sourceChannel, - * an error is thrown. - */ - -def safeJoin(targetChannel, sourceChannel, key) { - def sourceIDs = new IDChecker() - - def sourceCheck = sourceChannel - | map { tup -> - sourceIDs.observe(tup[0]) - tup - } - def targetCheck = targetChannel - | map { tup -> - def id = tup[0] - - if (!sourceIDs.contains(id)) { - error ( - "Error in module '${key}' when merging output with original state.\n" + - " Reason: output with id '${id}' could not be joined with source channel.\n" + - " If the IDs in the output channel differ from the input channel,\n" + - " please set `tup[1]._meta.join_id to the original ID.\n" + - " Original IDs in input channel: ['${sourceIDs.getItems().join("', '")}'].\n" + - " Unexpected ID in the output channel: '${id}'.\n" + - " Example input event: [\"id\", [input: file(...)]],\n" + - " Example output event: [\"newid\", [output: file(...), _meta: [join_id: \"id\"]]]" - ) - } - // TODO: add link to our documentation on how to fix this - - tup - } - - sourceCheck.cross(targetChannel) - | map{ left, right -> - right + left.drop(1) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/_processArgument.nf' -def _processArgument(arg) { - arg.multiple = arg.multiple != null ? arg.multiple : false - arg.required = arg.required != null ? arg.required : false - arg.direction = arg.direction != null ? arg.direction : "input" - arg.multiple_sep = arg.multiple_sep != null ? arg.multiple_sep : ";" - arg.plainName = arg.name.replaceAll("^-*", "") - - if (arg.type == "file") { - arg.must_exist = arg.must_exist != null ? arg.must_exist : true - arg.create_parent = arg.create_parent != null ? arg.create_parent : true - } - - // add default values to output files which haven't already got a default - if (arg.type == "file" && arg.direction == "output" && arg.default == null) { - def mult = arg.multiple ? "_*" : "" - def extSearch = "" - if (arg.default != null) { - extSearch = arg.default - } else if (arg.example != null) { - extSearch = arg.example - } - if (extSearch instanceof List) { - extSearch = extSearch[0] - } - def extSearchResult = extSearch.find("\\.[^\\.]+\$") - def ext = extSearchResult != null ? extSearchResult : "" - arg.default = "\$id.\$key.${arg.plainName}${mult}${ext}" - if (arg.multiple) { - arg.default = [arg.default] - } - } - - if (!arg.multiple) { - if (arg.default != null && arg.default instanceof List) { - arg.default = arg.default[0] - } - if (arg.example != null && arg.example instanceof List) { - arg.example = arg.example[0] - } - } - - if (arg.type == "boolean_true") { - arg.default = false - } - if (arg.type == "boolean_false") { - arg.default = true - } - - arg -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/addGlobalParams.nf' -def addGlobalArguments(config) { - def localConfig = [ - "argument_groups": [ - [ - "name": "Nextflow input-output arguments", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "arguments" : [ - [ - 'name': '--publish_dir', - 'required': true, - 'type': 'string', - 'description': 'Path to an output directory.', - 'example': 'output/', - 'multiple': false - ], - [ - 'name': '--param_list', - 'required': false, - 'type': 'string', - 'description': '''Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob. - | - |* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ ['id': 'foo', 'input': 'foo.txt'], ['id': 'bar', 'input': 'bar.txt'] ]`. - |* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`. - |* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]`. - |* A yaml blob can also be passed directly as a string. Example: `--param_list "[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]"`. - | - |When passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.'''.stripMargin(), - 'example': 'my_params.yaml', - 'multiple': false, - 'hidden': true - ] - // TODO: allow multiple: true in param_list? - // TODO: allow to specify a --param_list_regex to filter the param_list? - // TODO: allow to specify a --param_list_from_state to remap entries in the param_list? - ] - ] - ] - ] - - return processConfig(_mergeMap(config, localConfig)) -} - -def _mergeMap(Map lhs, Map rhs) { - return rhs.inject(lhs.clone()) { map, entry -> - if (map[entry.key] instanceof Map && entry.value instanceof Map) { - map[entry.key] = _mergeMap(map[entry.key], entry.value) - } else if (map[entry.key] instanceof Collection && entry.value instanceof Collection) { - map[entry.key] += entry.value - } else { - map[entry.key] = entry.value - } - return map - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/generateHelp.nf' -def _generateArgumentHelp(param) { - // alternatives are not supported - // def names = param.alternatives ::: List(param.name) - - def unnamedProps = [ - ["required parameter", param.required], - ["multiple values allowed", param.multiple], - ["output", param.direction.toLowerCase() == "output"], - ["file must exist", param.type == "file" && param.must_exist] - ].findAll{it[1]}.collect{it[0]} - - def dflt = null - if (param.default != null) { - if (param.default instanceof List) { - dflt = param.default.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - dflt = param.default.toString() - } - } - def example = null - if (param.example != null) { - if (param.example instanceof List) { - example = param.example.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - example = param.example.toString() - } - } - def min = param.min?.toString() - def max = param.max?.toString() - - def escapeChoice = { choice -> - def s1 = choice.replaceAll("\\n", "\\\\n") - def s2 = s1.replaceAll("\"", """\\\"""") - s2.contains(",") || s2 != choice ? "\"" + s2 + "\"" : s2 - } - def choices = param.choices == null ? - null : - "[ " + param.choices.collect{escapeChoice(it.toString())}.join(", ") + " ]" - - def namedPropsStr = [ - ["type", ([param.type] + unnamedProps).join(", ")], - ["default", dflt], - ["example", example], - ["choices", choices], - ["min", min], - ["max", max] - ] - .findAll{it[1]} - .collect{"\n " + it[0] + ": " + it[1].replaceAll("\n", "\\n")} - .join("") - - def descStr = param.description == null ? - "" : - _paragraphWrap("\n" + param.description.trim(), 80 - 8).join("\n ") - - "\n --" + param.plainName + - namedPropsStr + - descStr -} - -// Based on Helper.generateHelp() in Helper.scala -def _generateHelp(config) { - def fun = config - - // PART 1: NAME AND VERSION - def nameStr = fun.name + - (fun.version == null ? "" : " " + fun.version) - - // PART 2: DESCRIPTION - def descrStr = fun.description == null ? - "" : - "\n\n" + _paragraphWrap(fun.description.trim(), 80).join("\n") - - // PART 3: Usage - def usageStr = fun.usage == null ? - "" : - "\n\nUsage:\n" + fun.usage.trim() - - // PART 4: Options - def argGroupStrs = fun.allArgumentGroups.collect{argGroup -> - def name = argGroup.name - def descriptionStr = argGroup.description == null ? - "" : - "\n " + _paragraphWrap(argGroup.description.trim(), 80-4).join("\n ") + "\n" - def arguments = argGroup.arguments.collect{arg -> - arg instanceof String ? fun.allArguments.find{it.plainName == arg} : arg - }.findAll{it != null} - def argumentStrs = arguments.collect{param -> _generateArgumentHelp(param)} - - "\n\n$name:" + - descriptionStr + - argumentStrs.join("\n") - } - - // FINAL: combine - def out = nameStr + - descrStr + - usageStr + - argGroupStrs.join("") - - return out -} - -// based on Format._paragraphWrap -def _paragraphWrap(str, maxLength) { - def outLines = [] - str.split("\n").each{par -> - def words = par.split("\\s").toList() - - def word = null - def line = words.pop() - while(!words.isEmpty()) { - word = words.pop() - if (line.length() + word.length() + 1 <= maxLength) { - line = line + " " + word - } else { - outLines.add(line) - line = word - } - } - if (words.isEmpty()) { - outLines.add(line) - } - } - return outLines -} - -def helpMessage(config) { - if (params.containsKey("help") && params.help) { - def mergedConfig = addGlobalArguments(config) - def helpStr = _generateHelp(mergedConfig) - println(helpStr) - exit 0 - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/processConfig.nf' -def processConfig(config) { - // set defaults for arguments - config.arguments = - (config.arguments ?: []).collect{_processArgument(it)} - - // set defaults for argument_group arguments - config.argument_groups = - (config.argument_groups ?: []).collect{grp -> - grp.arguments = (grp.arguments ?: []).collect{_processArgument(it)} - grp - } - - // create combined arguments list - config.allArguments = - config.arguments + - config.argument_groups.collectMany{it.arguments} - - // add missing argument groups (based on Functionality::allArgumentGroups()) - def argGroups = config.argument_groups - if (argGroups.any{it.name.toLowerCase() == "arguments"}) { - argGroups = argGroups.collect{ grp -> - if (grp.name.toLowerCase() == "arguments") { - grp = grp + [ - arguments: grp.arguments + config.arguments - ] - } - grp - } - } else { - argGroups = argGroups + [ - name: "Arguments", - arguments: config.arguments - ] - } - config.allArgumentGroups = argGroups - - config -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/readConfig.nf' - -def readConfig(file) { - def config = readYaml(file ?: moduleDir.resolve("config.vsh.yaml")) - processConfig(config) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_resolveSiblingIfNotAbsolute.nf' -/** - * Resolve a path relative to the current file. - * - * @param str The path to resolve, as a String. - * @param parentPath The path to resolve relative to, as a Path. - * - * @return The path that may have been resovled, as a Path. - */ -def _resolveSiblingIfNotAbsolute(str, parentPath) { - if (str !instanceof String) { - return str - } - if (!_stringIsAbsolutePath(str)) { - return parentPath.resolveSibling(str) - } else { - return file(str, hidden: true) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_stringIsAbsolutePath.nf' -/** - * Check whether a path as a string is absolute. - * - * In the past, we tried using `file(., relative: true).isAbsolute()`, - * but the 'relative' option was added in 22.10.0. - * - * @param path The path to check, as a String. - * - * @return Whether the path is absolute, as a boolean. - */ -def _stringIsAbsolutePath(path) { - def _resolve_URL_PROTOCOL = ~/^([a-zA-Z][a-zA-Z0-9]*:)?\\/.+/ - - assert path instanceof String - return _resolve_URL_PROTOCOL.matcher(path).matches() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/collectTraces.nf' -class CustomTraceObserver implements nextflow.trace.TraceObserver { - List traces - - CustomTraceObserver(List traces) { - this.traces = traces - } - - @Override - void onProcessComplete(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } - - @Override - void onProcessCached(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } -} - -def collectTraces() { - def traces = Collections.synchronizedList([]) - - // add custom trace observer which stores traces in the traces object - session.observers.add(new CustomTraceObserver(traces)) - - traces -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/deepClone.nf' -/** - * Performs a deep clone of the given object. - * @param x an object - */ -def deepClone(x) { - iterateMap(x, {it instanceof Cloneable ? it.clone() : it}) -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getPublishDir.nf' -def getPublishDir() { - return params.containsKey("publish_dir") ? params.publish_dir : - params.containsKey("publishDir") ? params.publishDir : - null -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getRootDir.nf' - -// Recurse upwards until we find a '.build.yaml' file -def _findBuildYamlFile(pathPossiblySymlink) { - def path = pathPossiblySymlink.toRealPath() - def child = path.resolve(".build.yaml") - if (java.nio.file.Files.isDirectory(path) && java.nio.file.Files.exists(child)) { - return child - } else { - def parent = path.getParent() - if (parent == null) { - return null - } else { - return _findBuildYamlFile(parent) - } - } -} - -// get the root of the target folder -def getRootDir() { - def dir = _findBuildYamlFile(meta.resources_dir) - assert dir != null: "Could not find .build.yaml in the folder structure" - dir.getParent() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/iterateMap.nf' -/** - * Recursively apply a function over the leaves of an object. - * @param obj The object to iterate over. - * @param fun The function to apply to each value. - * @return The object with the function applied to each value. - */ -def iterateMap(obj, fun) { - if (obj instanceof List && obj !instanceof String) { - return obj.collect{item -> - iterateMap(item, fun) - } - } else if (obj instanceof Map) { - return obj.collectEntries{key, item -> - [key.toString(), iterateMap(item, fun)] - } - } else { - return fun(obj) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/niceView.nf' -/** - * A view for printing the event of each channel as a YAML blob. - * This is useful for debugging. - */ -def niceView() { - workflow niceViewWf { - take: input - main: - output = input - | view{toYamlBlob(it)} - emit: output - } - return niceViewWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readCsv.nf' - -def readCsv(file_path) { - def output = [] - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - - // todo: allow escaped quotes in string - // todo: allow single quotes? - def splitRegex = java.util.regex.Pattern.compile(''',(?=(?:[^"]*"[^"]*")*[^"]*$)''') - def removeQuote = java.util.regex.Pattern.compile('''"(.*)"''') - - def br = java.nio.file.Files.newBufferedReader(inputFile) - - def row = -1 - def header = null - while (br.ready() && header == null) { - def line = br.readLine() - row++ - if (!line.startsWith("#")) { - header = splitRegex.split(line, -1).collect{field -> - m = removeQuote.matcher(field) - m.find() ? m.replaceFirst('$1') : field - } - } - } - assert header != null: "CSV file should contain a header" - - while (br.ready()) { - def line = br.readLine() - row++ - if (line == null) { - br.close() - break - } - - if (!line.startsWith("#")) { - def predata = splitRegex.split(line, -1) - def data = predata.collect{field -> - if (field == "") { - return null - } - def m = removeQuote.matcher(field) - if (m.find()) { - return m.replaceFirst('$1') - } else { - return field - } - } - assert header.size() == data.size(): "Row $row should contain the same number as fields as the header" - - def dataMap = [header, data].transpose().collectEntries().findAll{it.value != null} - output.add(dataMap) - } - } - - output -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJson.nf' -def readJson(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parse(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJsonBlob.nf' -def readJsonBlob(str) { - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parseText(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readTaggedYaml.nf' -// Custom constructor to modify how certain objects are parsed from YAML -class CustomConstructor extends org.yaml.snakeyaml.constructor.Constructor { - Path root - - class ConstructPath extends org.yaml.snakeyaml.constructor.AbstractConstruct { - public Object construct(org.yaml.snakeyaml.nodes.Node node) { - String filename = (String) constructScalar(node); - if (root != null) { - return root.resolve(filename); - } - return java.nio.file.Paths.get(filename); - } - } - - CustomConstructor(org.yaml.snakeyaml.LoaderOptions options, Path root) { - super(options) - this.root = root - // Handling !file tag and parse it back to a File type - this.yamlConstructors.put(new org.yaml.snakeyaml.nodes.Tag("!file"), new ConstructPath()) - } -} - -def readTaggedYaml(Path path) { - def options = new org.yaml.snakeyaml.LoaderOptions() - def constructor = new CustomConstructor(options, path.getParent()) - def yaml = new org.yaml.snakeyaml.Yaml(constructor) - return yaml.load(path.text) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYaml.nf' -def readYaml(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYamlBlob.nf' -def readYamlBlob(str) { - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toJsonBlob.nf' -String toJsonBlob(data) { - return groovy.json.JsonOutput.toJson(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toTaggedYamlBlob.nf' -// Custom representer to modify how certain objects are represented in YAML -class CustomRepresenter extends org.yaml.snakeyaml.representer.Representer { - Path relativizer - - class RepresentPath implements org.yaml.snakeyaml.representer.Represent { - public String getFileName(Object obj) { - if (obj instanceof File) { - obj = ((File) obj).toPath(); - } - if (obj !instanceof Path) { - throw new IllegalArgumentException("Object: " + obj + " is not a Path or File"); - } - def path = (Path) obj; - - if (relativizer != null) { - return relativizer.relativize(path).toString() - } else { - return path.toString() - } - } - - public org.yaml.snakeyaml.nodes.Node representData(Object data) { - String filename = getFileName(data); - def tag = new org.yaml.snakeyaml.nodes.Tag("!file"); - return representScalar(tag, filename); - } - } - CustomRepresenter(org.yaml.snakeyaml.DumperOptions options, Path relativizer) { - super(options) - this.relativizer = relativizer - this.representers.put(sun.nio.fs.UnixPath, new RepresentPath()) - this.representers.put(Path, new RepresentPath()) - this.representers.put(File, new RepresentPath()) - } -} - -String toTaggedYamlBlob(data) { - return toRelativeTaggedYamlBlob(data, null) -} -String toRelativeTaggedYamlBlob(data, Path relativizer) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - def representer = new CustomRepresenter(options, relativizer) - def yaml = new org.yaml.snakeyaml.Yaml(representer, options) - return yaml.dump(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toYamlBlob.nf' -String toYamlBlob(data) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - options.setPrettyFlow(true) - def yaml = new org.yaml.snakeyaml.Yaml(options) - def cleanData = iterateMap(data, { it instanceof Path ? it.toString() : it }) - return yaml.dump(cleanData) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeJson.nf' -void writeJson(data, file) { - assert data: "writeJson: data should not be null" - assert file: "writeJson: file should not be null" - file.write(toJsonBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeYaml.nf' -void writeYaml(data, file) { - assert data: "writeYaml: data should not be null" - assert file: "writeYaml: file should not be null" - file.write(toYamlBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/findStates.nf' -def findStates(Map params, Map config) { - def auto_config = deepClone(config) - def auto_params = deepClone(params) - - auto_config = auto_config.clone() - // override arguments - auto_config.argument_groups = [] - auto_config.arguments = [ - [ - type: "string", - name: "--id", - description: "A dummy identifier", - required: false - ], - [ - type: "file", - name: "--input_states", - example: "/path/to/input/directory/**/state.yaml", - description: "Path to input directory containing the datasets to be integrated.", - required: true, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--filter", - example: "foo/.*/state.yaml", - description: "Regex to filter state files by path.", - required: false - ], - // to do: make this a yaml blob? - [ - type: "string", - name: "--rename_keys", - example: ["newKey1:oldKey1", "newKey2:oldKey2"], - description: "Rename keys in the detected input files. This is useful if the input files do not match the set of input arguments of the workflow.", - required: false, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--settings", - example: '{"output_dataset": "dataset.h5ad", "k": 10}', - description: "Global arguments as a JSON glob to be passed to all components.", - required: false - ] - ] - if (!(auto_params.containsKey("id"))) { - auto_params["id"] = "auto" - } - - // run auto config through processConfig once more - auto_config = processConfig(auto_config) - - workflow findStatesWf { - helpMessage(auto_config) - - output_ch = - channelFromParams(auto_params, auto_config) - | flatMap { autoId, args -> - - def globalSettings = args.settings ? readYamlBlob(args.settings) : [:] - - // look for state files in input dir - def stateFiles = args.input_states - - // filter state files by regex - if (args.filter) { - stateFiles = stateFiles.findAll{ stateFile -> - def stateFileStr = stateFile.toString() - def matcher = stateFileStr =~ args.filter - matcher.matches()} - } - - // read in states - def states = stateFiles.collect { stateFile -> - def state_ = readTaggedYaml(stateFile) - [state_.id, state_] - } - - // construct renameMap - if (args.rename_keys) { - def renameMap = args.rename_keys.collectEntries{renameString -> - def split = renameString.split(";") - assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey,newKey:oldKey'" - split - } - - // rename keys in state, only let states through which have all keys - // also add global settings - states = states.collectMany{id, state -> - def newState = [:] - - for (key in renameMap.keySet()) { - def origKey = renameMap[key] - if (!(state.containsKey(origKey))) { - return [] - } - newState[key] = state[origKey] - } - - [[id, globalSettings + newState]] - } - } - - states - } - emit: - output_ch - } - - return findStatesWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/joinStates.nf' -def joinStates(Closure apply_) { - workflow joinStatesWf { - take: input_ch - main: - output_ch = input_ch - | toSortedList - | filter{ it.size() > 0 } - | map{ tups -> - def ids = tups.collect{it[0]} - def states = tups.collect{it[1]} - apply_(ids, states) - } - - emit: output_ch - } - return joinStatesWf -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/publishStates.nf' -def collectFiles(obj) { - if (obj instanceof java.io.File || obj instanceof Path) { - return [obj] - } else if (obj instanceof List && obj !instanceof String) { - return obj.collectMany{item -> - collectFiles(item) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectFiles(item) - } - } else { - return [] - } -} - -/** - * Recurse through a state and collect all input files and their target output filenames. - * @param obj The state to recurse through. - * @param prefix The prefix to prepend to the output filenames. - */ -def collectInputOutputPaths(obj, prefix) { - if (obj instanceof File || obj instanceof Path) { - def path = obj instanceof Path ? obj : obj.toPath() - def ext = path.getFileName().toString().find("\\.[^\\.]+\$") ?: "" - def newFilename = prefix + ext - return [[obj, newFilename]] - } else if (obj instanceof List && obj !instanceof String) { - return obj.withIndex().collectMany{item, ix -> - collectInputOutputPaths(item, prefix + "_" + ix) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectInputOutputPaths(item, prefix + "." + key) - } - } else { - return [] - } -} - -def publishStates(Map args) { - def key_ = args.get("key") - def yamlTemplate_ = args.get("output_state", args.get("outputState", '$id.$key.state.yaml')) - - assert key_ != null : "publishStates: key must be specified" - - workflow publishStatesWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] - - // the input files and the target output filenames - def inputoutputFilenames_ = collectInputOutputPaths(state_, id_ + "." + key_).transpose() - def inputFiles_ = inputoutputFilenames_[0] - def outputFilenames_ = inputoutputFilenames_[1] - - def yamlFilename = yamlTemplate_ - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - - // TODO: do the pathnames in state_ match up with the outputFilenames_? - - // convert state to yaml blob - def yamlBlob_ = toRelativeTaggedYamlBlob([id: id_] + state_, java.nio.file.Paths.get(yamlFilename)) - - [id_, yamlBlob_, yamlFilename, inputFiles_, outputFilenames_] - } - | publishStatesProc - emit: input_ch - } - return publishStatesWf -} -process publishStatesProc { - // todo: check publishpath? - publishDir path: "${getPublishDir()}/", mode: "copy" - tag "$id" - input: - tuple val(id), val(yamlBlob), val(yamlFile), path(inputFiles, stageAs: "_inputfile?/*"), val(outputFiles) - output: - tuple val(id), path{[yamlFile] + outputFiles} - script: - def copyCommands = [ - inputFiles instanceof List ? inputFiles : [inputFiles], - outputFiles instanceof List ? outputFiles : [outputFiles] - ] - .transpose() - .collectMany{infile, outfile -> - if (infile.toString() != outfile.toString()) { - [ - "[ -d \"\$(dirname '${outfile.toString()}')\" ] || mkdir -p \"\$(dirname '${outfile.toString()}')\"", - "cp -r '${infile.toString()}' '${outfile.toString()}'" - ] - } else { - // no need to copy if infile is the same as outfile - [] - } - } - """ -mkdir -p "\$(dirname '${yamlFile}')" -echo "Storing state as yaml" -echo '${yamlBlob}' > '${yamlFile}' -echo "Copying output files to destination folder" -${copyCommands.join("\n ")} -""" -} - - -// this assumes that the state contains no other values other than those specified in the config -def publishStatesByConfig(Map args) { - def config = args.get("config") - assert config != null : "publishStatesByConfig: config must be specified" - - def key_ = args.get("key", config.name) - assert key_ != null : "publishStatesByConfig: key must be specified" - - workflow publishStatesSimpleWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] // e.g. [output: new File("myoutput.h5ad"), k: 10] - def origState_ = tup[2] // e.g. [output: '$id.$key.foo.h5ad'] - - // TODO: allow overriding the state.yaml template - // TODO TODO: if auto.publish == "state", add output_state as an argument - def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' - def yamlFilename = yamlTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() - - // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where - // - key is a String - // - value is any object that can be serialized to a Yaml (so a String/Integer/Long/Double/Boolean, a List, a Map, or a Path) - // - inputPath is a List[Path] - // - outputFilename is a List[String] - // - (key, value) are the tuples that will be saved to the state.yaml file - // - (inputPath, outputFilename) are the files that will be copied from src to dest (relative to the state.yaml) - def processedState = - config.allArguments - .findAll { it.direction == "output" } - .collectMany { par -> - def plainName_ = par.plainName - // if the state does not contain the key, it's an - // optional argument for which the component did - // not generate any output - if (!state_.containsKey(plainName_)) { - return [] - } - def value = state_[plainName_] - // if the parameter is not a file, it should be stored - // in the state as-is, but is not something that needs - // to be copied from the source path to the dest path - if (par.type != "file") { - return [[key: plainName_, value: value, inputPath: [], outputFilename: []]] - } - // if the orig state does not contain this filename, - // it's an optional argument for which the user specified - // that it should not be returned as a state - if (!origState_.containsKey(plainName_)) { - return [] - } - def filenameTemplate = origState_[plainName_] - // if the pararameter is multiple: true, fetch the template - if (par.multiple && filenameTemplate instanceof List) { - filenameTemplate = filenameTemplate[0] - } - // instantiate the template - def filename = filenameTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - if (par.multiple) { - // if the parameter is multiple: true, the filename - // should contain a wildcard '*' that is replaced with - // the index of the file - assert filename.contains("*") : "Module '${key_}' id '${id_}': Multiple output files specified, but no wildcard '*' in the filename: ${filename}" - def outputPerFile = value.withIndex().collect{ val, ix -> - def filename_ix = filename.replace("*", ix.toString()) - def value_ = java.nio.file.Paths.get(filename_ix) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = val instanceof File ? val.toPath() : val - [value: value_, inputPath: inputPath, outputFilename: filename_ix] - } - def transposedOutputs = ["value", "inputPath", "outputFilename"].collectEntries{ key -> - [key, outputPerFile.collect{dic -> dic[key]}] - } - return [[key: plainName_] + transposedOutputs] - } else { - def value_ = java.nio.file.Paths.get(filename) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = value instanceof File ? value.toPath() : value - return [[key: plainName_, value: value_, inputPath: [inputPath], outputFilename: [filename]]] - } - } - - def updatedState_ = processedState.collectEntries{[it.key, it.value]} - def inputPaths = processedState.collectMany{it.inputPath} - def outputFilenames = processedState.collectMany{it.outputFilename} - - // convert state to yaml blob - def yamlBlob_ = toTaggedYamlBlob([id: id_] + updatedState_) - - [id_, yamlBlob_, yamlFilename, inputPaths, outputFilenames] - } - | publishStatesProc - emit: input_ch - } - return publishStatesSimpleWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/setState.nf' -def setState(fun) { - assert fun instanceof Closure || fun instanceof Map || fun instanceof List : - "Error in setState: Expected process argument to be a Closure, a Map, or a List. Found: class ${fun.getClass()}" - - // if fun is a List, convert to map - if (fun instanceof List) { - // check whether fun is a list[string] - assert fun.every{it instanceof CharSequence} : "Error in setState: argument is a List, but not all elements are Strings" - fun = fun.collectEntries{[it, it]} - } - - // if fun is a map, convert to closure - if (fun instanceof Map) { - // check whether fun is a map[string, string] - assert fun.values().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all values are Strings" - assert fun.keySet().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all keys are Strings" - def funMap = fun.clone() - // turn the map into a closure to be used later on - fun = { id_, state_ -> - assert state_ instanceof Map : "Error in setState: the state is not a Map" - funMap.collectMany{newkey, origkey -> - if (state_.containsKey(origkey)) { - [[newkey, state_[origkey]]] - } else { - [] - } - }.collectEntries() - } - } - - map { tup -> - def id = tup[0] - def state = tup[1] - def unfilteredState = fun(id, state) - def newState = unfilteredState.findAll{key, val -> val != null} - [id, newState] + tup.drop(2) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processAuto.nf' -// TODO: unit test processAuto -def processAuto(Map auto) { - // remove null values - auto = auto.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = ["simplifyInput", "simplifyOutput", "transcript", "publish"] - def unexpectedKeys = auto.keySet() - expectedKeys - assert unexpectedKeys.isEmpty(), "unexpected keys in auto: '${unexpectedKeys.join("', '")}'" - - // check auto.simplifyInput - assert auto.simplifyInput instanceof Boolean, "auto.simplifyInput must be a boolean" - - // check auto.simplifyOutput - assert auto.simplifyOutput instanceof Boolean, "auto.simplifyOutput must be a boolean" - - // check auto.transcript - assert auto.transcript instanceof Boolean, "auto.transcript must be a boolean" - - // check auto.publish - assert auto.publish instanceof Boolean || auto.publish == "state", "auto.publish must be a boolean or 'state'" - - return auto.subMap(expectedKeys) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processDirectives.nf' -def assertMapKeys(map, expectedKeys, requiredKeys, mapName) { - assert map instanceof Map : "Expected argument '$mapName' to be a Map. Found: class ${map.getClass()}" - map.forEach { key, val -> - assert key in expectedKeys : "Unexpected key '$key' in ${mapName ? mapName + " " : ""}map" - } - requiredKeys.forEach { requiredKey -> - assert map.containsKey(requiredKey) : "Missing required key '$key' in ${mapName ? mapName + " " : ""}map" - } -} - -// TODO: unit test processDirectives -def processDirectives(Map drctv) { - // remove null values - drctv = drctv.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = [ - "accelerator", "afterScript", "beforeScript", "cache", "conda", "container", "containerOptions", "cpus", "disk", "echo", "errorStrategy", "executor", "machineType", "maxErrors", "maxForks", "maxRetries", "memory", "module", "penv", "pod", "publishDir", "queue", "label", "scratch", "storeDir", "stageInMode", "stageOutMode", "tag", "time" - ] - def unexpectedKeys = drctv.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Unexpected keys in process directive: '${unexpectedKeys.join("', '")}'" - - /* DIRECTIVE accelerator - accepted examples: - - [ limit: 4, type: "nvidia-tesla-k80" ] - */ - if (drctv.containsKey("accelerator")) { - assertMapKeys(drctv["accelerator"], ["type", "limit", "request", "runtime"], [], "accelerator") - } - - /* DIRECTIVE afterScript - accepted examples: - - "source /cluster/bin/cleanup" - */ - if (drctv.containsKey("afterScript")) { - assert drctv["afterScript"] instanceof CharSequence - } - - /* DIRECTIVE beforeScript - accepted examples: - - "source /cluster/bin/setup" - */ - if (drctv.containsKey("beforeScript")) { - assert drctv["beforeScript"] instanceof CharSequence - } - - /* DIRECTIVE cache - accepted examples: - - true - - false - - "deep" - - "lenient" - */ - if (drctv.containsKey("cache")) { - assert drctv["cache"] instanceof CharSequence || drctv["cache"] instanceof Boolean - if (drctv["cache"] instanceof CharSequence) { - assert drctv["cache"] in ["deep", "lenient"] : "Unexpected value for cache" - } - } - - /* DIRECTIVE conda - accepted examples: - - "bwa=0.7.15" - - "bwa=0.7.15 fastqc=0.11.5" - - ["bwa=0.7.15", "fastqc=0.11.5"] - */ - if (drctv.containsKey("conda")) { - if (drctv["conda"] instanceof List) { - drctv["conda"] = drctv["conda"].join(" ") - } - assert drctv["conda"] instanceof CharSequence - } - - /* DIRECTIVE container - accepted examples: - - "foo/bar:tag" - - [ registry: "reg", image: "im", tag: "ta" ] - is transformed to "reg/im:ta" - - [ image: "im" ] - is transformed to "im:latest" - */ - if (drctv.containsKey("container")) { - assert drctv["container"] instanceof Map || drctv["container"] instanceof CharSequence - if (drctv["container"] instanceof Map) { - def m = drctv["container"] - assertMapKeys(m, [ "registry", "image", "tag" ], ["image"], "container") - def part1 = - System.getenv('OVERRIDE_CONTAINER_REGISTRY') ? System.getenv('OVERRIDE_CONTAINER_REGISTRY') + "/" : - params.containsKey("override_container_registry") ? params["override_container_registry"] + "/" : // todo: remove? - m.registry ? m.registry + "/" : - "" - def part2 = m.image - def part3 = m.tag ? ":" + m.tag : ":latest" - drctv["container"] = part1 + part2 + part3 - } - } - - /* DIRECTIVE containerOptions - accepted examples: - - "--foo bar" - - ["--foo bar", "-f b"] - */ - if (drctv.containsKey("containerOptions")) { - if (drctv["containerOptions"] instanceof List) { - drctv["containerOptions"] = drctv["containerOptions"].join(" ") - } - assert drctv["containerOptions"] instanceof CharSequence - } - - /* DIRECTIVE cpus - accepted examples: - - 1 - - 10 - */ - if (drctv.containsKey("cpus")) { - assert drctv["cpus"] instanceof Integer - } - - /* DIRECTIVE disk - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("disk")) { - assert drctv["disk"] instanceof CharSequence - // assert drctv["disk"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE echo - accepted examples: - - true - - false - */ - if (drctv.containsKey("echo")) { - assert drctv["echo"] instanceof Boolean - } - - /* DIRECTIVE errorStrategy - accepted examples: - - "terminate" - - "finish" - */ - if (drctv.containsKey("errorStrategy")) { - assert drctv["errorStrategy"] instanceof CharSequence - assert drctv["errorStrategy"] in ["terminate", "finish", "ignore", "retry"] : "Unexpected value for errorStrategy" - } - - /* DIRECTIVE executor - accepted examples: - - "local" - - "sge" - */ - if (drctv.containsKey("executor")) { - assert drctv["executor"] instanceof CharSequence - assert drctv["executor"] in ["local", "sge", "uge", "lsf", "slurm", "pbs", "pbspro", "moab", "condor", "nqsii", "ignite", "k8s", "awsbatch", "google-pipelines"] : "Unexpected value for executor" - } - - /* DIRECTIVE machineType - accepted examples: - - "n1-highmem-8" - */ - if (drctv.containsKey("machineType")) { - assert drctv["machineType"] instanceof CharSequence - } - - /* DIRECTIVE maxErrors - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxErrors")) { - assert drctv["maxErrors"] instanceof Integer - } - - /* DIRECTIVE maxForks - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxForks")) { - assert drctv["maxForks"] instanceof Integer - } - - /* DIRECTIVE maxRetries - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxRetries")) { - assert drctv["maxRetries"] instanceof Integer - } - - /* DIRECTIVE memory - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("memory")) { - assert drctv["memory"] instanceof CharSequence - // assert drctv["memory"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE module - accepted examples: - - "ncbi-blast/2.2.27" - - "ncbi-blast/2.2.27:t_coffee/10.0" - - ["ncbi-blast/2.2.27", "t_coffee/10.0"] - */ - if (drctv.containsKey("module")) { - if (drctv["module"] instanceof List) { - drctv["module"] = drctv["module"].join(":") - } - assert drctv["module"] instanceof CharSequence - } - - /* DIRECTIVE penv - accepted examples: - - "smp" - */ - if (drctv.containsKey("penv")) { - assert drctv["penv"] instanceof CharSequence - } - - /* DIRECTIVE pod - accepted examples: - - [ label: "key", value: "val" ] - - [ annotation: "key", value: "val" ] - - [ env: "key", value: "val" ] - - [ [label: "l", value: "v"], [env: "e", value: "v"]] - */ - if (drctv.containsKey("pod")) { - if (drctv["pod"] instanceof Map) { - drctv["pod"] = [ drctv["pod"] ] - } - assert drctv["pod"] instanceof List - drctv["pod"].forEach { pod -> - assert pod instanceof Map - // TODO: should more checks be added? - // See https://www.nextflow.io/docs/latest/process.html?highlight=directives#pod - // e.g. does it contain 'label' and 'value', or 'annotation' and 'value', or ...? - } - } - - /* DIRECTIVE publishDir - accepted examples: - - [] - - [ [ path: "foo", enabled: true ], [ path: "bar", enabled: false ] ] - - "/path/to/dir" - is transformed to [[ path: "/path/to/dir" ]] - - [ path: "/path/to/dir", mode: "cache" ] - is transformed to [[ path: "/path/to/dir", mode: "cache" ]] - */ - // TODO: should we also look at params["publishDir"]? - if (drctv.containsKey("publishDir")) { - def pblsh = drctv["publishDir"] - - // check different options - assert pblsh instanceof List || pblsh instanceof Map || pblsh instanceof CharSequence - - // turn into list if not already so - // for some reason, 'if (!pblsh instanceof List) pblsh = [ pblsh ]' doesn't work. - pblsh = pblsh instanceof List ? pblsh : [ pblsh ] - - // check elements of publishDir - pblsh = pblsh.collect{ elem -> - // turn into map if not already so - elem = elem instanceof CharSequence ? [ path: elem ] : elem - - // check types and keys - assert elem instanceof Map : "Expected publish argument '$elem' to be a String or a Map. Found: class ${elem.getClass()}" - assertMapKeys(elem, [ "path", "mode", "overwrite", "pattern", "saveAs", "enabled" ], ["path"], "publishDir") - - // check elements in map - assert elem.containsKey("path") - assert elem["path"] instanceof CharSequence - if (elem.containsKey("mode")) { - assert elem["mode"] instanceof CharSequence - assert elem["mode"] in [ "symlink", "rellink", "link", "copy", "copyNoFollow", "move" ] - } - if (elem.containsKey("overwrite")) { - assert elem["overwrite"] instanceof Boolean - } - if (elem.containsKey("pattern")) { - assert elem["pattern"] instanceof CharSequence - } - if (elem.containsKey("saveAs")) { - assert elem["saveAs"] instanceof CharSequence //: "saveAs as a Closure is currently not supported. Surround your closure with single quotes to get the desired effect. Example: '\{ foo \}'" - } - if (elem.containsKey("enabled")) { - assert elem["enabled"] instanceof Boolean - } - - // return final result - elem - } - // store final directive - drctv["publishDir"] = pblsh - } - - /* DIRECTIVE queue - accepted examples: - - "long" - - "short,long" - - ["short", "long"] - */ - if (drctv.containsKey("queue")) { - if (drctv["queue"] instanceof List) { - drctv["queue"] = drctv["queue"].join(",") - } - assert drctv["queue"] instanceof CharSequence - } - - /* DIRECTIVE label - accepted examples: - - "big_mem" - - "big_cpu" - - ["big_mem", "big_cpu"] - */ - if (drctv.containsKey("label")) { - if (drctv["label"] instanceof CharSequence) { - drctv["label"] = [ drctv["label"] ] - } - assert drctv["label"] instanceof List - drctv["label"].forEach { label -> - assert label instanceof CharSequence - // assert label.matches("[a-zA-Z0-9]([a-zA-Z0-9_]*[a-zA-Z0-9])?") - // ^ does not allow closures - } - } - - /* DIRECTIVE scratch - accepted examples: - - true - - "/path/to/scratch" - - '$MY_PATH_TO_SCRATCH' - - "ram-disk" - */ - if (drctv.containsKey("scratch")) { - assert drctv["scratch"] == true || drctv["scratch"] instanceof CharSequence - } - - /* DIRECTIVE storeDir - accepted examples: - - "/path/to/storeDir" - */ - if (drctv.containsKey("storeDir")) { - assert drctv["storeDir"] instanceof CharSequence - } - - /* DIRECTIVE stageInMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageInMode")) { - assert drctv["stageInMode"] instanceof CharSequence - assert drctv["stageInMode"] in ["copy", "link", "symlink", "rellink"] - } - - /* DIRECTIVE stageOutMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageOutMode")) { - assert drctv["stageOutMode"] instanceof CharSequence - assert drctv["stageOutMode"] in ["copy", "move", "rsync"] - } - - /* DIRECTIVE tag - accepted examples: - - "foo" - - '$id' - */ - if (drctv.containsKey("tag")) { - assert drctv["tag"] instanceof CharSequence - } - - /* DIRECTIVE time - accepted examples: - - "1h" - - "2days" - - "1day 6hours 3minutes 30seconds" - */ - if (drctv.containsKey("time")) { - assert drctv["time"] instanceof CharSequence - // todo: validation regex? - } - - return drctv -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf' -def processWorkflowArgs(Map args, Map defaultWfArgs, Map meta) { - // override defaults with args - def workflowArgs = defaultWfArgs + args - - // check whether 'key' exists - assert workflowArgs.containsKey("key") : "Error in module '${meta.config.name}': key is a required argument" - - // if 'key' is a closure, apply it to the original key - if (workflowArgs["key"] instanceof Closure) { - workflowArgs["key"] = workflowArgs["key"](meta.config.name) - } - def key = workflowArgs["key"] - assert key instanceof CharSequence : "Expected process argument 'key' to be a String. Found: class ${key.getClass()}" - assert key ==~ /^[a-zA-Z_]\w*$/ : "Error in module '$key': Expected process argument 'key' to consist of only letters, digits or underscores. Found: ${key}" - - // check for any unexpected keys - def expectedKeys = ["key", "directives", "auto", "map", "mapId", "mapData", "mapPassthrough", "filter", "runIf", "fromState", "toState", "args", "renameKeys", "debug"] - def unexpectedKeys = workflowArgs.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Error in module '$key': unexpected arguments to the '.run()' function: '${unexpectedKeys.join("', '")}'" - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("directives") : "Error in module '$key': directives is a required argument" - assert workflowArgs["directives"] instanceof Map : "Error in module '$key': Expected process argument 'directives' to be a Map. Found: class ${workflowArgs['directives'].getClass()}" - workflowArgs["directives"] = processDirectives(defaultWfArgs.directives + workflowArgs["directives"]) - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("auto") : "Error in module '$key': auto is a required argument" - assert workflowArgs["auto"] instanceof Map : "Error in module '$key': Expected process argument 'auto' to be a Map. Found: class ${workflowArgs['auto'].getClass()}" - workflowArgs["auto"] = processAuto(defaultWfArgs.auto + workflowArgs["auto"]) - - // auto define publish, if so desired - if (workflowArgs.auto.publish == true && (workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : [:]).isEmpty()) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.publish is true, params.publish_dir needs to be defined.\n" + - // " Example: params.publish_dir = \"./output/\"" - def publishDir = getPublishDir() - - if (publishDir != null) { - workflowArgs.directives.publishDir = [[ - path: publishDir, - saveAs: "{ it.startsWith('.') ? null : it }", // don't publish hidden files, by default - mode: "copy" - ]] - } - } - - // auto define transcript, if so desired - if (workflowArgs.auto.transcript == true) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("transcriptsDir") || params.containsKey("transcripts_dir") || params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.transcript is true, either params.transcripts_dir or params.publish_dir needs to be defined.\n" + - // " Example: params.transcripts_dir = \"./transcripts/\"" - def transcriptsDir = - params.containsKey("transcripts_dir") ? params.transcripts_dir : - params.containsKey("transcriptsDir") ? params.transcriptsDir : - params.containsKey("publish_dir") ? params.publish_dir + "/_transcripts" : - params.containsKey("publishDir") ? params.publishDir + "/_transcripts" : - null - if (transcriptsDir != null) { - def timestamp = nextflow.Nextflow.getSession().getWorkflowMetadata().start.format('yyyy-MM-dd_HH-mm-ss') - def transcriptsPublishDir = [ - path: "$transcriptsDir/$timestamp/\${task.process.replaceAll(':', '-')}/\${id}/", - saveAs: "{ it.startsWith('.') ? it.replaceAll('^.', '') : null }", - mode: "copy" - ] - def publishDirs = workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : null ? workflowArgs.directives.publishDir : [] - workflowArgs.directives.publishDir = publishDirs + transcriptsPublishDir - } - } - - // if this is a stubrun, remove certain directives? - if (workflow.stubRun) { - workflowArgs.directives.keySet().removeAll(["publishDir", "cpus", "memory", "label"]) - } - - for (nam in ["map", "mapId", "mapData", "mapPassthrough", "filter", "runIf"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam]) { - assert workflowArgs[nam] instanceof Closure : "Error in module '$key': Expected process argument '$nam' to be null or a Closure. Found: class ${workflowArgs[nam].getClass()}" - } - } - - // TODO: should functions like 'map', 'mapId', 'mapData', 'mapPassthrough' be deprecated as well? - for (nam in ["map", "mapData", "mapPassthrough", "renameKeys"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam] != null) { - log.warn "module '$key': workflow argument '$nam' is deprecated and will be removed in Viash 0.9.0. Please use 'fromState' and 'toState' instead." - } - } - - // check fromState - workflowArgs["fromState"] = _processFromState(workflowArgs.get("fromState"), key, meta.config) - - // check toState - workflowArgs["toState"] = _processToState(workflowArgs.get("toState"), key, meta.config) - - // return output - return workflowArgs -} - -def _processFromState(fromState, key_, config_) { - assert fromState == null || fromState instanceof Closure || fromState instanceof Map || fromState instanceof List : - "Error in module '$key_': Expected process argument 'fromState' to be null, a Closure, a Map, or a List. Found: class ${fromState.getClass()}" - if (fromState == null) { - return null - } - - // if fromState is a List, convert to map - if (fromState instanceof List) { - // check whether fromstate is a list[string] - assert fromState.every{it instanceof CharSequence} : "Error in module '$key_': fromState is a List, but not all elements are Strings" - fromState = fromState.collectEntries{[it, it]} - } - - // if fromState is a map, convert to closure - if (fromState instanceof Map) { - // check whether fromstate is a map[string, string] - assert fromState.values().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all values are Strings" - assert fromState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all keys are Strings" - def fromStateMap = fromState.clone() - def requiredInputNames = meta.config.allArguments.findAll{it.required && it.direction == "Input"}.collect{it.plainName} - // turn the map into a closure to be used later on - fromState = { it -> - def state = it[1] - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def data = fromStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (state.containsKey(origkey)) { - [[newkey, state[origkey]]] - } else if (!requiredInputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': fromState key '$origkey' not found in current state") - } - }.collectEntries() - data - } - } - - return fromState -} - -def _processToState(toState, key_, config_) { - if (toState == null) { - toState = { tup -> tup[1] } - } - - // toState should be a closure, map[string, string], or list[string] - assert toState instanceof Closure || toState instanceof Map || toState instanceof List : - "Error in module '$key_': Expected process argument 'toState' to be a Closure, a Map, or a List. Found: class ${toState.getClass()}" - - // if toState is a List, convert to map - if (toState instanceof List) { - // check whether toState is a list[string] - assert toState.every{it instanceof CharSequence} : "Error in module '$key_': toState is a List, but not all elements are Strings" - toState = toState.collectEntries{[it, it]} - } - - // if toState is a map, convert to closure - if (toState instanceof Map) { - // check whether toState is a map[string, string] - assert toState.values().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all values are Strings" - assert toState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all keys are Strings" - def toStateMap = toState.clone() - def requiredOutputNames = config_.allArguments.findAll{it.required && it.direction == "Output"}.collect{it.plainName} - // turn the map into a closure to be used later on - toState = { it -> - def output = it[1] - def state = it[2] - assert output instanceof Map : "Error in module '$key_': the output is not a Map" - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def extraEntries = toStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (output.containsKey(origkey)) { - [[newkey, output[origkey]]] - } else if (!requiredOutputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': toState key '$origkey' not found in current output") - } - }.collectEntries() - state + extraEntries - } - } - - return toState -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/workflowFactory.nf' -def _debug(workflowArgs, debugKey) { - if (workflowArgs.debug) { - view { "process '${workflowArgs.key}' $debugKey tuple: $it" } - } else { - map { it } - } -} - -// depends on: innerWorkflowFactory -def workflowFactory(Map args, Map defaultWfArgs, Map meta) { - def workflowArgs = processWorkflowArgs(args, defaultWfArgs, meta) - def key_ = workflowArgs["key"] - - workflow workflowInstance { - take: input_ - - main: - def chModified = input_ - | checkUniqueIds([:]) - | _debug(workflowArgs, "input") - | map { tuple -> - tuple = deepClone(tuple) - - if (workflowArgs.map) { - tuple = workflowArgs.map(tuple) - } - if (workflowArgs.mapId) { - tuple[0] = workflowArgs.mapId(tuple[0]) - } - if (workflowArgs.mapData) { - tuple[1] = workflowArgs.mapData(tuple[1]) - } - if (workflowArgs.mapPassthrough) { - tuple = tuple.take(2) + workflowArgs.mapPassthrough(tuple.drop(2)) - } - - // check tuple - assert tuple instanceof List : - "Error in module '${key_}': element in channel should be a tuple [id, data, ...otherargs...]\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: List. Found: tuple.getClass() is ${tuple.getClass()}" - assert tuple.size() >= 2 : - "Error in module '${key_}': expected length of tuple in input channel to be two or greater.\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: tuple.size() == ${tuple.size()}" - - // check id field - if (tuple[0] instanceof GString) { - tuple[0] = tuple[0].toString() - } - assert tuple[0] instanceof CharSequence : - "Error in module '${key_}': first element of tuple in channel should be a String\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: ${tuple[0]}" - - // match file to input file - if (workflowArgs.auto.simplifyInput && (tuple[1] instanceof Path || tuple[1] instanceof List)) { - def inputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - - assert inputFiles.size() == 1 : - "Error in module '${key_}' id '${tuple[0]}'.\n" + - " Anonymous file inputs are only allowed when the process has exactly one file input.\n" + - " Expected: inputFiles.size() == 1. Found: inputFiles.size() is ${inputFiles.size()}" - - tuple[1] = [[ inputFiles[0].plainName, tuple[1] ]].collectEntries() - } - - // check data field - assert tuple[1] instanceof Map : - "Error in module '${key_}' id '${tuple[0]}': second element of tuple in channel should be a Map\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // rename keys of data field in tuple - if (workflowArgs.renameKeys) { - assert workflowArgs.renameKeys instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class: Map. Found: renameKeys.getClass() is ${workflowArgs.renameKeys.getClass()}" - assert tuple[1] instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // TODO: allow renameKeys to be a function? - workflowArgs.renameKeys.each { newKey, oldKey -> - assert newKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of newKey: String. Found: newKey.getClass() is ${newKey.getClass()}" - assert oldKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of oldKey: String. Found: oldKey.getClass() is ${oldKey.getClass()}" - assert tuple[1].containsKey(oldKey) : - "Error renaming data keys in module '${key}' id '${tuple[0]}'.\n" + - " Key '$oldKey' is missing in the data map. tuple[1].keySet() is '${tuple[1].keySet()}'" - tuple[1].put(newKey, tuple[1][oldKey]) - } - tuple[1].keySet().removeAll(workflowArgs.renameKeys.collect{ newKey, oldKey -> oldKey }) - } - tuple - } - - def chModifiedFiltered = workflowArgs.filter ? - chModified | filter{workflowArgs.filter(it)} : - chModified - - def chRun = null - def chPassthrough = null - if (workflowArgs.runIf) { - def runIfBranch = chModifiedFiltered.branch{ tup -> - run: workflowArgs.runIf(tup[0], tup[1]) - passthrough: true - } - chRun = runIfBranch.run - chPassthrough = runIfBranch.passthrough - } else { - chRun = chModifiedFiltered - chPassthrough = Channel.empty() - } - - def chArgs = workflowArgs.fromState ? - chRun | map{ - def new_data = workflowArgs.fromState(it.take(2)) - [it[0], new_data] - } : - chRun | map {tup -> tup.take(2)} - - // fill in defaults - def chArgsWithDefaults = chArgs - | map { tuple -> - def id_ = tuple[0] - def data_ = tuple[1] - - // TODO: could move fromState to here - - // fetch default params from functionality - def defaultArgs = meta.config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - // fetch overrides in params - def paramArgs = meta.config.allArguments - .findAll { par -> - def argKey = key_ + "__" + par.plainName - params.containsKey(argKey) - } - .collectEntries { [ it.plainName, params[key_ + "__" + it.plainName] ] } - - // fetch overrides in data - def dataArgs = meta.config.allArguments - .findAll { data_.containsKey(it.plainName) } - .collectEntries { [ it.plainName, data_[it.plainName] ] } - - // combine params - def combinedArgs = defaultArgs + paramArgs + workflowArgs.args + dataArgs - - // remove arguments with explicit null values - combinedArgs - .removeAll{_, val -> val == null || val == "viash_no_value" || val == "force_null"} - - combinedArgs = _processInputValues(combinedArgs, meta.config, id_, key_) - - [id_, combinedArgs] + tuple.drop(2) - } - - // TODO: move some of the _meta.join_id wrangling to the safeJoin() function. - def chInitialOutput = chArgsWithDefaults - | _debug(workflowArgs, "processed") - // run workflow - | innerWorkflowFactory(workflowArgs) - // check output tuple - | map { id_, output_ -> - - // see if output map contains metadata - def meta_ = - output_ instanceof Map && output_.containsKey("_meta") ? - output_["_meta"] : - [:] - def join_id = meta_.join_id ?: id_ - - // remove metadata - output_ = output_.findAll{k, v -> k != "_meta"} - - // check value types - output_ = _processOutputValues(output_, meta.config, id_, key_) - - // simplify output if need be - if (workflowArgs.auto.simplifyOutput && output_.size() == 1) { - output_ = output_.values()[0] - } - - [join_id, id_, output_] - } - // | view{"chInitialOutput: ${it.take(3)}"} - - // join the output [prev_id, new_id, output] with the previous state [prev_id, state, ...] - def chNewState = safeJoin(chInitialOutput, chModifiedFiltered, key_) - // input tuple format: [join_id, id, output, prev_state, ...] - // output tuple format: [join_id, id, new_state, ...] - | map{ tup -> - def new_state = workflowArgs.toState(tup.drop(1).take(3)) - tup.take(2) + [new_state] + tup.drop(4) - } - - if (workflowArgs.auto.publish == "state") { - def chPublish = chNewState - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [join_id, id, new_state] - | map{ tup -> - tup.take(3) - } - - safeJoin(chPublish, chArgsWithDefaults, key_) - // input tuple format: [join_id, id, new_state, orig_state, ...] - // output tuple format: [id, new_state, orig_state] - | map { tup -> - tup.drop(1).take(3) - } - | publishStatesByConfig(key: key_, config: meta.config) - } - - // remove join_id and meta - chReturn = chNewState - | map { tup -> - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [id, new_state, ...] - tup.drop(1) - } - | _debug(workflowArgs, "output") - | concat(chPassthrough) - - emit: chReturn - } - - def wf = workflowInstance.cloneWithName(key_) - - // add factory function - wf.metaClass.run = { runArgs -> - workflowFactory(runArgs, workflowArgs, meta) - } - // add config to module for later introspection - wf.metaClass.config = meta.config - - return wf -} - -nextflow.enable.dsl=2 - -// START COMPONENT-SPECIFIC CODE - -// create meta object -meta = [ - "resources_dir": moduleDir.toRealPath().normalize(), - "config": processConfig(readJsonBlob('''{ - "name" : "samtools_idxstats", - "namespace" : "samtools", - "version" : "v0.1.0", - "argument_groups" : [ - { - "name" : "Inputs", - "arguments" : [ - { - "type" : "file", - "name" : "--bam", - "description" : "BAM input file.", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--bai", - "description" : "BAM index file.", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--fasta", - "description" : "Reference file the CRAM was created with (optional).", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Outputs", - "arguments" : [ - { - "type" : "file", - "name" : "--output", - "description" : "File containing samtools stats output in tab-delimited format.\n", - "example" : [ - "output.idxstats" - ], - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "output", - "multiple" : false, - "multiple_sep" : ";" - } - ] - } - ], - "resources" : [ - { - "type" : "bash_script", - "path" : "script.sh", - "is_executable" : true - } - ], - "description" : "Reports alignment summary statistics for a BAM file.", - "test_resources" : [ - { - "type" : "bash_script", - "path" : "test.sh", - "is_executable" : true - }, - { - "type" : "file", - "path" : "test_data" - } - ], - "status" : "enabled", - "requirements" : { - "commands" : [ - "ps" - ] - }, - "keywords" : [ - "stats", - "mapping", - "counts", - "chromosome", - "bam", - "sam", - "cram" - ], - "license" : "MIT/Expat", - "references" : { - "doi" : [ - "10.1093/bioinformatics/btp352", - "10.1093/gigascience/giab008" - ] - }, - "links" : { - "repository" : "https://github.com/samtools/samtools", - "homepage" : "https://www.htslib.org/", - "documentation" : "https://www.htslib.org/doc/samtools-idxstats.html" - }, - "runners" : [ - { - "type" : "executable", - "id" : "executable", - "docker_setup_strategy" : "ifneedbepullelsecachedbuild" - }, - { - "type" : "nextflow", - "id" : "nextflow", - "directives" : { - "tag" : "$id" - }, - "auto" : { - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false - }, - "config" : { - "labels" : { - "mem1gb" : "memory = 1000000000.B", - "mem2gb" : "memory = 2000000000.B", - "mem5gb" : "memory = 5000000000.B", - "mem10gb" : "memory = 10000000000.B", - "mem20gb" : "memory = 20000000000.B", - "mem50gb" : "memory = 50000000000.B", - "mem100gb" : "memory = 100000000000.B", - "mem200gb" : "memory = 200000000000.B", - "mem500gb" : "memory = 500000000000.B", - "mem1tb" : "memory = 1000000000000.B", - "mem2tb" : "memory = 2000000000000.B", - "mem5tb" : "memory = 5000000000000.B", - "mem10tb" : "memory = 10000000000000.B", - "mem20tb" : "memory = 20000000000000.B", - "mem50tb" : "memory = 50000000000000.B", - "mem100tb" : "memory = 100000000000000.B", - "mem200tb" : "memory = 200000000000000.B", - "mem500tb" : "memory = 500000000000000.B", - "mem1gib" : "memory = 1073741824.B", - "mem2gib" : "memory = 2147483648.B", - "mem4gib" : "memory = 4294967296.B", - "mem8gib" : "memory = 8589934592.B", - "mem16gib" : "memory = 17179869184.B", - "mem32gib" : "memory = 34359738368.B", - "mem64gib" : "memory = 68719476736.B", - "mem128gib" : "memory = 137438953472.B", - "mem256gib" : "memory = 274877906944.B", - "mem512gib" : "memory = 549755813888.B", - "mem1tib" : "memory = 1099511627776.B", - "mem2tib" : "memory = 2199023255552.B", - "mem4tib" : "memory = 4398046511104.B", - "mem8tib" : "memory = 8796093022208.B", - "mem16tib" : "memory = 17592186044416.B", - "mem32tib" : "memory = 35184372088832.B", - "mem64tib" : "memory = 70368744177664.B", - "mem128tib" : "memory = 140737488355328.B", - "mem256tib" : "memory = 281474976710656.B", - "mem512tib" : "memory = 562949953421312.B", - "cpu1" : "cpus = 1", - "cpu2" : "cpus = 2", - "cpu5" : "cpus = 5", - "cpu10" : "cpus = 10", - "cpu20" : "cpus = 20", - "cpu50" : "cpus = 50", - "cpu100" : "cpus = 100", - "cpu200" : "cpus = 200", - "cpu500" : "cpus = 500", - "cpu1000" : "cpus = 1000" - } - }, - "debug" : false, - "container" : "docker" - } - ], - "engines" : [ - { - "type" : "docker", - "id" : "docker", - "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", - "target_registry" : "images.viash-hub.com", - "target_tag" : "v0.1.0", - "namespace_separator" : "/", - "setup" : [ - { - "type" : "docker", - "run" : [ - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\\\nsed 's#Using ##;s# \\\\([0-9\\\\.]*\\\\)$#: \\\\1#' > /var/software_versions.txt\n" - ] - } - ] - }, - { - "type" : "native", - "id" : "native" - } - ], - "build_info" : { - "config" : "/workdir/root/repo/src/samtools/samtools_idxstats/config.vsh.yaml", - "runner" : "nextflow", - "engine" : "docker|native", - "output" : "target/nextflow/samtools/samtools_idxstats", - "viash_version" : "0.9.0-RC6", - "git_commit" : "b84b29747d0635f2ac83ea63b496be9a9edb6724", - "git_remote" : "https://github.com/viash-hub/biobox" - }, - "package_config" : { - "name" : "biobox", - "version" : "v0.1.0", - "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC6", - "source" : "src", - "target" : "target", - "config_mods" : [ - ".requirements.commands := ['ps']\n", - ".engines += { type: \\"native\\" }", - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - ], - "keywords" : [ - "bioinformatics", - "modules", - "sequencing" - ], - "license" : "MIT", - "organization" : "vsh", - "links" : { - "repository" : "https://github.com/viash-hub/biobox", - "issue_tracker" : "https://github.com/viash-hub/biobox/issues" - } - } -}''')) -] - -// resolve dependencies dependencies (if any) - - -// inner workflow -// inner workflow hook -def innerWorkflowFactory(args) { - def rawScript = '''set -e -tempscript=".viash_script.sh" -cat > "$tempscript" << VIASHMAIN -#!/bin/bash - -## VIASH START -# The following code has been auto-generated by Viash. -$( if [ ! -z ${VIASH_PAR_BAM+x} ]; then echo "${VIASH_PAR_BAM}" | sed "s#'#'\\"'\\"'#g;s#.*#par_bam='&'#" ; else echo "# par_bam="; fi ) -$( if [ ! -z ${VIASH_PAR_BAI+x} ]; then echo "${VIASH_PAR_BAI}" | sed "s#'#'\\"'\\"'#g;s#.*#par_bai='&'#" ; else echo "# par_bai="; fi ) -$( if [ ! -z ${VIASH_PAR_FASTA+x} ]; then echo "${VIASH_PAR_FASTA}" | sed "s#'#'\\"'\\"'#g;s#.*#par_fasta='&'#" ; else echo "# par_fasta="; fi ) -$( if [ ! -z ${VIASH_PAR_OUTPUT+x} ]; then echo "${VIASH_PAR_OUTPUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_output='&'#" ; else echo "# par_output="; fi ) -$( if [ ! -z ${VIASH_META_NAME+x} ]; then echo "${VIASH_META_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_name='&'#" ; else echo "# meta_name="; fi ) -$( if [ ! -z ${VIASH_META_FUNCTIONALITY_NAME+x} ]; then echo "${VIASH_META_FUNCTIONALITY_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_functionality_name='&'#" ; else echo "# meta_functionality_name="; fi ) -$( if [ ! -z ${VIASH_META_RESOURCES_DIR+x} ]; then echo "${VIASH_META_RESOURCES_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_resources_dir='&'#" ; else echo "# meta_resources_dir="; fi ) -$( if [ ! -z ${VIASH_META_EXECUTABLE+x} ]; then echo "${VIASH_META_EXECUTABLE}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_executable='&'#" ; else echo "# meta_executable="; fi ) -$( if [ ! -z ${VIASH_META_CONFIG+x} ]; then echo "${VIASH_META_CONFIG}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_config='&'#" ; else echo "# meta_config="; fi ) -$( if [ ! -z ${VIASH_META_TEMP_DIR+x} ]; then echo "${VIASH_META_TEMP_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_temp_dir='&'#" ; else echo "# meta_temp_dir="; fi ) -$( if [ ! -z ${VIASH_META_CPUS+x} ]; then echo "${VIASH_META_CPUS}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_cpus='&'#" ; else echo "# meta_cpus="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_B+x} ]; then echo "${VIASH_META_MEMORY_B}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_b='&'#" ; else echo "# meta_memory_b="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KB+x} ]; then echo "${VIASH_META_MEMORY_KB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kb='&'#" ; else echo "# meta_memory_kb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MB+x} ]; then echo "${VIASH_META_MEMORY_MB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mb='&'#" ; else echo "# meta_memory_mb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GB+x} ]; then echo "${VIASH_META_MEMORY_GB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gb='&'#" ; else echo "# meta_memory_gb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TB+x} ]; then echo "${VIASH_META_MEMORY_TB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tb='&'#" ; else echo "# meta_memory_tb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PB+x} ]; then echo "${VIASH_META_MEMORY_PB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pb='&'#" ; else echo "# meta_memory_pb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KIB+x} ]; then echo "${VIASH_META_MEMORY_KIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kib='&'#" ; else echo "# meta_memory_kib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MIB+x} ]; then echo "${VIASH_META_MEMORY_MIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mib='&'#" ; else echo "# meta_memory_mib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GIB+x} ]; then echo "${VIASH_META_MEMORY_GIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gib='&'#" ; else echo "# meta_memory_gib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TIB+x} ]; then echo "${VIASH_META_MEMORY_TIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tib='&'#" ; else echo "# meta_memory_tib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PIB+x} ]; then echo "${VIASH_META_MEMORY_PIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pib='&'#" ; else echo "# meta_memory_pib="; fi ) - -## VIASH END - -set -e - -samtools idxstats "\\$par_bam" > "\\$par_output" -VIASHMAIN -bash "$tempscript" -''' - - return vdsl3WorkflowFactory(args, meta, rawScript) -} - - - -/** - * Generate a workflow for VDSL3 modules. - * - * This function is called by the workflowFactory() function. - * - * Input channel: [id, input_map] - * Output channel: [id, output_map] - * - * Internally, this workflow will convert the input channel - * to a format which the Nextflow module will be able to handle. - */ -def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { - def key = args["key"] - def processObj = null - - workflow processWf { - take: input_ - main: - - if (processObj == null) { - processObj = _vdsl3ProcessFactory(args, meta, rawScript) - } - - output_ = input_ - | map { tuple -> - def id = tuple[0] - def data_ = tuple[1] - - if (workflow.stubRun) { - // add id if missing - data_ = [id: 'stub'] + data_ - } - - // process input files separately - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { par -> - def val = data_.containsKey(par.plainName) ? data_[par.plainName] : [] - def inputFiles = [] - if (val == null) { - inputFiles = [] - } else if (val instanceof List) { - inputFiles = val - } else if (val instanceof Path) { - inputFiles = [ val ] - } else { - inputFiles = [] - } - if (!workflow.stubRun) { - // throw error when an input file doesn't exist - inputFiles.each{ file -> - assert file.exists() : - "Error in module '${key}' id '${id}' argument '${par.plainName}'.\n" + - " Required input file does not exist.\n" + - " Path: '$file'.\n" + - " Expected input file to exist" - } - } - inputFiles - } - - // remove input files - def argsExclInputFiles = meta.config.allArguments - .findAll { (it.type != "file" || it.direction != "input") && data_.containsKey(it.plainName) } - .collectEntries { par -> - def parName = par.plainName - def val = data_[parName] - if (par.multiple && val instanceof Collection) { - val = val.join(par.multiple_sep) - } - if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) - } - [parName, val] - } - - [ id ] + inputPaths + [ argsExclInputFiles, meta.resources_dir ] - } - | processObj - | map { output -> - def outputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .indexed() - .collectEntries{ index, par -> - def out = output[index + 1] - // strip dummy '.exitcode' file from output (see nextflow-io/nextflow#2678) - if (!out instanceof List || out.size() <= 1) { - if (par.multiple) { - out = [] - } else { - assert !par.required : - "Error in module '${key}' id '${output[0]}' argument '${par.plainName}'.\n" + - " Required output file is missing" - out = null - } - } else if (out.size() == 2 && !par.multiple) { - out = out[1] - } else { - out = out.drop(1) - } - [ par.plainName, out ] - } - - // drop null outputs - outputFiles.removeAll{it.value == null} - - [ output[0], outputFiles ] - } - emit: output_ - } - - return processWf -} - -// depends on: session? -def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { - // autodetect process key - def wfKey = workflowArgs["key"] - def procKeyPrefix = "${wfKey}_process" - def scriptMeta = nextflow.script.ScriptMeta.current() - def existing = scriptMeta.getProcessNames().findAll{it.startsWith(procKeyPrefix)} - def numbers = existing.collect{it.replace(procKeyPrefix, "0").toInteger()} - def newNumber = (numbers + [-1]).max() + 1 - - def procKey = newNumber == 0 ? procKeyPrefix : "$procKeyPrefix$newNumber" - - if (newNumber > 0) { - log.warn "Key for module '${wfKey}' is duplicated.\n", - "If you run a component multiple times in the same workflow,\n" + - "it's recommended you set a unique key for every call,\n" + - "for example: ${wfKey}.run(key: \"foo\")." - } - - // subset directives and convert to list of tuples - def drctv = workflowArgs.directives - - // TODO: unit test the two commands below - // convert publish array into tags - def valueToStr = { val -> - // ignore closures - if (val instanceof CharSequence) { - if (!val.matches('^[{].*[}]$')) { - '"' + val + '"' - } else { - val - } - } else if (val instanceof List) { - "[" + val.collect{valueToStr(it)}.join(", ") + "]" - } else if (val instanceof Map) { - "[" + val.collect{k, v -> k + ": " + valueToStr(v)}.join(", ") + "]" - } else { - val.inspect() - } - } - - // multiple entries allowed: label, publishdir - def drctvStrs = drctv.collect { key, value -> - if (key in ["label", "publishDir"]) { - value.collect{ val -> - if (val instanceof Map) { - "\n$key " + val.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else if (val == null) { - "" - } else { - "\n$key " + valueToStr(val) - } - }.join() - } else if (value instanceof Map) { - "\n$key " + value.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else { - "\n$key " + valueToStr(value) - } - }.join() - - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { ', path(viash_par_' + it.plainName + ', stageAs: "_viash_par/' + it.plainName + '_?/*")' } - .join() - - def outputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - // insert dummy into every output (see nextflow-io/nextflow#2678) - if (!par.multiple) { - ', path{[".exitcode", args.' + par.plainName + ']}' - } else { - ', path{[".exitcode"] + args.' + par.plainName + '}' - } - } - .join() - - // TODO: move this functionality somewhere else? - if (workflowArgs.auto.transcript) { - outputPaths = outputPaths + ', path{[".exitcode", ".command*"]}' - } else { - outputPaths = outputPaths + ', path{[".exitcode"]}' - } - - // create dirs for output files (based on BashWrapper.createParentFiles) - def createParentStr = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" && it.create_parent } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // construct inputFileExports - def inputFileExports = meta.config.allArguments - .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } - .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" - } - - // NOTE: if using docker, use /tmp instead of tmpDir! - def tmpDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('VIASH_TMPDIR') ?: - System.getenv('VIASH_TEMPDIR') ?: - System.getenv('VIASH_TMP') ?: - System.getenv('TEMP') ?: - System.getenv('TMPDIR') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMP') ?: - '/tmp' - ).toAbsolutePath() - - // construct stub - def stub = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"touch2 \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"].replace(\"_*\", \"_0\") : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // escape script - def escapedScript = rawScript.replace('\\', '\\\\').replace('$', '\\$').replace('"""', '\\"\\"\\"') - - // publishdir assert - def assertStr = (workflowArgs.auto.publish == true) || workflowArgs.auto.transcript ? - """\nassert task.publishDir.size() > 0: "if auto.publish is true, params.publish_dir needs to be defined.\\n Example: --publish_dir './output/'" """ : - "" - - // generate process string - def procStr = - """nextflow.enable.dsl=2 - | - |process $procKey {$drctvStrs - |input: - | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") - |output: - | tuple val("\$id")$outputPaths, optional: true - |stub: - |\"\"\" - |touch2() { mkdir -p "\\\$(dirname "\\\$1")" && touch "\\\$1" ; } - |$stub - |\"\"\" - |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } - |def parInject = args - | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} - | .join("\\n") - |\"\"\" - |# meta exports - |export VIASH_META_RESOURCES_DIR="\${resourcesDir}" - |export VIASH_META_TEMP_DIR="${['docker', 'podman', 'charliecloud'].any{ it == workflow.containerEngine } ? '/tmp' : tmpDir}" - |export VIASH_META_NAME="${meta.config.name}" - |# export VIASH_META_EXECUTABLE="\\\$VIASH_META_RESOURCES_DIR/\\\$VIASH_META_NAME" - |export VIASH_META_CONFIG="\\\$VIASH_META_RESOURCES_DIR/.config.vsh.yaml" - |\${task.cpus ? "export VIASH_META_CPUS=\$task.cpus" : "" } - |\${task.memory?.bytes != null ? "export VIASH_META_MEMORY_B=\$task.memory.bytes" : "" } - |if [ ! -z \\\${VIASH_META_MEMORY_B+x} ]; then - | export VIASH_META_MEMORY_KB=\\\$(( (\\\$VIASH_META_MEMORY_B+999) / 1000 )) - | export VIASH_META_MEMORY_MB=\\\$(( (\\\$VIASH_META_MEMORY_KB+999) / 1000 )) - | export VIASH_META_MEMORY_GB=\\\$(( (\\\$VIASH_META_MEMORY_MB+999) / 1000 )) - | export VIASH_META_MEMORY_TB=\\\$(( (\\\$VIASH_META_MEMORY_GB+999) / 1000 )) - | export VIASH_META_MEMORY_PB=\\\$(( (\\\$VIASH_META_MEMORY_TB+999) / 1000 )) - | export VIASH_META_MEMORY_KIB=\\\$(( (\\\$VIASH_META_MEMORY_B+1023) / 1024 )) - | export VIASH_META_MEMORY_MIB=\\\$(( (\\\$VIASH_META_MEMORY_KIB+1023) / 1024 )) - | export VIASH_META_MEMORY_GIB=\\\$(( (\\\$VIASH_META_MEMORY_MIB+1023) / 1024 )) - | export VIASH_META_MEMORY_TIB=\\\$(( (\\\$VIASH_META_MEMORY_GIB+1023) / 1024 )) - | export VIASH_META_MEMORY_PIB=\\\$(( (\\\$VIASH_META_MEMORY_TIB+1023) / 1024 )) - |fi - | - |# meta synonyms - |export VIASH_TEMP="\\\$VIASH_META_TEMP_DIR" - |export TEMP_DIR="\\\$VIASH_META_TEMP_DIR" - | - |# create output dirs if need be - |function mkdir_parent { - | for file in "\\\$@"; do - | mkdir -p "\\\$(dirname "\\\$file")" - | done - |} - |$createParentStr - | - |# argument exports${inputFileExports.join()} - |\$parInject - | - |# process script - |${escapedScript} - |\"\"\" - |} - |""".stripMargin() - - // TODO: print on debug - // if (workflowArgs.debug == true) { - // println("######################\n$procStr\n######################") - // } - - // write process to temp file - def tempFile = java.nio.file.Files.createTempFile("viash-process-${procKey}-", ".nf") - addShutdownHook { java.nio.file.Files.deleteIfExists(tempFile) } - tempFile.text = procStr - - // create process from temp file - def binding = new nextflow.script.ScriptBinding([:]) - def session = nextflow.Nextflow.getSession() - def parser = new nextflow.script.ScriptParser(session) - .setModule(true) - .setBinding(binding) - def moduleScript = parser.runScript(tempFile) - .getScript() - - // register module in meta - def module = new nextflow.script.IncludeDef.Module(name: procKey) - scriptMeta.addModule(moduleScript, module.name, module.alias) - - // retrieve and return process from meta - return scriptMeta.getProcess(procKey) -} - -// defaults -meta["defaults"] = [ - // key to be used to trace the process and determine output names - key: null, - - // fixed arguments to be passed to script - args: [:], - - // default directives - directives: readJsonBlob('''{ - "container" : { - "registry" : "images.viash-hub.com", - "image" : "vsh/biobox/samtools/samtools_idxstats", - "tag" : "v0.1.0" - }, - "tag" : "$id" -}'''), - - // auto settings - auto: readJsonBlob('''{ - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false -}'''), - - // Apply a map over the incoming tuple - // Example: `{ tup -> [ tup[0], [input: tup[1].output] ] + tup.drop(2) }` - map: null, - - // Apply a map over the ID element of a tuple (i.e. the first element) - // Example: `{ id -> id + "_foo" }` - mapId: null, - - // Apply a map over the data element of a tuple (i.e. the second element) - // Example: `{ data -> [ input: data.output ] }` - mapData: null, - - // Apply a map over the passthrough elements of a tuple (i.e. the tuple excl. the first two elements) - // Example: `{ pt -> pt.drop(1) }` - mapPassthrough: null, - - // Filter the channel - // Example: `{ tup -> tup[0] == "foo" }` - filter: null, - - // Choose whether or not to run the component on the tuple if the condition is true. - // Otherwise, the tuple will be passed through. - // Example: `{ tup -> tup[0] != "skip_this" }` - runIf: null, - - // Rename keys in the data field of the tuple (i.e. the second element) - // Will likely be deprecated in favour of `fromState`. - // Example: `[ "new_key": "old_key" ]` - renameKeys: null, - - // Fetch data from the state and pass it to the module without altering the current state. - // - // `fromState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be passed to the module as is. - // - If it is a `List[String]`, the data will be the values of the state at the given keys. - // - If it is a `Map[String, String]`, the data will be the values of the state at the given keys, with the keys renamed according to the map. - // - If it is a function, the tuple (`[id, state]`) in the channel will be passed to the function, and the result will be used as the data. - // - // Example: `{ id, state -> [input: state.fastq_file] }` - // Default: `null` - fromState: null, - - // Determine how the state should be updated after the module has been run. - // - // `toState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be replaced with the output of the module. - // - If it is a `List[String]`, the state will be updated with the values of the data at the given keys. - // - If it is a `Map[String, String]`, the state will be updated with the values of the data at the given keys, with the keys renamed according to the map. - // - If it is a function, a tuple (`[id, output, state]`) will be passed to the function, and the result will be used as the new state. - // - // Example: `{ id, output, state -> state + [counts: state.output] }` - // Default: `{ id, output, state -> output }` - toState: null, - - // Whether or not to print debug messages - // Default: `false` - debug: false -] - -// initialise default workflow -meta["workflow"] = workflowFactory([key: meta.config.name], meta.defaults, meta) - -// add workflow to environment -nextflow.script.ScriptMeta.current().addDefinition(meta.workflow) - -// anonymous workflow for running this module as a standalone -workflow { - // add id argument if it's not already in the config - // TODO: deep copy - def newConfig = deepClone(meta.config) - def newParams = deepClone(params) - - def argsContainsId = newConfig.allArguments.any{it.plainName == "id"} - if (!argsContainsId) { - def idArg = [ - 'name': '--id', - 'required': false, - 'type': 'string', - 'description': 'A unique id for every entry.', - 'multiple': false - ] - newConfig.arguments.add(0, idArg) - newConfig = processConfig(newConfig) - } - if (!newParams.containsKey("id")) { - newParams.id = "run" - } - - helpMessage(newConfig) - - channelFromParams(newParams, newConfig) - // make sure id is not in the state if id is not in the args - | map {id, state -> - if (!argsContainsId) { - [id, state.findAll{k, v -> k != "id"}] - } else { - [id, state] - } - } - | meta.workflow.run( - auto: [ publish: "state" ] - ) -} - -// END COMPONENT-SPECIFIC CODE diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/nextflow.config deleted file mode 100644 index 94bbecb..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/nextflow.config +++ /dev/null @@ -1,125 +0,0 @@ -manifest { - name = 'samtools/samtools_idxstats' - mainScript = 'main.nf' - nextflowVersion = '!>=20.12.1-edge' - version = 'v0.1.0' - description = 'Reports alignment summary statistics for a BAM file.' -} - -process.container = 'nextflow/bash:latest' - -// detect tempdir -tempDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMPDIR') ?: - '/tmp' -).toAbsolutePath() - -profiles { - no_publish { - process { - withName: '.*' { - publishDir = [ - enabled: false - ] - } - } - } - mount_temp { - docker.temp = tempDir - podman.temp = tempDir - charliecloud.temp = tempDir - } - docker { - docker.enabled = true - // docker.userEmulation = true - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - singularity { - singularity.enabled = true - singularity.autoMounts = true - docker.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - podman { - podman.enabled = true - docker.enabled = false - singularity.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - shifter { - shifter.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - charliecloud.enabled = false - } - charliecloud { - charliecloud.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - } -} - -process{ - withLabel: mem1gb { memory = 1000000000.B } - withLabel: mem2gb { memory = 2000000000.B } - withLabel: mem5gb { memory = 5000000000.B } - withLabel: mem10gb { memory = 10000000000.B } - withLabel: mem20gb { memory = 20000000000.B } - withLabel: mem50gb { memory = 50000000000.B } - withLabel: mem100gb { memory = 100000000000.B } - withLabel: mem200gb { memory = 200000000000.B } - withLabel: mem500gb { memory = 500000000000.B } - withLabel: mem1tb { memory = 1000000000000.B } - withLabel: mem2tb { memory = 2000000000000.B } - withLabel: mem5tb { memory = 5000000000000.B } - withLabel: mem10tb { memory = 10000000000000.B } - withLabel: mem20tb { memory = 20000000000000.B } - withLabel: mem50tb { memory = 50000000000000.B } - withLabel: mem100tb { memory = 100000000000000.B } - withLabel: mem200tb { memory = 200000000000000.B } - withLabel: mem500tb { memory = 500000000000000.B } - withLabel: mem1gib { memory = 1073741824.B } - withLabel: mem2gib { memory = 2147483648.B } - withLabel: mem4gib { memory = 4294967296.B } - withLabel: mem8gib { memory = 8589934592.B } - withLabel: mem16gib { memory = 17179869184.B } - withLabel: mem32gib { memory = 34359738368.B } - withLabel: mem64gib { memory = 68719476736.B } - withLabel: mem128gib { memory = 137438953472.B } - withLabel: mem256gib { memory = 274877906944.B } - withLabel: mem512gib { memory = 549755813888.B } - withLabel: mem1tib { memory = 1099511627776.B } - withLabel: mem2tib { memory = 2199023255552.B } - withLabel: mem4tib { memory = 4398046511104.B } - withLabel: mem8tib { memory = 8796093022208.B } - withLabel: mem16tib { memory = 17592186044416.B } - withLabel: mem32tib { memory = 35184372088832.B } - withLabel: mem64tib { memory = 70368744177664.B } - withLabel: mem128tib { memory = 140737488355328.B } - withLabel: mem256tib { memory = 281474976710656.B } - withLabel: mem512tib { memory = 562949953421312.B } - withLabel: cpu1 { cpus = 1 } - withLabel: cpu2 { cpus = 2 } - withLabel: cpu5 { cpus = 5 } - withLabel: cpu10 { cpus = 10 } - withLabel: cpu20 { cpus = 20 } - withLabel: cpu50 { cpus = 50 } - withLabel: cpu100 { cpus = 100 } - withLabel: cpu200 { cpus = 200 } - withLabel: cpu500 { cpus = 500 } - withLabel: cpu1000 { cpus = 1000 } -} - - diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/nextflow_schema.json deleted file mode 100644 index 8426544..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/nextflow_schema.json +++ /dev/null @@ -1,115 +0,0 @@ -{ -"$schema": "http://json-schema.org/draft-07/schema", -"title": "samtools_idxstats", -"description": "Reports alignment summary statistics for a BAM file.", -"type": "object", -"definitions": { - - - - "inputs" : { - "title": "Inputs", - "type": "object", - "description": "No description", - "properties": { - - - "bam": { - "type": - "string", - "description": "Type: `file`. BAM input file", - "help_text": "Type: `file`. BAM input file." - - } - - - , - "bai": { - "type": - "string", - "description": "Type: `file`. BAM index file", - "help_text": "Type: `file`. BAM index file." - - } - - - , - "fasta": { - "type": - "string", - "description": "Type: `file`. Reference file the CRAM was created with (optional)", - "help_text": "Type: `file`. Reference file the CRAM was created with (optional)." - - } - - -} -}, - - - "outputs" : { - "title": "Outputs", - "type": "object", - "description": "No description", - "properties": { - - - "output": { - "type": - "string", - "description": "Type: `file`, required, default: `$id.$key.output.idxstats`, example: `output.idxstats`. File containing samtools stats output in tab-delimited format", - "help_text": "Type: `file`, required, default: `$id.$key.output.idxstats`, example: `output.idxstats`. File containing samtools stats output in tab-delimited format.\n" - , - "default": "$id.$key.output.idxstats" - } - - -} -}, - - - "nextflow input-output arguments" : { - "title": "Nextflow input-output arguments", - "type": "object", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "properties": { - - - "publish_dir": { - "type": - "string", - "description": "Type: `string`, required, example: `output/`. Path to an output directory", - "help_text": "Type: `string`, required, example: `output/`. Path to an output directory." - - } - - - , - "param_list": { - "type": - "string", - "description": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel", - "help_text": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob.\n\n* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ [\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027], [\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027] ]`.\n* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`.\n* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]`.\n* A yaml blob can also be passed directly as a string. Example: `--param_list \"[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]\"`.\n\nWhen passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.", - "hidden": true - - } - - -} -} -}, -"allOf": [ - - { - "$ref": "#/definitions/inputs" - }, - - { - "$ref": "#/definitions/outputs" - }, - - { - "$ref": "#/definitions/nextflow input-output arguments" - } -] -} diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/.config.vsh.yaml deleted file mode 100644 index f5dd78d..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/.config.vsh.yaml +++ /dev/null @@ -1,201 +0,0 @@ -name: "samtools_index" -namespace: "samtools" -version: "v0.1.0" -argument_groups: -- name: "Inputs" - arguments: - - type: "file" - name: "--input" - description: "Input file name" - info: null - must_exist: true - create_parent: true - required: true - direction: "input" - multiple: false - multiple_sep: ";" -- name: "Outputs" - arguments: - - type: "file" - name: "--output" - alternatives: - - "-o" - description: "Output file name" - info: null - example: - - "out.bam.bai" - must_exist: true - create_parent: true - required: true - direction: "output" - multiple: false - multiple_sep: ";" -- name: "Options" - arguments: - - type: "boolean_true" - name: "--bai" - alternatives: - - "-b" - description: "Generate BAM index" - info: null - direction: "input" - - type: "boolean_true" - name: "--csi" - alternatives: - - "-c" - description: "Create a CSI index for BAM files instead of the traditional BAI\ - \ \nindex. This will be required for genomes with larger chromosome \nsizes.\n" - info: null - direction: "input" - - type: "integer" - name: "--min_shift" - alternatives: - - "-m" - description: "Create a CSI index, with a minimum interval size of 2^INT.\n" - info: null - required: false - direction: "input" - multiple: false - multiple_sep: ";" -resources: -- type: "bash_script" - path: "script.sh" - is_executable: true -description: "Index SAM/BAM/CRAM files." -test_resources: -- type: "bash_script" - path: "test.sh" - is_executable: true -- type: "file" - path: "test_data" -info: null -status: "enabled" -requirements: - commands: - - "ps" -keywords: -- "index" -- "bam" -- "sam" -- "cram" -license: "MIT/Expat" -references: - doi: - - "10.1093/bioinformatics/btp352" - - "10.1093/gigascience/giab008" -links: - repository: "https://github.com/samtools/samtools" - homepage: "https://www.htslib.org/" - documentation: "https://www.htslib.org/doc/samtools-index.html" -runners: -- type: "executable" - id: "executable" - docker_setup_strategy: "ifneedbepullelsecachedbuild" -- type: "nextflow" - id: "nextflow" - directives: - tag: "$id" - auto: - simplifyInput: true - simplifyOutput: false - transcript: false - publish: false - config: - labels: - mem1gb: "memory = 1000000000.B" - mem2gb: "memory = 2000000000.B" - mem5gb: "memory = 5000000000.B" - mem10gb: "memory = 10000000000.B" - mem20gb: "memory = 20000000000.B" - mem50gb: "memory = 50000000000.B" - mem100gb: "memory = 100000000000.B" - mem200gb: "memory = 200000000000.B" - mem500gb: "memory = 500000000000.B" - mem1tb: "memory = 1000000000000.B" - mem2tb: "memory = 2000000000000.B" - mem5tb: "memory = 5000000000000.B" - mem10tb: "memory = 10000000000000.B" - mem20tb: "memory = 20000000000000.B" - mem50tb: "memory = 50000000000000.B" - mem100tb: "memory = 100000000000000.B" - mem200tb: "memory = 200000000000000.B" - mem500tb: "memory = 500000000000000.B" - mem1gib: "memory = 1073741824.B" - mem2gib: "memory = 2147483648.B" - mem4gib: "memory = 4294967296.B" - mem8gib: "memory = 8589934592.B" - mem16gib: "memory = 17179869184.B" - mem32gib: "memory = 34359738368.B" - mem64gib: "memory = 68719476736.B" - mem128gib: "memory = 137438953472.B" - mem256gib: "memory = 274877906944.B" - mem512gib: "memory = 549755813888.B" - mem1tib: "memory = 1099511627776.B" - mem2tib: "memory = 2199023255552.B" - mem4tib: "memory = 4398046511104.B" - mem8tib: "memory = 8796093022208.B" - mem16tib: "memory = 17592186044416.B" - mem32tib: "memory = 35184372088832.B" - mem64tib: "memory = 70368744177664.B" - mem128tib: "memory = 140737488355328.B" - mem256tib: "memory = 281474976710656.B" - mem512tib: "memory = 562949953421312.B" - cpu1: "cpus = 1" - cpu2: "cpus = 2" - cpu5: "cpus = 5" - cpu10: "cpus = 10" - cpu20: "cpus = 20" - cpu50: "cpus = 50" - cpu100: "cpus = 100" - cpu200: "cpus = 200" - cpu500: "cpus = 500" - cpu1000: "cpus = 1000" - debug: false - container: "docker" -engines: -- type: "docker" - id: "docker" - image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" - target_registry: "images.viash-hub.com" - target_tag: "v0.1.0" - namespace_separator: "/" - setup: - - type: "docker" - run: - - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\nsed 's#Using\ - \ ##;s# \\([0-9\\.]*\\)$#: \\1#' > /var/software_versions.txt\n" - entrypoint: [] - cmd: null -- type: "native" - id: "native" -build_info: - config: "src/samtools/samtools_index/config.vsh.yaml" - runner: "nextflow" - engine: "docker|native" - output: "target/nextflow/samtools/samtools_index" - executable: "target/nextflow/samtools/samtools_index/main.nf" - viash_version: "0.9.0-RC6" - git_commit: "b84b29747d0635f2ac83ea63b496be9a9edb6724" - git_remote: "https://github.com/viash-hub/biobox" -package_config: - name: "biobox" - version: "v0.1.0" - description: "A collection of bioinformatics tools for working with sequence data.\n" - info: null - viash_version: "0.9.0-RC6" - source: "src" - target: "target" - config_mods: - - ".requirements.commands := ['ps']\n" - - ".engines += { type: \"native\" }" - - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - keywords: - - "bioinformatics" - - "modules" - - "sequencing" - license: "MIT" - organization: "vsh" - links: - repository: "https://github.com/viash-hub/biobox" - issue_tracker: "https://github.com/viash-hub/biobox/issues" diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/main.nf b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/main.nf deleted file mode 100644 index a60ee5c..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/main.nf +++ /dev/null @@ -1,3562 +0,0 @@ -// samtools_index v0.1.0 -// -// This wrapper script is auto-generated by viash 0.9.0-RC6 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. -// -// The component may contain files which fall under a different license. The -// authors of this component should specify the license in the header of such -// files, or include a separate license file detailing the licenses of all included -// files. - -//////////////////////////// -// VDSL3 helper functions // -//////////////////////////// - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_checkArgumentType.nf' -class UnexpectedArgumentTypeException extends Exception { - String errorIdentifier - String stage - String plainName - String expectedClass - String foundClass - - // ${key ? " in module '$key'" : ""}${id ? " id '$id'" : ""} - UnexpectedArgumentTypeException(String errorIdentifier, String stage, String plainName, String expectedClass, String foundClass) { - super("Error${errorIdentifier ? " $errorIdentifier" : ""}:${stage ? " $stage" : "" } argument '${plainName}' has the wrong type. " + - "Expected type: ${expectedClass}. Found type: ${foundClass}") - this.errorIdentifier = errorIdentifier - this.stage = stage - this.plainName = plainName - this.expectedClass = expectedClass - this.foundClass = foundClass - } -} - -/** - * Checks if the given value is of the expected type. If not, an exception is thrown. - * - * @param stage The stage of the argument (input or output) - * @param par The parameter definition - * @param value The value to check - * @param errorIdentifier The identifier to use in the error message - * @return The value, if it is of the expected type - * @throws UnexpectedArgumentTypeException If the value is not of the expected type -*/ -def _checkArgumentType(String stage, Map par, Object value, String errorIdentifier) { - // expectedClass will only be != null if value is not of the expected type - def expectedClass = null - def foundClass = null - - // todo: split if need be - - if (!par.required && value == null) { - expectedClass = null - } else if (par.multiple) { - if (value !instanceof Collection) { - value = [value] - } - - // split strings - value = value.collectMany{ val -> - if (val instanceof String) { - // collect() to ensure that the result is a List and not simply an array - val.split(par.multiple_sep).collect() - } else { - [val] - } - } - - // process globs - if (par.type == "file" && par.direction == "input") { - value = value.collect{ it instanceof String ? file(it, hidden: true) : it }.flatten() - } - - // check types of elements in list - try { - value = value.collect { listVal -> - _checkArgumentType(stage, par + [multiple: false], listVal, errorIdentifier) - } - } catch (UnexpectedArgumentTypeException e) { - expectedClass = "List[${e.expectedClass}]" - foundClass = "List[${e.foundClass}]" - } - } else if (par.type == "string") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else if (par.type == "integer") { - // cast to integer if need be - if (value instanceof String) { - try { - value = value.toInteger() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigInteger) { - value = value.intValue() - } - expectedClass = value instanceof Integer ? null : "Integer" - } else if (par.type == "long") { - // cast to long if need be - if (value instanceof String) { - try { - value = value.toLong() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof Integer) { - value = value.toLong() - } - expectedClass = value instanceof Long ? null : "Long" - } else if (par.type == "double") { - // cast to double if need be - if (value instanceof String) { - try { - value = value.toDouble() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigDecimal) { - value = value.doubleValue() - } - if (value instanceof Float) { - value = value.toDouble() - } - expectedClass = value instanceof Double ? null : "Double" - } else if (par.type == "boolean" | par.type == "boolean_true" | par.type == "boolean_false") { - // cast to boolean if need be - if (value instanceof String) { - def valueLower = value.toLowerCase() - if (valueLower == "true") { - value = true - } else if (valueLower == "false") { - value = false - } - } - expectedClass = value instanceof Boolean ? null : "Boolean" - } else if (par.type == "file" && (par.direction == "input" || stage == "output")) { - // cast to path if need be - if (value instanceof String) { - value = file(value, hidden: true) - } - if (value instanceof File) { - value = value.toPath() - } - expectedClass = value instanceof Path ? null : "Path" - } else if (par.type == "file" && stage == "input" && par.direction == "output") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else { - // didn't find a match for par.type - expectedClass = par.type - } - - if (expectedClass != null) { - if (foundClass == null) { - foundClass = value.getClass().getName() - } - throw new UnexpectedArgumentTypeException(errorIdentifier, stage, par.plainName, expectedClass, foundClass) - } - - return value -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processInputValues.nf' -Map _processInputValues(Map inputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.required) { - assert inputs.containsKey(arg.plainName) && inputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required input argument '${arg.plainName}' is missing" - } - } - - inputs = inputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid input argument" - - value = _checkArgumentType("input", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return inputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processOutputValues.nf' -Map _processOutputValues(Map outputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.direction == "output" && arg.required) { - assert outputs.containsKey(arg.plainName) && outputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required output argument '${arg.plainName}' is missing" - } - } - - outputs = outputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && it.direction == "output" } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid output argument" - - value = _checkArgumentType("output", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return outputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/IDChecker.nf' -class IDChecker { - final def items = [] as Set - - @groovy.transform.WithWriteLock - boolean observe(String item) { - if (items.contains(item)) { - return false - } else { - items << item - return true - } - } - - @groovy.transform.WithReadLock - boolean contains(String item) { - return items.contains(item) - } - - @groovy.transform.WithReadLock - Set getItems() { - return items.clone() - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_checkUniqueIds.nf' - -/** - * Check if the ids are unique across parameter sets - * - * @param parameterSets a list of parameter sets. - */ -private void _checkUniqueIds(List>> parameterSets) { - def ppIds = parameterSets.collect{it[0]} - assert ppIds.size() == ppIds.unique().size() : "All argument sets should have unique ids. Detected ids: $ppIds" -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_getChild.nf' - -// helper functions for reading params from file // -def _getChild(parent, child) { - if (child.contains("://") || java.nio.file.Paths.get(child).isAbsolute()) { - child - } else { - def parentAbsolute = java.nio.file.Paths.get(parent).toAbsolutePath().toString() - parentAbsolute.replaceAll('/[^/]*$', "/") + child - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_parseParamList.nf' -/** - * Figure out the param list format based on the file extension - * - * @param param_list A String containing the path to the parameter list file. - * - * @return A String containing the format of the parameter list file. - */ -def _paramListGuessFormat(param_list) { - if (param_list !instanceof String) { - "asis" - } else if (param_list.endsWith(".csv")) { - "csv" - } else if (param_list.endsWith(".json") || param_list.endsWith(".jsn")) { - "json" - } else if (param_list.endsWith(".yaml") || param_list.endsWith(".yml")) { - "yaml" - } else { - "yaml_blob" - } -} - - -/** - * Read the param list - * - * @param param_list One of the following: - * - A String containing the path to the parameter list file (csv, json or yaml), - * - A yaml blob of a list of maps (yaml_blob), - * - Or a groovy list of maps (asis). - * @param config A Map of the Viash configuration. - * - * @return A List of Maps containing the parameters. - */ -def _parseParamList(param_list, Map config) { - // first determine format by extension - def paramListFormat = _paramListGuessFormat(param_list) - - def paramListPath = (paramListFormat != "asis" && paramListFormat != "yaml_blob") ? - file(param_list, hidden: true) : - null - - // get the correct parser function for the detected params_list format - def paramSets = [] - if (paramListFormat == "asis") { - paramSets = param_list - } else if (paramListFormat == "yaml_blob") { - paramSets = readYamlBlob(param_list) - } else if (paramListFormat == "yaml") { - paramSets = readYaml(paramListPath) - } else if (paramListFormat == "json") { - paramSets = readJson(paramListPath) - } else if (paramListFormat == "csv") { - paramSets = readCsv(paramListPath) - } else { - error "Format of provided --param_list not recognised.\n" + - "Found: '$paramListFormat'.\n" + - "Expected: a csv file, a json file, a yaml file,\n" + - "a yaml blob or a groovy list of maps." - } - - // data checks - assert paramSets instanceof List: "--param_list should contain a list of maps" - for (value in paramSets) { - assert value instanceof Map: "--param_list should contain a list of maps" - } - - // id is argument - def idIsArgument = config.allArguments.any{it.plainName == "id"} - - // Reformat from List to List> by adding the ID as first element of a Tuple2 - paramSets = paramSets.collect({ data -> - def id = data.id - if (!idIsArgument) { - data = data.findAll{k, v -> k != "id"} - } - [id, data] - }) - - // Split parameters with 'multiple: true' - paramSets = paramSets.collect({ id, data -> - data = _splitParams(data, config) - [id, data] - }) - - // The paths of input files inside a param_list file may have been specified relatively to the - // location of the param_list file. These paths must be made absolute. - if (paramListPath) { - paramSets = paramSets.collect({ id, data -> - def new_data = data.collectEntries{ parName, parValue -> - def par = config.allArguments.find{it.plainName == parName} - if (par && par.type == "file" && par.direction == "input") { - if (parValue instanceof Collection) { - parValue = parValue.collectMany{path -> - def x = _resolveSiblingIfNotAbsolute(path, paramListPath) - x instanceof Collection ? x : [x] - } - } else { - parValue = _resolveSiblingIfNotAbsolute(parValue, paramListPath) - } - } - [parName, parValue] - } - [id, new_data] - }) - } - - return paramSets -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_splitParams.nf' -/** - * Split parameters for arguments that accept multiple values using their separator - * - * @param paramList A Map containing parameters to split. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A Map of parameters where the parameter values have been split into a list using - * their seperator. - */ -Map _splitParams(Map parValues, Map config){ - def parsedParamValues = parValues.collectEntries { parName, parValue -> - def parameterSettings = config.allArguments.find({it.plainName == parName}) - - if (!parameterSettings) { - // if argument is not found, do not alter - return [parName, parValue] - } - if (parameterSettings.multiple) { // Check if parameter can accept multiple values - if (parValue instanceof Collection) { - parValue = parValue.collect{it instanceof String ? it.split(parameterSettings.multiple_sep) : it } - } else if (parValue instanceof String) { - parValue = parValue.split(parameterSettings.multiple_sep) - } else if (parValue == null) { - parValue = [] - } else { - parValue = [ parValue ] - } - parValue = parValue.flatten() - } - // For all parameters check if multiple values are only passed for - // arguments that allow it. Quietly simplify lists of length 1. - if (!parameterSettings.multiple && parValue instanceof Collection) { - assert parValue.size() == 1 : - "Error: argument ${parName} has too many values.\n" + - " Expected amount: 1. Found: ${parValue.size()}" - parValue = parValue[0] - } - [parName, parValue] - } - return parsedParamValues -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/channelFromParams.nf' -/** - * Parse nextflow parameters based on settings defined in a viash config. - * Return a list of parameter sets, each parameter set corresponding to - * an event in a nextflow channel. The output from this function can be used - * with Channel.fromList to create a nextflow channel with Vdsl3 formatted - * events. - * - * This function performs: - * - A filtering of the params which can be found in the config file. - * - Process the params_list argument which allows a user to to initialise - * a Vsdl3 channel with multiple parameter sets. Possible formats are - * csv, json, yaml, or simply a yaml_blob. A csv should have column names - * which correspond to the different arguments of this pipeline. A json or a yaml - * file should be a list of maps, each of which has keys corresponding to the - * arguments of the pipeline. A yaml blob can also be passed directly as a parameter. - * When passing a csv, json or yaml, relative path names are relativized to the - * location of the parameter file. - * - Combine the parameter sets into a vdsl3 Channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A list of parameters with the first element of the event being - * the event ID and the second element containing a map of the parsed parameters. - */ - -private List>> _paramsToParamSets(Map params, Map config){ - // todo: fetch key from run args - def key_ = config.name - - /* parse regular parameters (not in param_list) */ - /*************************************************/ - def globalParams = config.allArguments - .findAll { params.containsKey(it.plainName) } - .collectEntries { [ it.plainName, params[it.plainName] ] } - def globalID = params.get("id", null) - - /* process params_list arguments */ - /*********************************/ - def paramList = params.containsKey("param_list") && params.param_list != null ? - params.param_list : [] - // if (paramList instanceof String) { - // paramList = [paramList] - // } - // def paramSets = paramList.collectMany{ _parseParamList(it, config) } - // TODO: be able to process param_list when it is a list of strings - def paramSets = _parseParamList(paramList, config) - if (paramSets.isEmpty()) { - paramSets = [[null, [:]]] - } - - /* combine arguments into channel */ - /**********************************/ - def processedParams = paramSets.indexed().collect{ index, tup -> - // Process ID - def id = tup[0] ?: globalID - - if (workflow.stubRun && !id) { - // if stub run, explicitly add an id if missing - id = "stub${index}" - } - assert id != null: "Each parameter set should have at least an 'id'" - - // Process params - def parValues = globalParams + tup[1] - // // Remove parameters which are null, if the default is also null - // parValues = parValues.collectEntries{paramName, paramValue -> - // parameterSettings = config.functionality.allArguments.find({it.plainName == paramName}) - // if ( paramValue != null || parameterSettings.get("default", null) != null ) { - // [paramName, paramValue] - // } - // } - parValues = parValues.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key_}' id '${id}': '${name}' is not a valid input argument" - - if (par == null) { - return [:] - } - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - - [ name, value ] - } - - [id, parValues] - } - - // Check if ids (first element of each list) is unique - _checkUniqueIds(processedParams) - return processedParams -} - -/** - * Parse nextflow parameters based on settings defined in a viash config - * and return a nextflow channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A nextflow Channel with events. Events are formatted as a tuple that contains - * first contains the ID of the event and as second element holds a parameter map. - * - * - */ -def channelFromParams(Map params, Map config) { - def processedParams = _paramsToParamSets(params, config) - return Channel.fromList(processedParams) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/checkUniqueIds.nf' -def checkUniqueIds(Map args) { - def stopOnError = args.stopOnError == null ? args.stopOnError : true - - def idChecker = new IDChecker() - - return filter { tup -> - if (!idChecker.observe(tup[0])) { - if (stopOnError) { - error "Duplicate id: ${tup[0]}" - } else { - log.warn "Duplicate id: ${tup[0]}, removing duplicate entry" - return false - } - } - return true - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/preprocessInputs.nf' -// This helper file will be deprecated soon -preprocessInputsDeprecationWarningPrinted = false - -def preprocessInputsDeprecationWarning() { - if (!preprocessInputsDeprecationWarningPrinted) { - preprocessInputsDeprecationWarningPrinted = true - System.err.println("Warning: preprocessInputs() is deprecated and will be removed in Viash 0.9.0.") - } -} - -/** - * Generate a nextflow Workflow that allows processing a channel of - * Vdsl3 formatted events and apply a Viash config to them: - * - Gather default parameters from the Viash config and make - * sure that they are correctly formatted (see applyConfig method). - * - Format the input parameters (also using the applyConfig method). - * - Apply the default parameter to the input parameters. - * - Do some assertions: - * ~ Check if the event IDs in the channel are unique. - * - * The events in the channel are formatted as tuples, with the - * first element of the tuples being a unique id of the parameter set, - * and the second element containg the the parameters themselves. - * Optional extra elements of the tuples will be passed to the output as is. - * - * @param args A map that must contain a 'config' key that points - * to a parsed config (see readConfig()). Optionally, a - * 'key' key can be provided which can be used to create a unique - * name for the workflow process. - * - * @return A workflow that allows processing a channel of Vdsl3 formatted events - * and apply a Viash config to them. - */ -def preprocessInputs(Map args) { - preprocessInputsDeprecationWarning() - - def config = args.config - assert config instanceof Map : - "Error in preprocessInputs: config must be a map. " + - "Expected class: Map. Found: config.getClass() is ${config.getClass()}" - def key_ = args.key ?: config.name - - // Get different parameter types (used throughout this function) - def defaultArgs = config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - map { tup -> - def id = tup[0] - def data = tup[1] - def passthrough = tup.drop(2) - - def new_data = (defaultArgs + data).collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - - if (par != null) { - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - } - - [ name, value ] - } - - [ id, new_data ] + passthrough - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runComponents.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component config. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component config. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component config. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component config. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runComponents(Map args) { - log.warn("runComponents is deprecated, use runEach instead") - assert args.components: "runComponents should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runComponents" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runComponentsWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def comp_config = comp_.config - - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_config) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - // def new_id = id_(tup[0], tup[1], comp_config) - def new_id = tup[0] - if (id_ instanceof String) { - new_id = id_ - } else if (id_ instanceof Closure) { - new_id = id_(new_id, tup[1], comp_config) - } - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_config) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_config) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runComponentsWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runEach.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component itself. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component itself. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component itself. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component itself. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runEach(Map args) { - assert args.components: "runEach should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runEach" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runEachWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - def new_id = id_ - if (new_id instanceof Closure) { - new_id = new_id(tup[0], tup[1], comp_) - } - assert new_id instanceof String : "Error in runEach: id should be a String or a Closure that returns a String. Expected: id instanceof String. Found: ${new_id.getClass()}" - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runEachWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/safeJoin.nf' -/** - * Join sourceChannel to targetChannel - * - * This function joins the sourceChannel to the targetChannel. - * However, each id in the targetChannel must be present in the - * sourceChannel. If _meta.join_id exists in the targetChannel, that is - * used as an id instead. If the id doesn't match any id in the sourceChannel, - * an error is thrown. - */ - -def safeJoin(targetChannel, sourceChannel, key) { - def sourceIDs = new IDChecker() - - def sourceCheck = sourceChannel - | map { tup -> - sourceIDs.observe(tup[0]) - tup - } - def targetCheck = targetChannel - | map { tup -> - def id = tup[0] - - if (!sourceIDs.contains(id)) { - error ( - "Error in module '${key}' when merging output with original state.\n" + - " Reason: output with id '${id}' could not be joined with source channel.\n" + - " If the IDs in the output channel differ from the input channel,\n" + - " please set `tup[1]._meta.join_id to the original ID.\n" + - " Original IDs in input channel: ['${sourceIDs.getItems().join("', '")}'].\n" + - " Unexpected ID in the output channel: '${id}'.\n" + - " Example input event: [\"id\", [input: file(...)]],\n" + - " Example output event: [\"newid\", [output: file(...), _meta: [join_id: \"id\"]]]" - ) - } - // TODO: add link to our documentation on how to fix this - - tup - } - - sourceCheck.cross(targetChannel) - | map{ left, right -> - right + left.drop(1) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/_processArgument.nf' -def _processArgument(arg) { - arg.multiple = arg.multiple != null ? arg.multiple : false - arg.required = arg.required != null ? arg.required : false - arg.direction = arg.direction != null ? arg.direction : "input" - arg.multiple_sep = arg.multiple_sep != null ? arg.multiple_sep : ";" - arg.plainName = arg.name.replaceAll("^-*", "") - - if (arg.type == "file") { - arg.must_exist = arg.must_exist != null ? arg.must_exist : true - arg.create_parent = arg.create_parent != null ? arg.create_parent : true - } - - // add default values to output files which haven't already got a default - if (arg.type == "file" && arg.direction == "output" && arg.default == null) { - def mult = arg.multiple ? "_*" : "" - def extSearch = "" - if (arg.default != null) { - extSearch = arg.default - } else if (arg.example != null) { - extSearch = arg.example - } - if (extSearch instanceof List) { - extSearch = extSearch[0] - } - def extSearchResult = extSearch.find("\\.[^\\.]+\$") - def ext = extSearchResult != null ? extSearchResult : "" - arg.default = "\$id.\$key.${arg.plainName}${mult}${ext}" - if (arg.multiple) { - arg.default = [arg.default] - } - } - - if (!arg.multiple) { - if (arg.default != null && arg.default instanceof List) { - arg.default = arg.default[0] - } - if (arg.example != null && arg.example instanceof List) { - arg.example = arg.example[0] - } - } - - if (arg.type == "boolean_true") { - arg.default = false - } - if (arg.type == "boolean_false") { - arg.default = true - } - - arg -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/addGlobalParams.nf' -def addGlobalArguments(config) { - def localConfig = [ - "argument_groups": [ - [ - "name": "Nextflow input-output arguments", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "arguments" : [ - [ - 'name': '--publish_dir', - 'required': true, - 'type': 'string', - 'description': 'Path to an output directory.', - 'example': 'output/', - 'multiple': false - ], - [ - 'name': '--param_list', - 'required': false, - 'type': 'string', - 'description': '''Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob. - | - |* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ ['id': 'foo', 'input': 'foo.txt'], ['id': 'bar', 'input': 'bar.txt'] ]`. - |* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`. - |* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]`. - |* A yaml blob can also be passed directly as a string. Example: `--param_list "[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]"`. - | - |When passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.'''.stripMargin(), - 'example': 'my_params.yaml', - 'multiple': false, - 'hidden': true - ] - // TODO: allow multiple: true in param_list? - // TODO: allow to specify a --param_list_regex to filter the param_list? - // TODO: allow to specify a --param_list_from_state to remap entries in the param_list? - ] - ] - ] - ] - - return processConfig(_mergeMap(config, localConfig)) -} - -def _mergeMap(Map lhs, Map rhs) { - return rhs.inject(lhs.clone()) { map, entry -> - if (map[entry.key] instanceof Map && entry.value instanceof Map) { - map[entry.key] = _mergeMap(map[entry.key], entry.value) - } else if (map[entry.key] instanceof Collection && entry.value instanceof Collection) { - map[entry.key] += entry.value - } else { - map[entry.key] = entry.value - } - return map - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/generateHelp.nf' -def _generateArgumentHelp(param) { - // alternatives are not supported - // def names = param.alternatives ::: List(param.name) - - def unnamedProps = [ - ["required parameter", param.required], - ["multiple values allowed", param.multiple], - ["output", param.direction.toLowerCase() == "output"], - ["file must exist", param.type == "file" && param.must_exist] - ].findAll{it[1]}.collect{it[0]} - - def dflt = null - if (param.default != null) { - if (param.default instanceof List) { - dflt = param.default.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - dflt = param.default.toString() - } - } - def example = null - if (param.example != null) { - if (param.example instanceof List) { - example = param.example.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - example = param.example.toString() - } - } - def min = param.min?.toString() - def max = param.max?.toString() - - def escapeChoice = { choice -> - def s1 = choice.replaceAll("\\n", "\\\\n") - def s2 = s1.replaceAll("\"", """\\\"""") - s2.contains(",") || s2 != choice ? "\"" + s2 + "\"" : s2 - } - def choices = param.choices == null ? - null : - "[ " + param.choices.collect{escapeChoice(it.toString())}.join(", ") + " ]" - - def namedPropsStr = [ - ["type", ([param.type] + unnamedProps).join(", ")], - ["default", dflt], - ["example", example], - ["choices", choices], - ["min", min], - ["max", max] - ] - .findAll{it[1]} - .collect{"\n " + it[0] + ": " + it[1].replaceAll("\n", "\\n")} - .join("") - - def descStr = param.description == null ? - "" : - _paragraphWrap("\n" + param.description.trim(), 80 - 8).join("\n ") - - "\n --" + param.plainName + - namedPropsStr + - descStr -} - -// Based on Helper.generateHelp() in Helper.scala -def _generateHelp(config) { - def fun = config - - // PART 1: NAME AND VERSION - def nameStr = fun.name + - (fun.version == null ? "" : " " + fun.version) - - // PART 2: DESCRIPTION - def descrStr = fun.description == null ? - "" : - "\n\n" + _paragraphWrap(fun.description.trim(), 80).join("\n") - - // PART 3: Usage - def usageStr = fun.usage == null ? - "" : - "\n\nUsage:\n" + fun.usage.trim() - - // PART 4: Options - def argGroupStrs = fun.allArgumentGroups.collect{argGroup -> - def name = argGroup.name - def descriptionStr = argGroup.description == null ? - "" : - "\n " + _paragraphWrap(argGroup.description.trim(), 80-4).join("\n ") + "\n" - def arguments = argGroup.arguments.collect{arg -> - arg instanceof String ? fun.allArguments.find{it.plainName == arg} : arg - }.findAll{it != null} - def argumentStrs = arguments.collect{param -> _generateArgumentHelp(param)} - - "\n\n$name:" + - descriptionStr + - argumentStrs.join("\n") - } - - // FINAL: combine - def out = nameStr + - descrStr + - usageStr + - argGroupStrs.join("") - - return out -} - -// based on Format._paragraphWrap -def _paragraphWrap(str, maxLength) { - def outLines = [] - str.split("\n").each{par -> - def words = par.split("\\s").toList() - - def word = null - def line = words.pop() - while(!words.isEmpty()) { - word = words.pop() - if (line.length() + word.length() + 1 <= maxLength) { - line = line + " " + word - } else { - outLines.add(line) - line = word - } - } - if (words.isEmpty()) { - outLines.add(line) - } - } - return outLines -} - -def helpMessage(config) { - if (params.containsKey("help") && params.help) { - def mergedConfig = addGlobalArguments(config) - def helpStr = _generateHelp(mergedConfig) - println(helpStr) - exit 0 - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/processConfig.nf' -def processConfig(config) { - // set defaults for arguments - config.arguments = - (config.arguments ?: []).collect{_processArgument(it)} - - // set defaults for argument_group arguments - config.argument_groups = - (config.argument_groups ?: []).collect{grp -> - grp.arguments = (grp.arguments ?: []).collect{_processArgument(it)} - grp - } - - // create combined arguments list - config.allArguments = - config.arguments + - config.argument_groups.collectMany{it.arguments} - - // add missing argument groups (based on Functionality::allArgumentGroups()) - def argGroups = config.argument_groups - if (argGroups.any{it.name.toLowerCase() == "arguments"}) { - argGroups = argGroups.collect{ grp -> - if (grp.name.toLowerCase() == "arguments") { - grp = grp + [ - arguments: grp.arguments + config.arguments - ] - } - grp - } - } else { - argGroups = argGroups + [ - name: "Arguments", - arguments: config.arguments - ] - } - config.allArgumentGroups = argGroups - - config -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/readConfig.nf' - -def readConfig(file) { - def config = readYaml(file ?: moduleDir.resolve("config.vsh.yaml")) - processConfig(config) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_resolveSiblingIfNotAbsolute.nf' -/** - * Resolve a path relative to the current file. - * - * @param str The path to resolve, as a String. - * @param parentPath The path to resolve relative to, as a Path. - * - * @return The path that may have been resovled, as a Path. - */ -def _resolveSiblingIfNotAbsolute(str, parentPath) { - if (str !instanceof String) { - return str - } - if (!_stringIsAbsolutePath(str)) { - return parentPath.resolveSibling(str) - } else { - return file(str, hidden: true) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_stringIsAbsolutePath.nf' -/** - * Check whether a path as a string is absolute. - * - * In the past, we tried using `file(., relative: true).isAbsolute()`, - * but the 'relative' option was added in 22.10.0. - * - * @param path The path to check, as a String. - * - * @return Whether the path is absolute, as a boolean. - */ -def _stringIsAbsolutePath(path) { - def _resolve_URL_PROTOCOL = ~/^([a-zA-Z][a-zA-Z0-9]*:)?\\/.+/ - - assert path instanceof String - return _resolve_URL_PROTOCOL.matcher(path).matches() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/collectTraces.nf' -class CustomTraceObserver implements nextflow.trace.TraceObserver { - List traces - - CustomTraceObserver(List traces) { - this.traces = traces - } - - @Override - void onProcessComplete(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } - - @Override - void onProcessCached(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } -} - -def collectTraces() { - def traces = Collections.synchronizedList([]) - - // add custom trace observer which stores traces in the traces object - session.observers.add(new CustomTraceObserver(traces)) - - traces -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/deepClone.nf' -/** - * Performs a deep clone of the given object. - * @param x an object - */ -def deepClone(x) { - iterateMap(x, {it instanceof Cloneable ? it.clone() : it}) -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getPublishDir.nf' -def getPublishDir() { - return params.containsKey("publish_dir") ? params.publish_dir : - params.containsKey("publishDir") ? params.publishDir : - null -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getRootDir.nf' - -// Recurse upwards until we find a '.build.yaml' file -def _findBuildYamlFile(pathPossiblySymlink) { - def path = pathPossiblySymlink.toRealPath() - def child = path.resolve(".build.yaml") - if (java.nio.file.Files.isDirectory(path) && java.nio.file.Files.exists(child)) { - return child - } else { - def parent = path.getParent() - if (parent == null) { - return null - } else { - return _findBuildYamlFile(parent) - } - } -} - -// get the root of the target folder -def getRootDir() { - def dir = _findBuildYamlFile(meta.resources_dir) - assert dir != null: "Could not find .build.yaml in the folder structure" - dir.getParent() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/iterateMap.nf' -/** - * Recursively apply a function over the leaves of an object. - * @param obj The object to iterate over. - * @param fun The function to apply to each value. - * @return The object with the function applied to each value. - */ -def iterateMap(obj, fun) { - if (obj instanceof List && obj !instanceof String) { - return obj.collect{item -> - iterateMap(item, fun) - } - } else if (obj instanceof Map) { - return obj.collectEntries{key, item -> - [key.toString(), iterateMap(item, fun)] - } - } else { - return fun(obj) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/niceView.nf' -/** - * A view for printing the event of each channel as a YAML blob. - * This is useful for debugging. - */ -def niceView() { - workflow niceViewWf { - take: input - main: - output = input - | view{toYamlBlob(it)} - emit: output - } - return niceViewWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readCsv.nf' - -def readCsv(file_path) { - def output = [] - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - - // todo: allow escaped quotes in string - // todo: allow single quotes? - def splitRegex = java.util.regex.Pattern.compile(''',(?=(?:[^"]*"[^"]*")*[^"]*$)''') - def removeQuote = java.util.regex.Pattern.compile('''"(.*)"''') - - def br = java.nio.file.Files.newBufferedReader(inputFile) - - def row = -1 - def header = null - while (br.ready() && header == null) { - def line = br.readLine() - row++ - if (!line.startsWith("#")) { - header = splitRegex.split(line, -1).collect{field -> - m = removeQuote.matcher(field) - m.find() ? m.replaceFirst('$1') : field - } - } - } - assert header != null: "CSV file should contain a header" - - while (br.ready()) { - def line = br.readLine() - row++ - if (line == null) { - br.close() - break - } - - if (!line.startsWith("#")) { - def predata = splitRegex.split(line, -1) - def data = predata.collect{field -> - if (field == "") { - return null - } - def m = removeQuote.matcher(field) - if (m.find()) { - return m.replaceFirst('$1') - } else { - return field - } - } - assert header.size() == data.size(): "Row $row should contain the same number as fields as the header" - - def dataMap = [header, data].transpose().collectEntries().findAll{it.value != null} - output.add(dataMap) - } - } - - output -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJson.nf' -def readJson(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parse(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJsonBlob.nf' -def readJsonBlob(str) { - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parseText(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readTaggedYaml.nf' -// Custom constructor to modify how certain objects are parsed from YAML -class CustomConstructor extends org.yaml.snakeyaml.constructor.Constructor { - Path root - - class ConstructPath extends org.yaml.snakeyaml.constructor.AbstractConstruct { - public Object construct(org.yaml.snakeyaml.nodes.Node node) { - String filename = (String) constructScalar(node); - if (root != null) { - return root.resolve(filename); - } - return java.nio.file.Paths.get(filename); - } - } - - CustomConstructor(org.yaml.snakeyaml.LoaderOptions options, Path root) { - super(options) - this.root = root - // Handling !file tag and parse it back to a File type - this.yamlConstructors.put(new org.yaml.snakeyaml.nodes.Tag("!file"), new ConstructPath()) - } -} - -def readTaggedYaml(Path path) { - def options = new org.yaml.snakeyaml.LoaderOptions() - def constructor = new CustomConstructor(options, path.getParent()) - def yaml = new org.yaml.snakeyaml.Yaml(constructor) - return yaml.load(path.text) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYaml.nf' -def readYaml(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYamlBlob.nf' -def readYamlBlob(str) { - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toJsonBlob.nf' -String toJsonBlob(data) { - return groovy.json.JsonOutput.toJson(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toTaggedYamlBlob.nf' -// Custom representer to modify how certain objects are represented in YAML -class CustomRepresenter extends org.yaml.snakeyaml.representer.Representer { - Path relativizer - - class RepresentPath implements org.yaml.snakeyaml.representer.Represent { - public String getFileName(Object obj) { - if (obj instanceof File) { - obj = ((File) obj).toPath(); - } - if (obj !instanceof Path) { - throw new IllegalArgumentException("Object: " + obj + " is not a Path or File"); - } - def path = (Path) obj; - - if (relativizer != null) { - return relativizer.relativize(path).toString() - } else { - return path.toString() - } - } - - public org.yaml.snakeyaml.nodes.Node representData(Object data) { - String filename = getFileName(data); - def tag = new org.yaml.snakeyaml.nodes.Tag("!file"); - return representScalar(tag, filename); - } - } - CustomRepresenter(org.yaml.snakeyaml.DumperOptions options, Path relativizer) { - super(options) - this.relativizer = relativizer - this.representers.put(sun.nio.fs.UnixPath, new RepresentPath()) - this.representers.put(Path, new RepresentPath()) - this.representers.put(File, new RepresentPath()) - } -} - -String toTaggedYamlBlob(data) { - return toRelativeTaggedYamlBlob(data, null) -} -String toRelativeTaggedYamlBlob(data, Path relativizer) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - def representer = new CustomRepresenter(options, relativizer) - def yaml = new org.yaml.snakeyaml.Yaml(representer, options) - return yaml.dump(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toYamlBlob.nf' -String toYamlBlob(data) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - options.setPrettyFlow(true) - def yaml = new org.yaml.snakeyaml.Yaml(options) - def cleanData = iterateMap(data, { it instanceof Path ? it.toString() : it }) - return yaml.dump(cleanData) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeJson.nf' -void writeJson(data, file) { - assert data: "writeJson: data should not be null" - assert file: "writeJson: file should not be null" - file.write(toJsonBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeYaml.nf' -void writeYaml(data, file) { - assert data: "writeYaml: data should not be null" - assert file: "writeYaml: file should not be null" - file.write(toYamlBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/findStates.nf' -def findStates(Map params, Map config) { - def auto_config = deepClone(config) - def auto_params = deepClone(params) - - auto_config = auto_config.clone() - // override arguments - auto_config.argument_groups = [] - auto_config.arguments = [ - [ - type: "string", - name: "--id", - description: "A dummy identifier", - required: false - ], - [ - type: "file", - name: "--input_states", - example: "/path/to/input/directory/**/state.yaml", - description: "Path to input directory containing the datasets to be integrated.", - required: true, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--filter", - example: "foo/.*/state.yaml", - description: "Regex to filter state files by path.", - required: false - ], - // to do: make this a yaml blob? - [ - type: "string", - name: "--rename_keys", - example: ["newKey1:oldKey1", "newKey2:oldKey2"], - description: "Rename keys in the detected input files. This is useful if the input files do not match the set of input arguments of the workflow.", - required: false, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--settings", - example: '{"output_dataset": "dataset.h5ad", "k": 10}', - description: "Global arguments as a JSON glob to be passed to all components.", - required: false - ] - ] - if (!(auto_params.containsKey("id"))) { - auto_params["id"] = "auto" - } - - // run auto config through processConfig once more - auto_config = processConfig(auto_config) - - workflow findStatesWf { - helpMessage(auto_config) - - output_ch = - channelFromParams(auto_params, auto_config) - | flatMap { autoId, args -> - - def globalSettings = args.settings ? readYamlBlob(args.settings) : [:] - - // look for state files in input dir - def stateFiles = args.input_states - - // filter state files by regex - if (args.filter) { - stateFiles = stateFiles.findAll{ stateFile -> - def stateFileStr = stateFile.toString() - def matcher = stateFileStr =~ args.filter - matcher.matches()} - } - - // read in states - def states = stateFiles.collect { stateFile -> - def state_ = readTaggedYaml(stateFile) - [state_.id, state_] - } - - // construct renameMap - if (args.rename_keys) { - def renameMap = args.rename_keys.collectEntries{renameString -> - def split = renameString.split(";") - assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey,newKey:oldKey'" - split - } - - // rename keys in state, only let states through which have all keys - // also add global settings - states = states.collectMany{id, state -> - def newState = [:] - - for (key in renameMap.keySet()) { - def origKey = renameMap[key] - if (!(state.containsKey(origKey))) { - return [] - } - newState[key] = state[origKey] - } - - [[id, globalSettings + newState]] - } - } - - states - } - emit: - output_ch - } - - return findStatesWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/joinStates.nf' -def joinStates(Closure apply_) { - workflow joinStatesWf { - take: input_ch - main: - output_ch = input_ch - | toSortedList - | filter{ it.size() > 0 } - | map{ tups -> - def ids = tups.collect{it[0]} - def states = tups.collect{it[1]} - apply_(ids, states) - } - - emit: output_ch - } - return joinStatesWf -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/publishStates.nf' -def collectFiles(obj) { - if (obj instanceof java.io.File || obj instanceof Path) { - return [obj] - } else if (obj instanceof List && obj !instanceof String) { - return obj.collectMany{item -> - collectFiles(item) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectFiles(item) - } - } else { - return [] - } -} - -/** - * Recurse through a state and collect all input files and their target output filenames. - * @param obj The state to recurse through. - * @param prefix The prefix to prepend to the output filenames. - */ -def collectInputOutputPaths(obj, prefix) { - if (obj instanceof File || obj instanceof Path) { - def path = obj instanceof Path ? obj : obj.toPath() - def ext = path.getFileName().toString().find("\\.[^\\.]+\$") ?: "" - def newFilename = prefix + ext - return [[obj, newFilename]] - } else if (obj instanceof List && obj !instanceof String) { - return obj.withIndex().collectMany{item, ix -> - collectInputOutputPaths(item, prefix + "_" + ix) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectInputOutputPaths(item, prefix + "." + key) - } - } else { - return [] - } -} - -def publishStates(Map args) { - def key_ = args.get("key") - def yamlTemplate_ = args.get("output_state", args.get("outputState", '$id.$key.state.yaml')) - - assert key_ != null : "publishStates: key must be specified" - - workflow publishStatesWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] - - // the input files and the target output filenames - def inputoutputFilenames_ = collectInputOutputPaths(state_, id_ + "." + key_).transpose() - def inputFiles_ = inputoutputFilenames_[0] - def outputFilenames_ = inputoutputFilenames_[1] - - def yamlFilename = yamlTemplate_ - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - - // TODO: do the pathnames in state_ match up with the outputFilenames_? - - // convert state to yaml blob - def yamlBlob_ = toRelativeTaggedYamlBlob([id: id_] + state_, java.nio.file.Paths.get(yamlFilename)) - - [id_, yamlBlob_, yamlFilename, inputFiles_, outputFilenames_] - } - | publishStatesProc - emit: input_ch - } - return publishStatesWf -} -process publishStatesProc { - // todo: check publishpath? - publishDir path: "${getPublishDir()}/", mode: "copy" - tag "$id" - input: - tuple val(id), val(yamlBlob), val(yamlFile), path(inputFiles, stageAs: "_inputfile?/*"), val(outputFiles) - output: - tuple val(id), path{[yamlFile] + outputFiles} - script: - def copyCommands = [ - inputFiles instanceof List ? inputFiles : [inputFiles], - outputFiles instanceof List ? outputFiles : [outputFiles] - ] - .transpose() - .collectMany{infile, outfile -> - if (infile.toString() != outfile.toString()) { - [ - "[ -d \"\$(dirname '${outfile.toString()}')\" ] || mkdir -p \"\$(dirname '${outfile.toString()}')\"", - "cp -r '${infile.toString()}' '${outfile.toString()}'" - ] - } else { - // no need to copy if infile is the same as outfile - [] - } - } - """ -mkdir -p "\$(dirname '${yamlFile}')" -echo "Storing state as yaml" -echo '${yamlBlob}' > '${yamlFile}' -echo "Copying output files to destination folder" -${copyCommands.join("\n ")} -""" -} - - -// this assumes that the state contains no other values other than those specified in the config -def publishStatesByConfig(Map args) { - def config = args.get("config") - assert config != null : "publishStatesByConfig: config must be specified" - - def key_ = args.get("key", config.name) - assert key_ != null : "publishStatesByConfig: key must be specified" - - workflow publishStatesSimpleWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] // e.g. [output: new File("myoutput.h5ad"), k: 10] - def origState_ = tup[2] // e.g. [output: '$id.$key.foo.h5ad'] - - // TODO: allow overriding the state.yaml template - // TODO TODO: if auto.publish == "state", add output_state as an argument - def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' - def yamlFilename = yamlTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() - - // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where - // - key is a String - // - value is any object that can be serialized to a Yaml (so a String/Integer/Long/Double/Boolean, a List, a Map, or a Path) - // - inputPath is a List[Path] - // - outputFilename is a List[String] - // - (key, value) are the tuples that will be saved to the state.yaml file - // - (inputPath, outputFilename) are the files that will be copied from src to dest (relative to the state.yaml) - def processedState = - config.allArguments - .findAll { it.direction == "output" } - .collectMany { par -> - def plainName_ = par.plainName - // if the state does not contain the key, it's an - // optional argument for which the component did - // not generate any output - if (!state_.containsKey(plainName_)) { - return [] - } - def value = state_[plainName_] - // if the parameter is not a file, it should be stored - // in the state as-is, but is not something that needs - // to be copied from the source path to the dest path - if (par.type != "file") { - return [[key: plainName_, value: value, inputPath: [], outputFilename: []]] - } - // if the orig state does not contain this filename, - // it's an optional argument for which the user specified - // that it should not be returned as a state - if (!origState_.containsKey(plainName_)) { - return [] - } - def filenameTemplate = origState_[plainName_] - // if the pararameter is multiple: true, fetch the template - if (par.multiple && filenameTemplate instanceof List) { - filenameTemplate = filenameTemplate[0] - } - // instantiate the template - def filename = filenameTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - if (par.multiple) { - // if the parameter is multiple: true, the filename - // should contain a wildcard '*' that is replaced with - // the index of the file - assert filename.contains("*") : "Module '${key_}' id '${id_}': Multiple output files specified, but no wildcard '*' in the filename: ${filename}" - def outputPerFile = value.withIndex().collect{ val, ix -> - def filename_ix = filename.replace("*", ix.toString()) - def value_ = java.nio.file.Paths.get(filename_ix) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = val instanceof File ? val.toPath() : val - [value: value_, inputPath: inputPath, outputFilename: filename_ix] - } - def transposedOutputs = ["value", "inputPath", "outputFilename"].collectEntries{ key -> - [key, outputPerFile.collect{dic -> dic[key]}] - } - return [[key: plainName_] + transposedOutputs] - } else { - def value_ = java.nio.file.Paths.get(filename) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = value instanceof File ? value.toPath() : value - return [[key: plainName_, value: value_, inputPath: [inputPath], outputFilename: [filename]]] - } - } - - def updatedState_ = processedState.collectEntries{[it.key, it.value]} - def inputPaths = processedState.collectMany{it.inputPath} - def outputFilenames = processedState.collectMany{it.outputFilename} - - // convert state to yaml blob - def yamlBlob_ = toTaggedYamlBlob([id: id_] + updatedState_) - - [id_, yamlBlob_, yamlFilename, inputPaths, outputFilenames] - } - | publishStatesProc - emit: input_ch - } - return publishStatesSimpleWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/setState.nf' -def setState(fun) { - assert fun instanceof Closure || fun instanceof Map || fun instanceof List : - "Error in setState: Expected process argument to be a Closure, a Map, or a List. Found: class ${fun.getClass()}" - - // if fun is a List, convert to map - if (fun instanceof List) { - // check whether fun is a list[string] - assert fun.every{it instanceof CharSequence} : "Error in setState: argument is a List, but not all elements are Strings" - fun = fun.collectEntries{[it, it]} - } - - // if fun is a map, convert to closure - if (fun instanceof Map) { - // check whether fun is a map[string, string] - assert fun.values().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all values are Strings" - assert fun.keySet().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all keys are Strings" - def funMap = fun.clone() - // turn the map into a closure to be used later on - fun = { id_, state_ -> - assert state_ instanceof Map : "Error in setState: the state is not a Map" - funMap.collectMany{newkey, origkey -> - if (state_.containsKey(origkey)) { - [[newkey, state_[origkey]]] - } else { - [] - } - }.collectEntries() - } - } - - map { tup -> - def id = tup[0] - def state = tup[1] - def unfilteredState = fun(id, state) - def newState = unfilteredState.findAll{key, val -> val != null} - [id, newState] + tup.drop(2) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processAuto.nf' -// TODO: unit test processAuto -def processAuto(Map auto) { - // remove null values - auto = auto.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = ["simplifyInput", "simplifyOutput", "transcript", "publish"] - def unexpectedKeys = auto.keySet() - expectedKeys - assert unexpectedKeys.isEmpty(), "unexpected keys in auto: '${unexpectedKeys.join("', '")}'" - - // check auto.simplifyInput - assert auto.simplifyInput instanceof Boolean, "auto.simplifyInput must be a boolean" - - // check auto.simplifyOutput - assert auto.simplifyOutput instanceof Boolean, "auto.simplifyOutput must be a boolean" - - // check auto.transcript - assert auto.transcript instanceof Boolean, "auto.transcript must be a boolean" - - // check auto.publish - assert auto.publish instanceof Boolean || auto.publish == "state", "auto.publish must be a boolean or 'state'" - - return auto.subMap(expectedKeys) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processDirectives.nf' -def assertMapKeys(map, expectedKeys, requiredKeys, mapName) { - assert map instanceof Map : "Expected argument '$mapName' to be a Map. Found: class ${map.getClass()}" - map.forEach { key, val -> - assert key in expectedKeys : "Unexpected key '$key' in ${mapName ? mapName + " " : ""}map" - } - requiredKeys.forEach { requiredKey -> - assert map.containsKey(requiredKey) : "Missing required key '$key' in ${mapName ? mapName + " " : ""}map" - } -} - -// TODO: unit test processDirectives -def processDirectives(Map drctv) { - // remove null values - drctv = drctv.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = [ - "accelerator", "afterScript", "beforeScript", "cache", "conda", "container", "containerOptions", "cpus", "disk", "echo", "errorStrategy", "executor", "machineType", "maxErrors", "maxForks", "maxRetries", "memory", "module", "penv", "pod", "publishDir", "queue", "label", "scratch", "storeDir", "stageInMode", "stageOutMode", "tag", "time" - ] - def unexpectedKeys = drctv.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Unexpected keys in process directive: '${unexpectedKeys.join("', '")}'" - - /* DIRECTIVE accelerator - accepted examples: - - [ limit: 4, type: "nvidia-tesla-k80" ] - */ - if (drctv.containsKey("accelerator")) { - assertMapKeys(drctv["accelerator"], ["type", "limit", "request", "runtime"], [], "accelerator") - } - - /* DIRECTIVE afterScript - accepted examples: - - "source /cluster/bin/cleanup" - */ - if (drctv.containsKey("afterScript")) { - assert drctv["afterScript"] instanceof CharSequence - } - - /* DIRECTIVE beforeScript - accepted examples: - - "source /cluster/bin/setup" - */ - if (drctv.containsKey("beforeScript")) { - assert drctv["beforeScript"] instanceof CharSequence - } - - /* DIRECTIVE cache - accepted examples: - - true - - false - - "deep" - - "lenient" - */ - if (drctv.containsKey("cache")) { - assert drctv["cache"] instanceof CharSequence || drctv["cache"] instanceof Boolean - if (drctv["cache"] instanceof CharSequence) { - assert drctv["cache"] in ["deep", "lenient"] : "Unexpected value for cache" - } - } - - /* DIRECTIVE conda - accepted examples: - - "bwa=0.7.15" - - "bwa=0.7.15 fastqc=0.11.5" - - ["bwa=0.7.15", "fastqc=0.11.5"] - */ - if (drctv.containsKey("conda")) { - if (drctv["conda"] instanceof List) { - drctv["conda"] = drctv["conda"].join(" ") - } - assert drctv["conda"] instanceof CharSequence - } - - /* DIRECTIVE container - accepted examples: - - "foo/bar:tag" - - [ registry: "reg", image: "im", tag: "ta" ] - is transformed to "reg/im:ta" - - [ image: "im" ] - is transformed to "im:latest" - */ - if (drctv.containsKey("container")) { - assert drctv["container"] instanceof Map || drctv["container"] instanceof CharSequence - if (drctv["container"] instanceof Map) { - def m = drctv["container"] - assertMapKeys(m, [ "registry", "image", "tag" ], ["image"], "container") - def part1 = - System.getenv('OVERRIDE_CONTAINER_REGISTRY') ? System.getenv('OVERRIDE_CONTAINER_REGISTRY') + "/" : - params.containsKey("override_container_registry") ? params["override_container_registry"] + "/" : // todo: remove? - m.registry ? m.registry + "/" : - "" - def part2 = m.image - def part3 = m.tag ? ":" + m.tag : ":latest" - drctv["container"] = part1 + part2 + part3 - } - } - - /* DIRECTIVE containerOptions - accepted examples: - - "--foo bar" - - ["--foo bar", "-f b"] - */ - if (drctv.containsKey("containerOptions")) { - if (drctv["containerOptions"] instanceof List) { - drctv["containerOptions"] = drctv["containerOptions"].join(" ") - } - assert drctv["containerOptions"] instanceof CharSequence - } - - /* DIRECTIVE cpus - accepted examples: - - 1 - - 10 - */ - if (drctv.containsKey("cpus")) { - assert drctv["cpus"] instanceof Integer - } - - /* DIRECTIVE disk - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("disk")) { - assert drctv["disk"] instanceof CharSequence - // assert drctv["disk"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE echo - accepted examples: - - true - - false - */ - if (drctv.containsKey("echo")) { - assert drctv["echo"] instanceof Boolean - } - - /* DIRECTIVE errorStrategy - accepted examples: - - "terminate" - - "finish" - */ - if (drctv.containsKey("errorStrategy")) { - assert drctv["errorStrategy"] instanceof CharSequence - assert drctv["errorStrategy"] in ["terminate", "finish", "ignore", "retry"] : "Unexpected value for errorStrategy" - } - - /* DIRECTIVE executor - accepted examples: - - "local" - - "sge" - */ - if (drctv.containsKey("executor")) { - assert drctv["executor"] instanceof CharSequence - assert drctv["executor"] in ["local", "sge", "uge", "lsf", "slurm", "pbs", "pbspro", "moab", "condor", "nqsii", "ignite", "k8s", "awsbatch", "google-pipelines"] : "Unexpected value for executor" - } - - /* DIRECTIVE machineType - accepted examples: - - "n1-highmem-8" - */ - if (drctv.containsKey("machineType")) { - assert drctv["machineType"] instanceof CharSequence - } - - /* DIRECTIVE maxErrors - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxErrors")) { - assert drctv["maxErrors"] instanceof Integer - } - - /* DIRECTIVE maxForks - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxForks")) { - assert drctv["maxForks"] instanceof Integer - } - - /* DIRECTIVE maxRetries - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxRetries")) { - assert drctv["maxRetries"] instanceof Integer - } - - /* DIRECTIVE memory - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("memory")) { - assert drctv["memory"] instanceof CharSequence - // assert drctv["memory"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE module - accepted examples: - - "ncbi-blast/2.2.27" - - "ncbi-blast/2.2.27:t_coffee/10.0" - - ["ncbi-blast/2.2.27", "t_coffee/10.0"] - */ - if (drctv.containsKey("module")) { - if (drctv["module"] instanceof List) { - drctv["module"] = drctv["module"].join(":") - } - assert drctv["module"] instanceof CharSequence - } - - /* DIRECTIVE penv - accepted examples: - - "smp" - */ - if (drctv.containsKey("penv")) { - assert drctv["penv"] instanceof CharSequence - } - - /* DIRECTIVE pod - accepted examples: - - [ label: "key", value: "val" ] - - [ annotation: "key", value: "val" ] - - [ env: "key", value: "val" ] - - [ [label: "l", value: "v"], [env: "e", value: "v"]] - */ - if (drctv.containsKey("pod")) { - if (drctv["pod"] instanceof Map) { - drctv["pod"] = [ drctv["pod"] ] - } - assert drctv["pod"] instanceof List - drctv["pod"].forEach { pod -> - assert pod instanceof Map - // TODO: should more checks be added? - // See https://www.nextflow.io/docs/latest/process.html?highlight=directives#pod - // e.g. does it contain 'label' and 'value', or 'annotation' and 'value', or ...? - } - } - - /* DIRECTIVE publishDir - accepted examples: - - [] - - [ [ path: "foo", enabled: true ], [ path: "bar", enabled: false ] ] - - "/path/to/dir" - is transformed to [[ path: "/path/to/dir" ]] - - [ path: "/path/to/dir", mode: "cache" ] - is transformed to [[ path: "/path/to/dir", mode: "cache" ]] - */ - // TODO: should we also look at params["publishDir"]? - if (drctv.containsKey("publishDir")) { - def pblsh = drctv["publishDir"] - - // check different options - assert pblsh instanceof List || pblsh instanceof Map || pblsh instanceof CharSequence - - // turn into list if not already so - // for some reason, 'if (!pblsh instanceof List) pblsh = [ pblsh ]' doesn't work. - pblsh = pblsh instanceof List ? pblsh : [ pblsh ] - - // check elements of publishDir - pblsh = pblsh.collect{ elem -> - // turn into map if not already so - elem = elem instanceof CharSequence ? [ path: elem ] : elem - - // check types and keys - assert elem instanceof Map : "Expected publish argument '$elem' to be a String or a Map. Found: class ${elem.getClass()}" - assertMapKeys(elem, [ "path", "mode", "overwrite", "pattern", "saveAs", "enabled" ], ["path"], "publishDir") - - // check elements in map - assert elem.containsKey("path") - assert elem["path"] instanceof CharSequence - if (elem.containsKey("mode")) { - assert elem["mode"] instanceof CharSequence - assert elem["mode"] in [ "symlink", "rellink", "link", "copy", "copyNoFollow", "move" ] - } - if (elem.containsKey("overwrite")) { - assert elem["overwrite"] instanceof Boolean - } - if (elem.containsKey("pattern")) { - assert elem["pattern"] instanceof CharSequence - } - if (elem.containsKey("saveAs")) { - assert elem["saveAs"] instanceof CharSequence //: "saveAs as a Closure is currently not supported. Surround your closure with single quotes to get the desired effect. Example: '\{ foo \}'" - } - if (elem.containsKey("enabled")) { - assert elem["enabled"] instanceof Boolean - } - - // return final result - elem - } - // store final directive - drctv["publishDir"] = pblsh - } - - /* DIRECTIVE queue - accepted examples: - - "long" - - "short,long" - - ["short", "long"] - */ - if (drctv.containsKey("queue")) { - if (drctv["queue"] instanceof List) { - drctv["queue"] = drctv["queue"].join(",") - } - assert drctv["queue"] instanceof CharSequence - } - - /* DIRECTIVE label - accepted examples: - - "big_mem" - - "big_cpu" - - ["big_mem", "big_cpu"] - */ - if (drctv.containsKey("label")) { - if (drctv["label"] instanceof CharSequence) { - drctv["label"] = [ drctv["label"] ] - } - assert drctv["label"] instanceof List - drctv["label"].forEach { label -> - assert label instanceof CharSequence - // assert label.matches("[a-zA-Z0-9]([a-zA-Z0-9_]*[a-zA-Z0-9])?") - // ^ does not allow closures - } - } - - /* DIRECTIVE scratch - accepted examples: - - true - - "/path/to/scratch" - - '$MY_PATH_TO_SCRATCH' - - "ram-disk" - */ - if (drctv.containsKey("scratch")) { - assert drctv["scratch"] == true || drctv["scratch"] instanceof CharSequence - } - - /* DIRECTIVE storeDir - accepted examples: - - "/path/to/storeDir" - */ - if (drctv.containsKey("storeDir")) { - assert drctv["storeDir"] instanceof CharSequence - } - - /* DIRECTIVE stageInMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageInMode")) { - assert drctv["stageInMode"] instanceof CharSequence - assert drctv["stageInMode"] in ["copy", "link", "symlink", "rellink"] - } - - /* DIRECTIVE stageOutMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageOutMode")) { - assert drctv["stageOutMode"] instanceof CharSequence - assert drctv["stageOutMode"] in ["copy", "move", "rsync"] - } - - /* DIRECTIVE tag - accepted examples: - - "foo" - - '$id' - */ - if (drctv.containsKey("tag")) { - assert drctv["tag"] instanceof CharSequence - } - - /* DIRECTIVE time - accepted examples: - - "1h" - - "2days" - - "1day 6hours 3minutes 30seconds" - */ - if (drctv.containsKey("time")) { - assert drctv["time"] instanceof CharSequence - // todo: validation regex? - } - - return drctv -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf' -def processWorkflowArgs(Map args, Map defaultWfArgs, Map meta) { - // override defaults with args - def workflowArgs = defaultWfArgs + args - - // check whether 'key' exists - assert workflowArgs.containsKey("key") : "Error in module '${meta.config.name}': key is a required argument" - - // if 'key' is a closure, apply it to the original key - if (workflowArgs["key"] instanceof Closure) { - workflowArgs["key"] = workflowArgs["key"](meta.config.name) - } - def key = workflowArgs["key"] - assert key instanceof CharSequence : "Expected process argument 'key' to be a String. Found: class ${key.getClass()}" - assert key ==~ /^[a-zA-Z_]\w*$/ : "Error in module '$key': Expected process argument 'key' to consist of only letters, digits or underscores. Found: ${key}" - - // check for any unexpected keys - def expectedKeys = ["key", "directives", "auto", "map", "mapId", "mapData", "mapPassthrough", "filter", "runIf", "fromState", "toState", "args", "renameKeys", "debug"] - def unexpectedKeys = workflowArgs.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Error in module '$key': unexpected arguments to the '.run()' function: '${unexpectedKeys.join("', '")}'" - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("directives") : "Error in module '$key': directives is a required argument" - assert workflowArgs["directives"] instanceof Map : "Error in module '$key': Expected process argument 'directives' to be a Map. Found: class ${workflowArgs['directives'].getClass()}" - workflowArgs["directives"] = processDirectives(defaultWfArgs.directives + workflowArgs["directives"]) - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("auto") : "Error in module '$key': auto is a required argument" - assert workflowArgs["auto"] instanceof Map : "Error in module '$key': Expected process argument 'auto' to be a Map. Found: class ${workflowArgs['auto'].getClass()}" - workflowArgs["auto"] = processAuto(defaultWfArgs.auto + workflowArgs["auto"]) - - // auto define publish, if so desired - if (workflowArgs.auto.publish == true && (workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : [:]).isEmpty()) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.publish is true, params.publish_dir needs to be defined.\n" + - // " Example: params.publish_dir = \"./output/\"" - def publishDir = getPublishDir() - - if (publishDir != null) { - workflowArgs.directives.publishDir = [[ - path: publishDir, - saveAs: "{ it.startsWith('.') ? null : it }", // don't publish hidden files, by default - mode: "copy" - ]] - } - } - - // auto define transcript, if so desired - if (workflowArgs.auto.transcript == true) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("transcriptsDir") || params.containsKey("transcripts_dir") || params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.transcript is true, either params.transcripts_dir or params.publish_dir needs to be defined.\n" + - // " Example: params.transcripts_dir = \"./transcripts/\"" - def transcriptsDir = - params.containsKey("transcripts_dir") ? params.transcripts_dir : - params.containsKey("transcriptsDir") ? params.transcriptsDir : - params.containsKey("publish_dir") ? params.publish_dir + "/_transcripts" : - params.containsKey("publishDir") ? params.publishDir + "/_transcripts" : - null - if (transcriptsDir != null) { - def timestamp = nextflow.Nextflow.getSession().getWorkflowMetadata().start.format('yyyy-MM-dd_HH-mm-ss') - def transcriptsPublishDir = [ - path: "$transcriptsDir/$timestamp/\${task.process.replaceAll(':', '-')}/\${id}/", - saveAs: "{ it.startsWith('.') ? it.replaceAll('^.', '') : null }", - mode: "copy" - ] - def publishDirs = workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : null ? workflowArgs.directives.publishDir : [] - workflowArgs.directives.publishDir = publishDirs + transcriptsPublishDir - } - } - - // if this is a stubrun, remove certain directives? - if (workflow.stubRun) { - workflowArgs.directives.keySet().removeAll(["publishDir", "cpus", "memory", "label"]) - } - - for (nam in ["map", "mapId", "mapData", "mapPassthrough", "filter", "runIf"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam]) { - assert workflowArgs[nam] instanceof Closure : "Error in module '$key': Expected process argument '$nam' to be null or a Closure. Found: class ${workflowArgs[nam].getClass()}" - } - } - - // TODO: should functions like 'map', 'mapId', 'mapData', 'mapPassthrough' be deprecated as well? - for (nam in ["map", "mapData", "mapPassthrough", "renameKeys"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam] != null) { - log.warn "module '$key': workflow argument '$nam' is deprecated and will be removed in Viash 0.9.0. Please use 'fromState' and 'toState' instead." - } - } - - // check fromState - workflowArgs["fromState"] = _processFromState(workflowArgs.get("fromState"), key, meta.config) - - // check toState - workflowArgs["toState"] = _processToState(workflowArgs.get("toState"), key, meta.config) - - // return output - return workflowArgs -} - -def _processFromState(fromState, key_, config_) { - assert fromState == null || fromState instanceof Closure || fromState instanceof Map || fromState instanceof List : - "Error in module '$key_': Expected process argument 'fromState' to be null, a Closure, a Map, or a List. Found: class ${fromState.getClass()}" - if (fromState == null) { - return null - } - - // if fromState is a List, convert to map - if (fromState instanceof List) { - // check whether fromstate is a list[string] - assert fromState.every{it instanceof CharSequence} : "Error in module '$key_': fromState is a List, but not all elements are Strings" - fromState = fromState.collectEntries{[it, it]} - } - - // if fromState is a map, convert to closure - if (fromState instanceof Map) { - // check whether fromstate is a map[string, string] - assert fromState.values().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all values are Strings" - assert fromState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all keys are Strings" - def fromStateMap = fromState.clone() - def requiredInputNames = meta.config.allArguments.findAll{it.required && it.direction == "Input"}.collect{it.plainName} - // turn the map into a closure to be used later on - fromState = { it -> - def state = it[1] - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def data = fromStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (state.containsKey(origkey)) { - [[newkey, state[origkey]]] - } else if (!requiredInputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': fromState key '$origkey' not found in current state") - } - }.collectEntries() - data - } - } - - return fromState -} - -def _processToState(toState, key_, config_) { - if (toState == null) { - toState = { tup -> tup[1] } - } - - // toState should be a closure, map[string, string], or list[string] - assert toState instanceof Closure || toState instanceof Map || toState instanceof List : - "Error in module '$key_': Expected process argument 'toState' to be a Closure, a Map, or a List. Found: class ${toState.getClass()}" - - // if toState is a List, convert to map - if (toState instanceof List) { - // check whether toState is a list[string] - assert toState.every{it instanceof CharSequence} : "Error in module '$key_': toState is a List, but not all elements are Strings" - toState = toState.collectEntries{[it, it]} - } - - // if toState is a map, convert to closure - if (toState instanceof Map) { - // check whether toState is a map[string, string] - assert toState.values().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all values are Strings" - assert toState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all keys are Strings" - def toStateMap = toState.clone() - def requiredOutputNames = config_.allArguments.findAll{it.required && it.direction == "Output"}.collect{it.plainName} - // turn the map into a closure to be used later on - toState = { it -> - def output = it[1] - def state = it[2] - assert output instanceof Map : "Error in module '$key_': the output is not a Map" - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def extraEntries = toStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (output.containsKey(origkey)) { - [[newkey, output[origkey]]] - } else if (!requiredOutputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': toState key '$origkey' not found in current output") - } - }.collectEntries() - state + extraEntries - } - } - - return toState -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/workflowFactory.nf' -def _debug(workflowArgs, debugKey) { - if (workflowArgs.debug) { - view { "process '${workflowArgs.key}' $debugKey tuple: $it" } - } else { - map { it } - } -} - -// depends on: innerWorkflowFactory -def workflowFactory(Map args, Map defaultWfArgs, Map meta) { - def workflowArgs = processWorkflowArgs(args, defaultWfArgs, meta) - def key_ = workflowArgs["key"] - - workflow workflowInstance { - take: input_ - - main: - def chModified = input_ - | checkUniqueIds([:]) - | _debug(workflowArgs, "input") - | map { tuple -> - tuple = deepClone(tuple) - - if (workflowArgs.map) { - tuple = workflowArgs.map(tuple) - } - if (workflowArgs.mapId) { - tuple[0] = workflowArgs.mapId(tuple[0]) - } - if (workflowArgs.mapData) { - tuple[1] = workflowArgs.mapData(tuple[1]) - } - if (workflowArgs.mapPassthrough) { - tuple = tuple.take(2) + workflowArgs.mapPassthrough(tuple.drop(2)) - } - - // check tuple - assert tuple instanceof List : - "Error in module '${key_}': element in channel should be a tuple [id, data, ...otherargs...]\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: List. Found: tuple.getClass() is ${tuple.getClass()}" - assert tuple.size() >= 2 : - "Error in module '${key_}': expected length of tuple in input channel to be two or greater.\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: tuple.size() == ${tuple.size()}" - - // check id field - if (tuple[0] instanceof GString) { - tuple[0] = tuple[0].toString() - } - assert tuple[0] instanceof CharSequence : - "Error in module '${key_}': first element of tuple in channel should be a String\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: ${tuple[0]}" - - // match file to input file - if (workflowArgs.auto.simplifyInput && (tuple[1] instanceof Path || tuple[1] instanceof List)) { - def inputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - - assert inputFiles.size() == 1 : - "Error in module '${key_}' id '${tuple[0]}'.\n" + - " Anonymous file inputs are only allowed when the process has exactly one file input.\n" + - " Expected: inputFiles.size() == 1. Found: inputFiles.size() is ${inputFiles.size()}" - - tuple[1] = [[ inputFiles[0].plainName, tuple[1] ]].collectEntries() - } - - // check data field - assert tuple[1] instanceof Map : - "Error in module '${key_}' id '${tuple[0]}': second element of tuple in channel should be a Map\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // rename keys of data field in tuple - if (workflowArgs.renameKeys) { - assert workflowArgs.renameKeys instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class: Map. Found: renameKeys.getClass() is ${workflowArgs.renameKeys.getClass()}" - assert tuple[1] instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // TODO: allow renameKeys to be a function? - workflowArgs.renameKeys.each { newKey, oldKey -> - assert newKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of newKey: String. Found: newKey.getClass() is ${newKey.getClass()}" - assert oldKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of oldKey: String. Found: oldKey.getClass() is ${oldKey.getClass()}" - assert tuple[1].containsKey(oldKey) : - "Error renaming data keys in module '${key}' id '${tuple[0]}'.\n" + - " Key '$oldKey' is missing in the data map. tuple[1].keySet() is '${tuple[1].keySet()}'" - tuple[1].put(newKey, tuple[1][oldKey]) - } - tuple[1].keySet().removeAll(workflowArgs.renameKeys.collect{ newKey, oldKey -> oldKey }) - } - tuple - } - - def chModifiedFiltered = workflowArgs.filter ? - chModified | filter{workflowArgs.filter(it)} : - chModified - - def chRun = null - def chPassthrough = null - if (workflowArgs.runIf) { - def runIfBranch = chModifiedFiltered.branch{ tup -> - run: workflowArgs.runIf(tup[0], tup[1]) - passthrough: true - } - chRun = runIfBranch.run - chPassthrough = runIfBranch.passthrough - } else { - chRun = chModifiedFiltered - chPassthrough = Channel.empty() - } - - def chArgs = workflowArgs.fromState ? - chRun | map{ - def new_data = workflowArgs.fromState(it.take(2)) - [it[0], new_data] - } : - chRun | map {tup -> tup.take(2)} - - // fill in defaults - def chArgsWithDefaults = chArgs - | map { tuple -> - def id_ = tuple[0] - def data_ = tuple[1] - - // TODO: could move fromState to here - - // fetch default params from functionality - def defaultArgs = meta.config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - // fetch overrides in params - def paramArgs = meta.config.allArguments - .findAll { par -> - def argKey = key_ + "__" + par.plainName - params.containsKey(argKey) - } - .collectEntries { [ it.plainName, params[key_ + "__" + it.plainName] ] } - - // fetch overrides in data - def dataArgs = meta.config.allArguments - .findAll { data_.containsKey(it.plainName) } - .collectEntries { [ it.plainName, data_[it.plainName] ] } - - // combine params - def combinedArgs = defaultArgs + paramArgs + workflowArgs.args + dataArgs - - // remove arguments with explicit null values - combinedArgs - .removeAll{_, val -> val == null || val == "viash_no_value" || val == "force_null"} - - combinedArgs = _processInputValues(combinedArgs, meta.config, id_, key_) - - [id_, combinedArgs] + tuple.drop(2) - } - - // TODO: move some of the _meta.join_id wrangling to the safeJoin() function. - def chInitialOutput = chArgsWithDefaults - | _debug(workflowArgs, "processed") - // run workflow - | innerWorkflowFactory(workflowArgs) - // check output tuple - | map { id_, output_ -> - - // see if output map contains metadata - def meta_ = - output_ instanceof Map && output_.containsKey("_meta") ? - output_["_meta"] : - [:] - def join_id = meta_.join_id ?: id_ - - // remove metadata - output_ = output_.findAll{k, v -> k != "_meta"} - - // check value types - output_ = _processOutputValues(output_, meta.config, id_, key_) - - // simplify output if need be - if (workflowArgs.auto.simplifyOutput && output_.size() == 1) { - output_ = output_.values()[0] - } - - [join_id, id_, output_] - } - // | view{"chInitialOutput: ${it.take(3)}"} - - // join the output [prev_id, new_id, output] with the previous state [prev_id, state, ...] - def chNewState = safeJoin(chInitialOutput, chModifiedFiltered, key_) - // input tuple format: [join_id, id, output, prev_state, ...] - // output tuple format: [join_id, id, new_state, ...] - | map{ tup -> - def new_state = workflowArgs.toState(tup.drop(1).take(3)) - tup.take(2) + [new_state] + tup.drop(4) - } - - if (workflowArgs.auto.publish == "state") { - def chPublish = chNewState - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [join_id, id, new_state] - | map{ tup -> - tup.take(3) - } - - safeJoin(chPublish, chArgsWithDefaults, key_) - // input tuple format: [join_id, id, new_state, orig_state, ...] - // output tuple format: [id, new_state, orig_state] - | map { tup -> - tup.drop(1).take(3) - } - | publishStatesByConfig(key: key_, config: meta.config) - } - - // remove join_id and meta - chReturn = chNewState - | map { tup -> - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [id, new_state, ...] - tup.drop(1) - } - | _debug(workflowArgs, "output") - | concat(chPassthrough) - - emit: chReturn - } - - def wf = workflowInstance.cloneWithName(key_) - - // add factory function - wf.metaClass.run = { runArgs -> - workflowFactory(runArgs, workflowArgs, meta) - } - // add config to module for later introspection - wf.metaClass.config = meta.config - - return wf -} - -nextflow.enable.dsl=2 - -// START COMPONENT-SPECIFIC CODE - -// create meta object -meta = [ - "resources_dir": moduleDir.toRealPath().normalize(), - "config": processConfig(readJsonBlob('''{ - "name" : "samtools_index", - "namespace" : "samtools", - "version" : "v0.1.0", - "argument_groups" : [ - { - "name" : "Inputs", - "arguments" : [ - { - "type" : "file", - "name" : "--input", - "description" : "Input file name", - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Outputs", - "arguments" : [ - { - "type" : "file", - "name" : "--output", - "alternatives" : [ - "-o" - ], - "description" : "Output file name", - "example" : [ - "out.bam.bai" - ], - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "output", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Options", - "arguments" : [ - { - "type" : "boolean_true", - "name" : "--bai", - "alternatives" : [ - "-b" - ], - "description" : "Generate BAM index", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--csi", - "alternatives" : [ - "-c" - ], - "description" : "Create a CSI index for BAM files instead of the traditional BAI \nindex. This will be required for genomes with larger chromosome \nsizes.\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--min_shift", - "alternatives" : [ - "-m" - ], - "description" : "Create a CSI index, with a minimum interval size of 2^INT.\n", - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - } - ], - "resources" : [ - { - "type" : "bash_script", - "path" : "script.sh", - "is_executable" : true - } - ], - "description" : "Index SAM/BAM/CRAM files.", - "test_resources" : [ - { - "type" : "bash_script", - "path" : "test.sh", - "is_executable" : true - }, - { - "type" : "file", - "path" : "test_data" - } - ], - "status" : "enabled", - "requirements" : { - "commands" : [ - "ps" - ] - }, - "keywords" : [ - "index", - "bam", - "sam", - "cram" - ], - "license" : "MIT/Expat", - "references" : { - "doi" : [ - "10.1093/bioinformatics/btp352", - "10.1093/gigascience/giab008" - ] - }, - "links" : { - "repository" : "https://github.com/samtools/samtools", - "homepage" : "https://www.htslib.org/", - "documentation" : "https://www.htslib.org/doc/samtools-index.html" - }, - "runners" : [ - { - "type" : "executable", - "id" : "executable", - "docker_setup_strategy" : "ifneedbepullelsecachedbuild" - }, - { - "type" : "nextflow", - "id" : "nextflow", - "directives" : { - "tag" : "$id" - }, - "auto" : { - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false - }, - "config" : { - "labels" : { - "mem1gb" : "memory = 1000000000.B", - "mem2gb" : "memory = 2000000000.B", - "mem5gb" : "memory = 5000000000.B", - "mem10gb" : "memory = 10000000000.B", - "mem20gb" : "memory = 20000000000.B", - "mem50gb" : "memory = 50000000000.B", - "mem100gb" : "memory = 100000000000.B", - "mem200gb" : "memory = 200000000000.B", - "mem500gb" : "memory = 500000000000.B", - "mem1tb" : "memory = 1000000000000.B", - "mem2tb" : "memory = 2000000000000.B", - "mem5tb" : "memory = 5000000000000.B", - "mem10tb" : "memory = 10000000000000.B", - "mem20tb" : "memory = 20000000000000.B", - "mem50tb" : "memory = 50000000000000.B", - "mem100tb" : "memory = 100000000000000.B", - "mem200tb" : "memory = 200000000000000.B", - "mem500tb" : "memory = 500000000000000.B", - "mem1gib" : "memory = 1073741824.B", - "mem2gib" : "memory = 2147483648.B", - "mem4gib" : "memory = 4294967296.B", - "mem8gib" : "memory = 8589934592.B", - "mem16gib" : "memory = 17179869184.B", - "mem32gib" : "memory = 34359738368.B", - "mem64gib" : "memory = 68719476736.B", - "mem128gib" : "memory = 137438953472.B", - "mem256gib" : "memory = 274877906944.B", - "mem512gib" : "memory = 549755813888.B", - "mem1tib" : "memory = 1099511627776.B", - "mem2tib" : "memory = 2199023255552.B", - "mem4tib" : "memory = 4398046511104.B", - "mem8tib" : "memory = 8796093022208.B", - "mem16tib" : "memory = 17592186044416.B", - "mem32tib" : "memory = 35184372088832.B", - "mem64tib" : "memory = 70368744177664.B", - "mem128tib" : "memory = 140737488355328.B", - "mem256tib" : "memory = 281474976710656.B", - "mem512tib" : "memory = 562949953421312.B", - "cpu1" : "cpus = 1", - "cpu2" : "cpus = 2", - "cpu5" : "cpus = 5", - "cpu10" : "cpus = 10", - "cpu20" : "cpus = 20", - "cpu50" : "cpus = 50", - "cpu100" : "cpus = 100", - "cpu200" : "cpus = 200", - "cpu500" : "cpus = 500", - "cpu1000" : "cpus = 1000" - } - }, - "debug" : false, - "container" : "docker" - } - ], - "engines" : [ - { - "type" : "docker", - "id" : "docker", - "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", - "target_registry" : "images.viash-hub.com", - "target_tag" : "v0.1.0", - "namespace_separator" : "/", - "setup" : [ - { - "type" : "docker", - "run" : [ - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\\\nsed 's#Using ##;s# \\\\([0-9\\\\.]*\\\\)$#: \\\\1#' > /var/software_versions.txt\n" - ] - } - ] - }, - { - "type" : "native", - "id" : "native" - } - ], - "build_info" : { - "config" : "/workdir/root/repo/src/samtools/samtools_index/config.vsh.yaml", - "runner" : "nextflow", - "engine" : "docker|native", - "output" : "target/nextflow/samtools/samtools_index", - "viash_version" : "0.9.0-RC6", - "git_commit" : "b84b29747d0635f2ac83ea63b496be9a9edb6724", - "git_remote" : "https://github.com/viash-hub/biobox" - }, - "package_config" : { - "name" : "biobox", - "version" : "v0.1.0", - "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC6", - "source" : "src", - "target" : "target", - "config_mods" : [ - ".requirements.commands := ['ps']\n", - ".engines += { type: \\"native\\" }", - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - ], - "keywords" : [ - "bioinformatics", - "modules", - "sequencing" - ], - "license" : "MIT", - "organization" : "vsh", - "links" : { - "repository" : "https://github.com/viash-hub/biobox", - "issue_tracker" : "https://github.com/viash-hub/biobox/issues" - } - } -}''')) -] - -// resolve dependencies dependencies (if any) - - -// inner workflow -// inner workflow hook -def innerWorkflowFactory(args) { - def rawScript = '''set -e -tempscript=".viash_script.sh" -cat > "$tempscript" << VIASHMAIN -#!/bin/bash - -## VIASH START -# The following code has been auto-generated by Viash. -$( if [ ! -z ${VIASH_PAR_INPUT+x} ]; then echo "${VIASH_PAR_INPUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_input='&'#" ; else echo "# par_input="; fi ) -$( if [ ! -z ${VIASH_PAR_OUTPUT+x} ]; then echo "${VIASH_PAR_OUTPUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_output='&'#" ; else echo "# par_output="; fi ) -$( if [ ! -z ${VIASH_PAR_BAI+x} ]; then echo "${VIASH_PAR_BAI}" | sed "s#'#'\\"'\\"'#g;s#.*#par_bai='&'#" ; else echo "# par_bai="; fi ) -$( if [ ! -z ${VIASH_PAR_CSI+x} ]; then echo "${VIASH_PAR_CSI}" | sed "s#'#'\\"'\\"'#g;s#.*#par_csi='&'#" ; else echo "# par_csi="; fi ) -$( if [ ! -z ${VIASH_PAR_MIN_SHIFT+x} ]; then echo "${VIASH_PAR_MIN_SHIFT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_min_shift='&'#" ; else echo "# par_min_shift="; fi ) -$( if [ ! -z ${VIASH_META_NAME+x} ]; then echo "${VIASH_META_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_name='&'#" ; else echo "# meta_name="; fi ) -$( if [ ! -z ${VIASH_META_FUNCTIONALITY_NAME+x} ]; then echo "${VIASH_META_FUNCTIONALITY_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_functionality_name='&'#" ; else echo "# meta_functionality_name="; fi ) -$( if [ ! -z ${VIASH_META_RESOURCES_DIR+x} ]; then echo "${VIASH_META_RESOURCES_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_resources_dir='&'#" ; else echo "# meta_resources_dir="; fi ) -$( if [ ! -z ${VIASH_META_EXECUTABLE+x} ]; then echo "${VIASH_META_EXECUTABLE}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_executable='&'#" ; else echo "# meta_executable="; fi ) -$( if [ ! -z ${VIASH_META_CONFIG+x} ]; then echo "${VIASH_META_CONFIG}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_config='&'#" ; else echo "# meta_config="; fi ) -$( if [ ! -z ${VIASH_META_TEMP_DIR+x} ]; then echo "${VIASH_META_TEMP_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_temp_dir='&'#" ; else echo "# meta_temp_dir="; fi ) -$( if [ ! -z ${VIASH_META_CPUS+x} ]; then echo "${VIASH_META_CPUS}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_cpus='&'#" ; else echo "# meta_cpus="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_B+x} ]; then echo "${VIASH_META_MEMORY_B}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_b='&'#" ; else echo "# meta_memory_b="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KB+x} ]; then echo "${VIASH_META_MEMORY_KB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kb='&'#" ; else echo "# meta_memory_kb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MB+x} ]; then echo "${VIASH_META_MEMORY_MB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mb='&'#" ; else echo "# meta_memory_mb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GB+x} ]; then echo "${VIASH_META_MEMORY_GB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gb='&'#" ; else echo "# meta_memory_gb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TB+x} ]; then echo "${VIASH_META_MEMORY_TB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tb='&'#" ; else echo "# meta_memory_tb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PB+x} ]; then echo "${VIASH_META_MEMORY_PB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pb='&'#" ; else echo "# meta_memory_pb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KIB+x} ]; then echo "${VIASH_META_MEMORY_KIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kib='&'#" ; else echo "# meta_memory_kib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MIB+x} ]; then echo "${VIASH_META_MEMORY_MIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mib='&'#" ; else echo "# meta_memory_mib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GIB+x} ]; then echo "${VIASH_META_MEMORY_GIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gib='&'#" ; else echo "# meta_memory_gib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TIB+x} ]; then echo "${VIASH_META_MEMORY_TIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tib='&'#" ; else echo "# meta_memory_tib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PIB+x} ]; then echo "${VIASH_META_MEMORY_PIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pib='&'#" ; else echo "# meta_memory_pib="; fi ) - -## VIASH END - -set -e -[[ "\\$par_multiple" == "false" ]] && unset par_multiple -[[ "\\$par_bai" == "false" ]] && unset par_bai -[[ "\\$par_csi" == "false" ]] && unset par_csi -[[ "\\$par_multiple" == "false" ]] && unset par_multiple - -samtools index \\\\ - "\\$par_input" \\\\ - \\${par_csi:+-c} \\\\ - \\${par_bai:+-b} \\\\ - \\${par_min_shift:+-m "par_min_shift"} \\\\ - \\${par_multiple:+-M} \\\\ - -o "\\$par_output" -VIASHMAIN -bash "$tempscript" -''' - - return vdsl3WorkflowFactory(args, meta, rawScript) -} - - - -/** - * Generate a workflow for VDSL3 modules. - * - * This function is called by the workflowFactory() function. - * - * Input channel: [id, input_map] - * Output channel: [id, output_map] - * - * Internally, this workflow will convert the input channel - * to a format which the Nextflow module will be able to handle. - */ -def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { - def key = args["key"] - def processObj = null - - workflow processWf { - take: input_ - main: - - if (processObj == null) { - processObj = _vdsl3ProcessFactory(args, meta, rawScript) - } - - output_ = input_ - | map { tuple -> - def id = tuple[0] - def data_ = tuple[1] - - if (workflow.stubRun) { - // add id if missing - data_ = [id: 'stub'] + data_ - } - - // process input files separately - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { par -> - def val = data_.containsKey(par.plainName) ? data_[par.plainName] : [] - def inputFiles = [] - if (val == null) { - inputFiles = [] - } else if (val instanceof List) { - inputFiles = val - } else if (val instanceof Path) { - inputFiles = [ val ] - } else { - inputFiles = [] - } - if (!workflow.stubRun) { - // throw error when an input file doesn't exist - inputFiles.each{ file -> - assert file.exists() : - "Error in module '${key}' id '${id}' argument '${par.plainName}'.\n" + - " Required input file does not exist.\n" + - " Path: '$file'.\n" + - " Expected input file to exist" - } - } - inputFiles - } - - // remove input files - def argsExclInputFiles = meta.config.allArguments - .findAll { (it.type != "file" || it.direction != "input") && data_.containsKey(it.plainName) } - .collectEntries { par -> - def parName = par.plainName - def val = data_[parName] - if (par.multiple && val instanceof Collection) { - val = val.join(par.multiple_sep) - } - if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) - } - [parName, val] - } - - [ id ] + inputPaths + [ argsExclInputFiles, meta.resources_dir ] - } - | processObj - | map { output -> - def outputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .indexed() - .collectEntries{ index, par -> - def out = output[index + 1] - // strip dummy '.exitcode' file from output (see nextflow-io/nextflow#2678) - if (!out instanceof List || out.size() <= 1) { - if (par.multiple) { - out = [] - } else { - assert !par.required : - "Error in module '${key}' id '${output[0]}' argument '${par.plainName}'.\n" + - " Required output file is missing" - out = null - } - } else if (out.size() == 2 && !par.multiple) { - out = out[1] - } else { - out = out.drop(1) - } - [ par.plainName, out ] - } - - // drop null outputs - outputFiles.removeAll{it.value == null} - - [ output[0], outputFiles ] - } - emit: output_ - } - - return processWf -} - -// depends on: session? -def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { - // autodetect process key - def wfKey = workflowArgs["key"] - def procKeyPrefix = "${wfKey}_process" - def scriptMeta = nextflow.script.ScriptMeta.current() - def existing = scriptMeta.getProcessNames().findAll{it.startsWith(procKeyPrefix)} - def numbers = existing.collect{it.replace(procKeyPrefix, "0").toInteger()} - def newNumber = (numbers + [-1]).max() + 1 - - def procKey = newNumber == 0 ? procKeyPrefix : "$procKeyPrefix$newNumber" - - if (newNumber > 0) { - log.warn "Key for module '${wfKey}' is duplicated.\n", - "If you run a component multiple times in the same workflow,\n" + - "it's recommended you set a unique key for every call,\n" + - "for example: ${wfKey}.run(key: \"foo\")." - } - - // subset directives and convert to list of tuples - def drctv = workflowArgs.directives - - // TODO: unit test the two commands below - // convert publish array into tags - def valueToStr = { val -> - // ignore closures - if (val instanceof CharSequence) { - if (!val.matches('^[{].*[}]$')) { - '"' + val + '"' - } else { - val - } - } else if (val instanceof List) { - "[" + val.collect{valueToStr(it)}.join(", ") + "]" - } else if (val instanceof Map) { - "[" + val.collect{k, v -> k + ": " + valueToStr(v)}.join(", ") + "]" - } else { - val.inspect() - } - } - - // multiple entries allowed: label, publishdir - def drctvStrs = drctv.collect { key, value -> - if (key in ["label", "publishDir"]) { - value.collect{ val -> - if (val instanceof Map) { - "\n$key " + val.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else if (val == null) { - "" - } else { - "\n$key " + valueToStr(val) - } - }.join() - } else if (value instanceof Map) { - "\n$key " + value.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else { - "\n$key " + valueToStr(value) - } - }.join() - - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { ', path(viash_par_' + it.plainName + ', stageAs: "_viash_par/' + it.plainName + '_?/*")' } - .join() - - def outputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - // insert dummy into every output (see nextflow-io/nextflow#2678) - if (!par.multiple) { - ', path{[".exitcode", args.' + par.plainName + ']}' - } else { - ', path{[".exitcode"] + args.' + par.plainName + '}' - } - } - .join() - - // TODO: move this functionality somewhere else? - if (workflowArgs.auto.transcript) { - outputPaths = outputPaths + ', path{[".exitcode", ".command*"]}' - } else { - outputPaths = outputPaths + ', path{[".exitcode"]}' - } - - // create dirs for output files (based on BashWrapper.createParentFiles) - def createParentStr = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" && it.create_parent } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // construct inputFileExports - def inputFileExports = meta.config.allArguments - .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } - .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" - } - - // NOTE: if using docker, use /tmp instead of tmpDir! - def tmpDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('VIASH_TMPDIR') ?: - System.getenv('VIASH_TEMPDIR') ?: - System.getenv('VIASH_TMP') ?: - System.getenv('TEMP') ?: - System.getenv('TMPDIR') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMP') ?: - '/tmp' - ).toAbsolutePath() - - // construct stub - def stub = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"touch2 \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"].replace(\"_*\", \"_0\") : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // escape script - def escapedScript = rawScript.replace('\\', '\\\\').replace('$', '\\$').replace('"""', '\\"\\"\\"') - - // publishdir assert - def assertStr = (workflowArgs.auto.publish == true) || workflowArgs.auto.transcript ? - """\nassert task.publishDir.size() > 0: "if auto.publish is true, params.publish_dir needs to be defined.\\n Example: --publish_dir './output/'" """ : - "" - - // generate process string - def procStr = - """nextflow.enable.dsl=2 - | - |process $procKey {$drctvStrs - |input: - | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") - |output: - | tuple val("\$id")$outputPaths, optional: true - |stub: - |\"\"\" - |touch2() { mkdir -p "\\\$(dirname "\\\$1")" && touch "\\\$1" ; } - |$stub - |\"\"\" - |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } - |def parInject = args - | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} - | .join("\\n") - |\"\"\" - |# meta exports - |export VIASH_META_RESOURCES_DIR="\${resourcesDir}" - |export VIASH_META_TEMP_DIR="${['docker', 'podman', 'charliecloud'].any{ it == workflow.containerEngine } ? '/tmp' : tmpDir}" - |export VIASH_META_NAME="${meta.config.name}" - |# export VIASH_META_EXECUTABLE="\\\$VIASH_META_RESOURCES_DIR/\\\$VIASH_META_NAME" - |export VIASH_META_CONFIG="\\\$VIASH_META_RESOURCES_DIR/.config.vsh.yaml" - |\${task.cpus ? "export VIASH_META_CPUS=\$task.cpus" : "" } - |\${task.memory?.bytes != null ? "export VIASH_META_MEMORY_B=\$task.memory.bytes" : "" } - |if [ ! -z \\\${VIASH_META_MEMORY_B+x} ]; then - | export VIASH_META_MEMORY_KB=\\\$(( (\\\$VIASH_META_MEMORY_B+999) / 1000 )) - | export VIASH_META_MEMORY_MB=\\\$(( (\\\$VIASH_META_MEMORY_KB+999) / 1000 )) - | export VIASH_META_MEMORY_GB=\\\$(( (\\\$VIASH_META_MEMORY_MB+999) / 1000 )) - | export VIASH_META_MEMORY_TB=\\\$(( (\\\$VIASH_META_MEMORY_GB+999) / 1000 )) - | export VIASH_META_MEMORY_PB=\\\$(( (\\\$VIASH_META_MEMORY_TB+999) / 1000 )) - | export VIASH_META_MEMORY_KIB=\\\$(( (\\\$VIASH_META_MEMORY_B+1023) / 1024 )) - | export VIASH_META_MEMORY_MIB=\\\$(( (\\\$VIASH_META_MEMORY_KIB+1023) / 1024 )) - | export VIASH_META_MEMORY_GIB=\\\$(( (\\\$VIASH_META_MEMORY_MIB+1023) / 1024 )) - | export VIASH_META_MEMORY_TIB=\\\$(( (\\\$VIASH_META_MEMORY_GIB+1023) / 1024 )) - | export VIASH_META_MEMORY_PIB=\\\$(( (\\\$VIASH_META_MEMORY_TIB+1023) / 1024 )) - |fi - | - |# meta synonyms - |export VIASH_TEMP="\\\$VIASH_META_TEMP_DIR" - |export TEMP_DIR="\\\$VIASH_META_TEMP_DIR" - | - |# create output dirs if need be - |function mkdir_parent { - | for file in "\\\$@"; do - | mkdir -p "\\\$(dirname "\\\$file")" - | done - |} - |$createParentStr - | - |# argument exports${inputFileExports.join()} - |\$parInject - | - |# process script - |${escapedScript} - |\"\"\" - |} - |""".stripMargin() - - // TODO: print on debug - // if (workflowArgs.debug == true) { - // println("######################\n$procStr\n######################") - // } - - // write process to temp file - def tempFile = java.nio.file.Files.createTempFile("viash-process-${procKey}-", ".nf") - addShutdownHook { java.nio.file.Files.deleteIfExists(tempFile) } - tempFile.text = procStr - - // create process from temp file - def binding = new nextflow.script.ScriptBinding([:]) - def session = nextflow.Nextflow.getSession() - def parser = new nextflow.script.ScriptParser(session) - .setModule(true) - .setBinding(binding) - def moduleScript = parser.runScript(tempFile) - .getScript() - - // register module in meta - def module = new nextflow.script.IncludeDef.Module(name: procKey) - scriptMeta.addModule(moduleScript, module.name, module.alias) - - // retrieve and return process from meta - return scriptMeta.getProcess(procKey) -} - -// defaults -meta["defaults"] = [ - // key to be used to trace the process and determine output names - key: null, - - // fixed arguments to be passed to script - args: [:], - - // default directives - directives: readJsonBlob('''{ - "container" : { - "registry" : "images.viash-hub.com", - "image" : "vsh/biobox/samtools/samtools_index", - "tag" : "v0.1.0" - }, - "tag" : "$id" -}'''), - - // auto settings - auto: readJsonBlob('''{ - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false -}'''), - - // Apply a map over the incoming tuple - // Example: `{ tup -> [ tup[0], [input: tup[1].output] ] + tup.drop(2) }` - map: null, - - // Apply a map over the ID element of a tuple (i.e. the first element) - // Example: `{ id -> id + "_foo" }` - mapId: null, - - // Apply a map over the data element of a tuple (i.e. the second element) - // Example: `{ data -> [ input: data.output ] }` - mapData: null, - - // Apply a map over the passthrough elements of a tuple (i.e. the tuple excl. the first two elements) - // Example: `{ pt -> pt.drop(1) }` - mapPassthrough: null, - - // Filter the channel - // Example: `{ tup -> tup[0] == "foo" }` - filter: null, - - // Choose whether or not to run the component on the tuple if the condition is true. - // Otherwise, the tuple will be passed through. - // Example: `{ tup -> tup[0] != "skip_this" }` - runIf: null, - - // Rename keys in the data field of the tuple (i.e. the second element) - // Will likely be deprecated in favour of `fromState`. - // Example: `[ "new_key": "old_key" ]` - renameKeys: null, - - // Fetch data from the state and pass it to the module without altering the current state. - // - // `fromState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be passed to the module as is. - // - If it is a `List[String]`, the data will be the values of the state at the given keys. - // - If it is a `Map[String, String]`, the data will be the values of the state at the given keys, with the keys renamed according to the map. - // - If it is a function, the tuple (`[id, state]`) in the channel will be passed to the function, and the result will be used as the data. - // - // Example: `{ id, state -> [input: state.fastq_file] }` - // Default: `null` - fromState: null, - - // Determine how the state should be updated after the module has been run. - // - // `toState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be replaced with the output of the module. - // - If it is a `List[String]`, the state will be updated with the values of the data at the given keys. - // - If it is a `Map[String, String]`, the state will be updated with the values of the data at the given keys, with the keys renamed according to the map. - // - If it is a function, a tuple (`[id, output, state]`) will be passed to the function, and the result will be used as the new state. - // - // Example: `{ id, output, state -> state + [counts: state.output] }` - // Default: `{ id, output, state -> output }` - toState: null, - - // Whether or not to print debug messages - // Default: `false` - debug: false -] - -// initialise default workflow -meta["workflow"] = workflowFactory([key: meta.config.name], meta.defaults, meta) - -// add workflow to environment -nextflow.script.ScriptMeta.current().addDefinition(meta.workflow) - -// anonymous workflow for running this module as a standalone -workflow { - // add id argument if it's not already in the config - // TODO: deep copy - def newConfig = deepClone(meta.config) - def newParams = deepClone(params) - - def argsContainsId = newConfig.allArguments.any{it.plainName == "id"} - if (!argsContainsId) { - def idArg = [ - 'name': '--id', - 'required': false, - 'type': 'string', - 'description': 'A unique id for every entry.', - 'multiple': false - ] - newConfig.arguments.add(0, idArg) - newConfig = processConfig(newConfig) - } - if (!newParams.containsKey("id")) { - newParams.id = "run" - } - - helpMessage(newConfig) - - channelFromParams(newParams, newConfig) - // make sure id is not in the state if id is not in the args - | map {id, state -> - if (!argsContainsId) { - [id, state.findAll{k, v -> k != "id"}] - } else { - [id, state] - } - } - | meta.workflow.run( - auto: [ publish: "state" ] - ) -} - -// END COMPONENT-SPECIFIC CODE diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/nextflow.config deleted file mode 100644 index c4359c1..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/nextflow.config +++ /dev/null @@ -1,125 +0,0 @@ -manifest { - name = 'samtools/samtools_index' - mainScript = 'main.nf' - nextflowVersion = '!>=20.12.1-edge' - version = 'v0.1.0' - description = 'Index SAM/BAM/CRAM files.' -} - -process.container = 'nextflow/bash:latest' - -// detect tempdir -tempDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMPDIR') ?: - '/tmp' -).toAbsolutePath() - -profiles { - no_publish { - process { - withName: '.*' { - publishDir = [ - enabled: false - ] - } - } - } - mount_temp { - docker.temp = tempDir - podman.temp = tempDir - charliecloud.temp = tempDir - } - docker { - docker.enabled = true - // docker.userEmulation = true - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - singularity { - singularity.enabled = true - singularity.autoMounts = true - docker.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - podman { - podman.enabled = true - docker.enabled = false - singularity.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - shifter { - shifter.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - charliecloud.enabled = false - } - charliecloud { - charliecloud.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - } -} - -process{ - withLabel: mem1gb { memory = 1000000000.B } - withLabel: mem2gb { memory = 2000000000.B } - withLabel: mem5gb { memory = 5000000000.B } - withLabel: mem10gb { memory = 10000000000.B } - withLabel: mem20gb { memory = 20000000000.B } - withLabel: mem50gb { memory = 50000000000.B } - withLabel: mem100gb { memory = 100000000000.B } - withLabel: mem200gb { memory = 200000000000.B } - withLabel: mem500gb { memory = 500000000000.B } - withLabel: mem1tb { memory = 1000000000000.B } - withLabel: mem2tb { memory = 2000000000000.B } - withLabel: mem5tb { memory = 5000000000000.B } - withLabel: mem10tb { memory = 10000000000000.B } - withLabel: mem20tb { memory = 20000000000000.B } - withLabel: mem50tb { memory = 50000000000000.B } - withLabel: mem100tb { memory = 100000000000000.B } - withLabel: mem200tb { memory = 200000000000000.B } - withLabel: mem500tb { memory = 500000000000000.B } - withLabel: mem1gib { memory = 1073741824.B } - withLabel: mem2gib { memory = 2147483648.B } - withLabel: mem4gib { memory = 4294967296.B } - withLabel: mem8gib { memory = 8589934592.B } - withLabel: mem16gib { memory = 17179869184.B } - withLabel: mem32gib { memory = 34359738368.B } - withLabel: mem64gib { memory = 68719476736.B } - withLabel: mem128gib { memory = 137438953472.B } - withLabel: mem256gib { memory = 274877906944.B } - withLabel: mem512gib { memory = 549755813888.B } - withLabel: mem1tib { memory = 1099511627776.B } - withLabel: mem2tib { memory = 2199023255552.B } - withLabel: mem4tib { memory = 4398046511104.B } - withLabel: mem8tib { memory = 8796093022208.B } - withLabel: mem16tib { memory = 17592186044416.B } - withLabel: mem32tib { memory = 35184372088832.B } - withLabel: mem64tib { memory = 70368744177664.B } - withLabel: mem128tib { memory = 140737488355328.B } - withLabel: mem256tib { memory = 281474976710656.B } - withLabel: mem512tib { memory = 562949953421312.B } - withLabel: cpu1 { cpus = 1 } - withLabel: cpu2 { cpus = 2 } - withLabel: cpu5 { cpus = 5 } - withLabel: cpu10 { cpus = 10 } - withLabel: cpu20 { cpus = 20 } - withLabel: cpu50 { cpus = 50 } - withLabel: cpu100 { cpus = 100 } - withLabel: cpu200 { cpus = 200 } - withLabel: cpu500 { cpus = 500 } - withLabel: cpu1000 { cpus = 1000 } -} - - diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/nextflow_schema.json deleted file mode 100644 index 38b2492..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/nextflow_schema.json +++ /dev/null @@ -1,141 +0,0 @@ -{ -"$schema": "http://json-schema.org/draft-07/schema", -"title": "samtools_index", -"description": "Index SAM/BAM/CRAM files.", -"type": "object", -"definitions": { - - - - "inputs" : { - "title": "Inputs", - "type": "object", - "description": "No description", - "properties": { - - - "input": { - "type": - "string", - "description": "Type: `file`, required. Input file name", - "help_text": "Type: `file`, required. Input file name" - - } - - -} -}, - - - "outputs" : { - "title": "Outputs", - "type": "object", - "description": "No description", - "properties": { - - - "output": { - "type": - "string", - "description": "Type: `file`, required, default: `$id.$key.output.bai`, example: `out.bam.bai`. Output file name", - "help_text": "Type: `file`, required, default: `$id.$key.output.bai`, example: `out.bam.bai`. Output file name" - , - "default": "$id.$key.output.bai" - } - - -} -}, - - - "options" : { - "title": "Options", - "type": "object", - "description": "No description", - "properties": { - - - "bai": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Generate BAM index", - "help_text": "Type: `boolean_true`, default: `false`. Generate BAM index" - , - "default": "False" - } - - - , - "csi": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Create a CSI index for BAM files instead of the traditional BAI \nindex", - "help_text": "Type: `boolean_true`, default: `false`. Create a CSI index for BAM files instead of the traditional BAI \nindex. This will be required for genomes with larger chromosome \nsizes.\n" - , - "default": "False" - } - - - , - "min_shift": { - "type": - "integer", - "description": "Type: `integer`. Create a CSI index, with a minimum interval size of 2^INT", - "help_text": "Type: `integer`. Create a CSI index, with a minimum interval size of 2^INT.\n" - - } - - -} -}, - - - "nextflow input-output arguments" : { - "title": "Nextflow input-output arguments", - "type": "object", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "properties": { - - - "publish_dir": { - "type": - "string", - "description": "Type: `string`, required, example: `output/`. Path to an output directory", - "help_text": "Type: `string`, required, example: `output/`. Path to an output directory." - - } - - - , - "param_list": { - "type": - "string", - "description": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel", - "help_text": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob.\n\n* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ [\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027], [\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027] ]`.\n* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`.\n* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]`.\n* A yaml blob can also be passed directly as a string. Example: `--param_list \"[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]\"`.\n\nWhen passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.", - "hidden": true - - } - - -} -} -}, -"allOf": [ - - { - "$ref": "#/definitions/inputs" - }, - - { - "$ref": "#/definitions/outputs" - }, - - { - "$ref": "#/definitions/options" - }, - - { - "$ref": "#/definitions/nextflow input-output arguments" - } -] -} diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/.config.vsh.yaml deleted file mode 100644 index ac8efcb..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/.config.vsh.yaml +++ /dev/null @@ -1,344 +0,0 @@ -name: "samtools_sort" -namespace: "samtools" -version: "v0.1.0" -argument_groups: -- name: "Inputs" - arguments: - - type: "file" - name: "--input" - description: "SAM/BAM/CRAM input file." - info: null - must_exist: true - create_parent: true - required: true - direction: "input" - multiple: false - multiple_sep: ";" -- name: "Outputs" - arguments: - - type: "file" - name: "--output" - description: "Write final output to file.\n" - info: null - example: - - "out.bam" - must_exist: true - create_parent: true - required: true - direction: "output" - multiple: false - multiple_sep: ";" - - type: "string" - name: "--output_fmt" - alternatives: - - "-O" - description: "Specify output format (SAM, BAM, CRAM).\n" - info: null - example: - - "BAM" - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "string" - name: "--output_fmt_option" - description: "Specify a single output file format option in the form\nof OPTION\ - \ or OPTION=VALUE.\n" - info: null - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--reference" - description: "Reference sequence FASTA FILE.\n" - info: null - example: - - "ref.fa" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--write_index" - description: "Automatically index the output files.\n" - info: null - direction: "input" - - type: "string" - name: "--prefix" - alternatives: - - "-T" - description: "Write temporary files to PREFIX.nnnn.bam.\n" - info: null - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--no_PG" - description: "Do not add a PG line.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--template_coordinate" - description: "Sort by template-coordinate.\n" - info: null - direction: "input" - - type: "string" - name: "--input_fmt_option" - description: "Specify a single input file format option in the form\nof OPTION\ - \ or OPTION=VALUE.\n" - info: null - required: false - direction: "input" - multiple: false - multiple_sep: ";" -- name: "Options" - arguments: - - type: "integer" - name: "--compression" - alternatives: - - "-l" - description: "Set compression level, from 0 (uncompressed) to 9 (best).\n" - info: null - default: - - 0 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--uncompressed" - alternatives: - - "-u" - description: "Output uncompressed data (equivalent to --compression 0).\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--minimiser" - alternatives: - - "-M" - description: "Use minimiser for clustering unaligned/unplaced reads.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--not_reverse" - alternatives: - - "-R" - description: "Do not use reverse strand (only compatible with --minimiser)\n" - info: null - direction: "input" - - type: "integer" - name: "--kmer_size" - alternatives: - - "-K" - description: "Kmer size to use for minimiser.\n" - info: null - example: - - 20 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--order" - alternatives: - - "-I" - description: "Order minimisers by their position in FILE FASTA.\n" - info: null - example: - - "ref.fa" - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--window" - alternatives: - - "-w" - description: "Window size for minimiser INDEXING VIA --order REF.FA.\n" - info: null - example: - - 100 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--homopolymers" - alternatives: - - "-H" - description: "Squash homopolymers when computing minimiser.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--natural_sort" - alternatives: - - "-n" - description: "Sort by read name (natural): cannot be used with samtools index.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--ascii_sort" - alternatives: - - "-N" - description: "Sort by read name (ASCII): cannot be used with samtools index.\n" - info: null - direction: "input" - - type: "string" - name: "--tag" - alternatives: - - "-t" - description: "Sort by value of TAG. Uses position as secondary index \n(or read\ - \ name if --natural_sort is set).\n" - info: null - required: false - direction: "input" - multiple: false - multiple_sep: ";" -resources: -- type: "bash_script" - path: "script.sh" - is_executable: true -description: "Sort SAM/BAM/CRAM file." -test_resources: -- type: "bash_script" - path: "test.sh" - is_executable: true -- type: "file" - path: "test_data" -info: null -status: "enabled" -requirements: - commands: - - "ps" -keywords: -- "sort" -- "bam" -- "sam" -- "cram" -license: "MIT/Expat" -references: - doi: - - "10.1093/bioinformatics/btp352" - - "10.1093/gigascience/giab008" -links: - repository: "https://github.com/samtools/samtools" - homepage: "https://www.htslib.org/" - documentation: "https://www.htslib.org/doc/samtools-sort.html" -runners: -- type: "executable" - id: "executable" - docker_setup_strategy: "ifneedbepullelsecachedbuild" -- type: "nextflow" - id: "nextflow" - directives: - tag: "$id" - auto: - simplifyInput: true - simplifyOutput: false - transcript: false - publish: false - config: - labels: - mem1gb: "memory = 1000000000.B" - mem2gb: "memory = 2000000000.B" - mem5gb: "memory = 5000000000.B" - mem10gb: "memory = 10000000000.B" - mem20gb: "memory = 20000000000.B" - mem50gb: "memory = 50000000000.B" - mem100gb: "memory = 100000000000.B" - mem200gb: "memory = 200000000000.B" - mem500gb: "memory = 500000000000.B" - mem1tb: "memory = 1000000000000.B" - mem2tb: "memory = 2000000000000.B" - mem5tb: "memory = 5000000000000.B" - mem10tb: "memory = 10000000000000.B" - mem20tb: "memory = 20000000000000.B" - mem50tb: "memory = 50000000000000.B" - mem100tb: "memory = 100000000000000.B" - mem200tb: "memory = 200000000000000.B" - mem500tb: "memory = 500000000000000.B" - mem1gib: "memory = 1073741824.B" - mem2gib: "memory = 2147483648.B" - mem4gib: "memory = 4294967296.B" - mem8gib: "memory = 8589934592.B" - mem16gib: "memory = 17179869184.B" - mem32gib: "memory = 34359738368.B" - mem64gib: "memory = 68719476736.B" - mem128gib: "memory = 137438953472.B" - mem256gib: "memory = 274877906944.B" - mem512gib: "memory = 549755813888.B" - mem1tib: "memory = 1099511627776.B" - mem2tib: "memory = 2199023255552.B" - mem4tib: "memory = 4398046511104.B" - mem8tib: "memory = 8796093022208.B" - mem16tib: "memory = 17592186044416.B" - mem32tib: "memory = 35184372088832.B" - mem64tib: "memory = 70368744177664.B" - mem128tib: "memory = 140737488355328.B" - mem256tib: "memory = 281474976710656.B" - mem512tib: "memory = 562949953421312.B" - cpu1: "cpus = 1" - cpu2: "cpus = 2" - cpu5: "cpus = 5" - cpu10: "cpus = 10" - cpu20: "cpus = 20" - cpu50: "cpus = 50" - cpu100: "cpus = 100" - cpu200: "cpus = 200" - cpu500: "cpus = 500" - cpu1000: "cpus = 1000" - debug: false - container: "docker" -engines: -- type: "docker" - id: "docker" - image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" - target_registry: "images.viash-hub.com" - target_tag: "v0.1.0" - namespace_separator: "/" - setup: - - type: "docker" - run: - - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\nsed 's#Using\ - \ ##;s# \\([0-9\\.]*\\)$#: \\1#' > /var/software_versions.txt\n" - entrypoint: [] - cmd: null -- type: "native" - id: "native" -build_info: - config: "src/samtools/samtools_sort/config.vsh.yaml" - runner: "nextflow" - engine: "docker|native" - output: "target/nextflow/samtools/samtools_sort" - executable: "target/nextflow/samtools/samtools_sort/main.nf" - viash_version: "0.9.0-RC6" - git_commit: "b84b29747d0635f2ac83ea63b496be9a9edb6724" - git_remote: "https://github.com/viash-hub/biobox" -package_config: - name: "biobox" - version: "v0.1.0" - description: "A collection of bioinformatics tools for working with sequence data.\n" - info: null - viash_version: "0.9.0-RC6" - source: "src" - target: "target" - config_mods: - - ".requirements.commands := ['ps']\n" - - ".engines += { type: \"native\" }" - - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - keywords: - - "bioinformatics" - - "modules" - - "sequencing" - license: "MIT" - organization: "vsh" - links: - repository: "https://github.com/viash-hub/biobox" - issue_tracker: "https://github.com/viash-hub/biobox/issues" diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/main.nf b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/main.nf deleted file mode 100644 index 673ac48..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/main.nf +++ /dev/null @@ -1,3775 +0,0 @@ -// samtools_sort v0.1.0 -// -// This wrapper script is auto-generated by viash 0.9.0-RC6 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. -// -// The component may contain files which fall under a different license. The -// authors of this component should specify the license in the header of such -// files, or include a separate license file detailing the licenses of all included -// files. - -//////////////////////////// -// VDSL3 helper functions // -//////////////////////////// - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_checkArgumentType.nf' -class UnexpectedArgumentTypeException extends Exception { - String errorIdentifier - String stage - String plainName - String expectedClass - String foundClass - - // ${key ? " in module '$key'" : ""}${id ? " id '$id'" : ""} - UnexpectedArgumentTypeException(String errorIdentifier, String stage, String plainName, String expectedClass, String foundClass) { - super("Error${errorIdentifier ? " $errorIdentifier" : ""}:${stage ? " $stage" : "" } argument '${plainName}' has the wrong type. " + - "Expected type: ${expectedClass}. Found type: ${foundClass}") - this.errorIdentifier = errorIdentifier - this.stage = stage - this.plainName = plainName - this.expectedClass = expectedClass - this.foundClass = foundClass - } -} - -/** - * Checks if the given value is of the expected type. If not, an exception is thrown. - * - * @param stage The stage of the argument (input or output) - * @param par The parameter definition - * @param value The value to check - * @param errorIdentifier The identifier to use in the error message - * @return The value, if it is of the expected type - * @throws UnexpectedArgumentTypeException If the value is not of the expected type -*/ -def _checkArgumentType(String stage, Map par, Object value, String errorIdentifier) { - // expectedClass will only be != null if value is not of the expected type - def expectedClass = null - def foundClass = null - - // todo: split if need be - - if (!par.required && value == null) { - expectedClass = null - } else if (par.multiple) { - if (value !instanceof Collection) { - value = [value] - } - - // split strings - value = value.collectMany{ val -> - if (val instanceof String) { - // collect() to ensure that the result is a List and not simply an array - val.split(par.multiple_sep).collect() - } else { - [val] - } - } - - // process globs - if (par.type == "file" && par.direction == "input") { - value = value.collect{ it instanceof String ? file(it, hidden: true) : it }.flatten() - } - - // check types of elements in list - try { - value = value.collect { listVal -> - _checkArgumentType(stage, par + [multiple: false], listVal, errorIdentifier) - } - } catch (UnexpectedArgumentTypeException e) { - expectedClass = "List[${e.expectedClass}]" - foundClass = "List[${e.foundClass}]" - } - } else if (par.type == "string") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else if (par.type == "integer") { - // cast to integer if need be - if (value instanceof String) { - try { - value = value.toInteger() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigInteger) { - value = value.intValue() - } - expectedClass = value instanceof Integer ? null : "Integer" - } else if (par.type == "long") { - // cast to long if need be - if (value instanceof String) { - try { - value = value.toLong() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof Integer) { - value = value.toLong() - } - expectedClass = value instanceof Long ? null : "Long" - } else if (par.type == "double") { - // cast to double if need be - if (value instanceof String) { - try { - value = value.toDouble() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigDecimal) { - value = value.doubleValue() - } - if (value instanceof Float) { - value = value.toDouble() - } - expectedClass = value instanceof Double ? null : "Double" - } else if (par.type == "boolean" | par.type == "boolean_true" | par.type == "boolean_false") { - // cast to boolean if need be - if (value instanceof String) { - def valueLower = value.toLowerCase() - if (valueLower == "true") { - value = true - } else if (valueLower == "false") { - value = false - } - } - expectedClass = value instanceof Boolean ? null : "Boolean" - } else if (par.type == "file" && (par.direction == "input" || stage == "output")) { - // cast to path if need be - if (value instanceof String) { - value = file(value, hidden: true) - } - if (value instanceof File) { - value = value.toPath() - } - expectedClass = value instanceof Path ? null : "Path" - } else if (par.type == "file" && stage == "input" && par.direction == "output") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else { - // didn't find a match for par.type - expectedClass = par.type - } - - if (expectedClass != null) { - if (foundClass == null) { - foundClass = value.getClass().getName() - } - throw new UnexpectedArgumentTypeException(errorIdentifier, stage, par.plainName, expectedClass, foundClass) - } - - return value -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processInputValues.nf' -Map _processInputValues(Map inputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.required) { - assert inputs.containsKey(arg.plainName) && inputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required input argument '${arg.plainName}' is missing" - } - } - - inputs = inputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid input argument" - - value = _checkArgumentType("input", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return inputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processOutputValues.nf' -Map _processOutputValues(Map outputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.direction == "output" && arg.required) { - assert outputs.containsKey(arg.plainName) && outputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required output argument '${arg.plainName}' is missing" - } - } - - outputs = outputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && it.direction == "output" } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid output argument" - - value = _checkArgumentType("output", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return outputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/IDChecker.nf' -class IDChecker { - final def items = [] as Set - - @groovy.transform.WithWriteLock - boolean observe(String item) { - if (items.contains(item)) { - return false - } else { - items << item - return true - } - } - - @groovy.transform.WithReadLock - boolean contains(String item) { - return items.contains(item) - } - - @groovy.transform.WithReadLock - Set getItems() { - return items.clone() - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_checkUniqueIds.nf' - -/** - * Check if the ids are unique across parameter sets - * - * @param parameterSets a list of parameter sets. - */ -private void _checkUniqueIds(List>> parameterSets) { - def ppIds = parameterSets.collect{it[0]} - assert ppIds.size() == ppIds.unique().size() : "All argument sets should have unique ids. Detected ids: $ppIds" -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_getChild.nf' - -// helper functions for reading params from file // -def _getChild(parent, child) { - if (child.contains("://") || java.nio.file.Paths.get(child).isAbsolute()) { - child - } else { - def parentAbsolute = java.nio.file.Paths.get(parent).toAbsolutePath().toString() - parentAbsolute.replaceAll('/[^/]*$', "/") + child - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_parseParamList.nf' -/** - * Figure out the param list format based on the file extension - * - * @param param_list A String containing the path to the parameter list file. - * - * @return A String containing the format of the parameter list file. - */ -def _paramListGuessFormat(param_list) { - if (param_list !instanceof String) { - "asis" - } else if (param_list.endsWith(".csv")) { - "csv" - } else if (param_list.endsWith(".json") || param_list.endsWith(".jsn")) { - "json" - } else if (param_list.endsWith(".yaml") || param_list.endsWith(".yml")) { - "yaml" - } else { - "yaml_blob" - } -} - - -/** - * Read the param list - * - * @param param_list One of the following: - * - A String containing the path to the parameter list file (csv, json or yaml), - * - A yaml blob of a list of maps (yaml_blob), - * - Or a groovy list of maps (asis). - * @param config A Map of the Viash configuration. - * - * @return A List of Maps containing the parameters. - */ -def _parseParamList(param_list, Map config) { - // first determine format by extension - def paramListFormat = _paramListGuessFormat(param_list) - - def paramListPath = (paramListFormat != "asis" && paramListFormat != "yaml_blob") ? - file(param_list, hidden: true) : - null - - // get the correct parser function for the detected params_list format - def paramSets = [] - if (paramListFormat == "asis") { - paramSets = param_list - } else if (paramListFormat == "yaml_blob") { - paramSets = readYamlBlob(param_list) - } else if (paramListFormat == "yaml") { - paramSets = readYaml(paramListPath) - } else if (paramListFormat == "json") { - paramSets = readJson(paramListPath) - } else if (paramListFormat == "csv") { - paramSets = readCsv(paramListPath) - } else { - error "Format of provided --param_list not recognised.\n" + - "Found: '$paramListFormat'.\n" + - "Expected: a csv file, a json file, a yaml file,\n" + - "a yaml blob or a groovy list of maps." - } - - // data checks - assert paramSets instanceof List: "--param_list should contain a list of maps" - for (value in paramSets) { - assert value instanceof Map: "--param_list should contain a list of maps" - } - - // id is argument - def idIsArgument = config.allArguments.any{it.plainName == "id"} - - // Reformat from List to List> by adding the ID as first element of a Tuple2 - paramSets = paramSets.collect({ data -> - def id = data.id - if (!idIsArgument) { - data = data.findAll{k, v -> k != "id"} - } - [id, data] - }) - - // Split parameters with 'multiple: true' - paramSets = paramSets.collect({ id, data -> - data = _splitParams(data, config) - [id, data] - }) - - // The paths of input files inside a param_list file may have been specified relatively to the - // location of the param_list file. These paths must be made absolute. - if (paramListPath) { - paramSets = paramSets.collect({ id, data -> - def new_data = data.collectEntries{ parName, parValue -> - def par = config.allArguments.find{it.plainName == parName} - if (par && par.type == "file" && par.direction == "input") { - if (parValue instanceof Collection) { - parValue = parValue.collectMany{path -> - def x = _resolveSiblingIfNotAbsolute(path, paramListPath) - x instanceof Collection ? x : [x] - } - } else { - parValue = _resolveSiblingIfNotAbsolute(parValue, paramListPath) - } - } - [parName, parValue] - } - [id, new_data] - }) - } - - return paramSets -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_splitParams.nf' -/** - * Split parameters for arguments that accept multiple values using their separator - * - * @param paramList A Map containing parameters to split. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A Map of parameters where the parameter values have been split into a list using - * their seperator. - */ -Map _splitParams(Map parValues, Map config){ - def parsedParamValues = parValues.collectEntries { parName, parValue -> - def parameterSettings = config.allArguments.find({it.plainName == parName}) - - if (!parameterSettings) { - // if argument is not found, do not alter - return [parName, parValue] - } - if (parameterSettings.multiple) { // Check if parameter can accept multiple values - if (parValue instanceof Collection) { - parValue = parValue.collect{it instanceof String ? it.split(parameterSettings.multiple_sep) : it } - } else if (parValue instanceof String) { - parValue = parValue.split(parameterSettings.multiple_sep) - } else if (parValue == null) { - parValue = [] - } else { - parValue = [ parValue ] - } - parValue = parValue.flatten() - } - // For all parameters check if multiple values are only passed for - // arguments that allow it. Quietly simplify lists of length 1. - if (!parameterSettings.multiple && parValue instanceof Collection) { - assert parValue.size() == 1 : - "Error: argument ${parName} has too many values.\n" + - " Expected amount: 1. Found: ${parValue.size()}" - parValue = parValue[0] - } - [parName, parValue] - } - return parsedParamValues -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/channelFromParams.nf' -/** - * Parse nextflow parameters based on settings defined in a viash config. - * Return a list of parameter sets, each parameter set corresponding to - * an event in a nextflow channel. The output from this function can be used - * with Channel.fromList to create a nextflow channel with Vdsl3 formatted - * events. - * - * This function performs: - * - A filtering of the params which can be found in the config file. - * - Process the params_list argument which allows a user to to initialise - * a Vsdl3 channel with multiple parameter sets. Possible formats are - * csv, json, yaml, or simply a yaml_blob. A csv should have column names - * which correspond to the different arguments of this pipeline. A json or a yaml - * file should be a list of maps, each of which has keys corresponding to the - * arguments of the pipeline. A yaml blob can also be passed directly as a parameter. - * When passing a csv, json or yaml, relative path names are relativized to the - * location of the parameter file. - * - Combine the parameter sets into a vdsl3 Channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A list of parameters with the first element of the event being - * the event ID and the second element containing a map of the parsed parameters. - */ - -private List>> _paramsToParamSets(Map params, Map config){ - // todo: fetch key from run args - def key_ = config.name - - /* parse regular parameters (not in param_list) */ - /*************************************************/ - def globalParams = config.allArguments - .findAll { params.containsKey(it.plainName) } - .collectEntries { [ it.plainName, params[it.plainName] ] } - def globalID = params.get("id", null) - - /* process params_list arguments */ - /*********************************/ - def paramList = params.containsKey("param_list") && params.param_list != null ? - params.param_list : [] - // if (paramList instanceof String) { - // paramList = [paramList] - // } - // def paramSets = paramList.collectMany{ _parseParamList(it, config) } - // TODO: be able to process param_list when it is a list of strings - def paramSets = _parseParamList(paramList, config) - if (paramSets.isEmpty()) { - paramSets = [[null, [:]]] - } - - /* combine arguments into channel */ - /**********************************/ - def processedParams = paramSets.indexed().collect{ index, tup -> - // Process ID - def id = tup[0] ?: globalID - - if (workflow.stubRun && !id) { - // if stub run, explicitly add an id if missing - id = "stub${index}" - } - assert id != null: "Each parameter set should have at least an 'id'" - - // Process params - def parValues = globalParams + tup[1] - // // Remove parameters which are null, if the default is also null - // parValues = parValues.collectEntries{paramName, paramValue -> - // parameterSettings = config.functionality.allArguments.find({it.plainName == paramName}) - // if ( paramValue != null || parameterSettings.get("default", null) != null ) { - // [paramName, paramValue] - // } - // } - parValues = parValues.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key_}' id '${id}': '${name}' is not a valid input argument" - - if (par == null) { - return [:] - } - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - - [ name, value ] - } - - [id, parValues] - } - - // Check if ids (first element of each list) is unique - _checkUniqueIds(processedParams) - return processedParams -} - -/** - * Parse nextflow parameters based on settings defined in a viash config - * and return a nextflow channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A nextflow Channel with events. Events are formatted as a tuple that contains - * first contains the ID of the event and as second element holds a parameter map. - * - * - */ -def channelFromParams(Map params, Map config) { - def processedParams = _paramsToParamSets(params, config) - return Channel.fromList(processedParams) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/checkUniqueIds.nf' -def checkUniqueIds(Map args) { - def stopOnError = args.stopOnError == null ? args.stopOnError : true - - def idChecker = new IDChecker() - - return filter { tup -> - if (!idChecker.observe(tup[0])) { - if (stopOnError) { - error "Duplicate id: ${tup[0]}" - } else { - log.warn "Duplicate id: ${tup[0]}, removing duplicate entry" - return false - } - } - return true - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/preprocessInputs.nf' -// This helper file will be deprecated soon -preprocessInputsDeprecationWarningPrinted = false - -def preprocessInputsDeprecationWarning() { - if (!preprocessInputsDeprecationWarningPrinted) { - preprocessInputsDeprecationWarningPrinted = true - System.err.println("Warning: preprocessInputs() is deprecated and will be removed in Viash 0.9.0.") - } -} - -/** - * Generate a nextflow Workflow that allows processing a channel of - * Vdsl3 formatted events and apply a Viash config to them: - * - Gather default parameters from the Viash config and make - * sure that they are correctly formatted (see applyConfig method). - * - Format the input parameters (also using the applyConfig method). - * - Apply the default parameter to the input parameters. - * - Do some assertions: - * ~ Check if the event IDs in the channel are unique. - * - * The events in the channel are formatted as tuples, with the - * first element of the tuples being a unique id of the parameter set, - * and the second element containg the the parameters themselves. - * Optional extra elements of the tuples will be passed to the output as is. - * - * @param args A map that must contain a 'config' key that points - * to a parsed config (see readConfig()). Optionally, a - * 'key' key can be provided which can be used to create a unique - * name for the workflow process. - * - * @return A workflow that allows processing a channel of Vdsl3 formatted events - * and apply a Viash config to them. - */ -def preprocessInputs(Map args) { - preprocessInputsDeprecationWarning() - - def config = args.config - assert config instanceof Map : - "Error in preprocessInputs: config must be a map. " + - "Expected class: Map. Found: config.getClass() is ${config.getClass()}" - def key_ = args.key ?: config.name - - // Get different parameter types (used throughout this function) - def defaultArgs = config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - map { tup -> - def id = tup[0] - def data = tup[1] - def passthrough = tup.drop(2) - - def new_data = (defaultArgs + data).collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - - if (par != null) { - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - } - - [ name, value ] - } - - [ id, new_data ] + passthrough - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runComponents.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component config. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component config. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component config. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component config. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runComponents(Map args) { - log.warn("runComponents is deprecated, use runEach instead") - assert args.components: "runComponents should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runComponents" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runComponentsWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def comp_config = comp_.config - - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_config) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - // def new_id = id_(tup[0], tup[1], comp_config) - def new_id = tup[0] - if (id_ instanceof String) { - new_id = id_ - } else if (id_ instanceof Closure) { - new_id = id_(new_id, tup[1], comp_config) - } - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_config) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_config) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runComponentsWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runEach.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component itself. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component itself. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component itself. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component itself. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runEach(Map args) { - assert args.components: "runEach should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runEach" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runEachWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - def new_id = id_ - if (new_id instanceof Closure) { - new_id = new_id(tup[0], tup[1], comp_) - } - assert new_id instanceof String : "Error in runEach: id should be a String or a Closure that returns a String. Expected: id instanceof String. Found: ${new_id.getClass()}" - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runEachWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/safeJoin.nf' -/** - * Join sourceChannel to targetChannel - * - * This function joins the sourceChannel to the targetChannel. - * However, each id in the targetChannel must be present in the - * sourceChannel. If _meta.join_id exists in the targetChannel, that is - * used as an id instead. If the id doesn't match any id in the sourceChannel, - * an error is thrown. - */ - -def safeJoin(targetChannel, sourceChannel, key) { - def sourceIDs = new IDChecker() - - def sourceCheck = sourceChannel - | map { tup -> - sourceIDs.observe(tup[0]) - tup - } - def targetCheck = targetChannel - | map { tup -> - def id = tup[0] - - if (!sourceIDs.contains(id)) { - error ( - "Error in module '${key}' when merging output with original state.\n" + - " Reason: output with id '${id}' could not be joined with source channel.\n" + - " If the IDs in the output channel differ from the input channel,\n" + - " please set `tup[1]._meta.join_id to the original ID.\n" + - " Original IDs in input channel: ['${sourceIDs.getItems().join("', '")}'].\n" + - " Unexpected ID in the output channel: '${id}'.\n" + - " Example input event: [\"id\", [input: file(...)]],\n" + - " Example output event: [\"newid\", [output: file(...), _meta: [join_id: \"id\"]]]" - ) - } - // TODO: add link to our documentation on how to fix this - - tup - } - - sourceCheck.cross(targetChannel) - | map{ left, right -> - right + left.drop(1) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/_processArgument.nf' -def _processArgument(arg) { - arg.multiple = arg.multiple != null ? arg.multiple : false - arg.required = arg.required != null ? arg.required : false - arg.direction = arg.direction != null ? arg.direction : "input" - arg.multiple_sep = arg.multiple_sep != null ? arg.multiple_sep : ";" - arg.plainName = arg.name.replaceAll("^-*", "") - - if (arg.type == "file") { - arg.must_exist = arg.must_exist != null ? arg.must_exist : true - arg.create_parent = arg.create_parent != null ? arg.create_parent : true - } - - // add default values to output files which haven't already got a default - if (arg.type == "file" && arg.direction == "output" && arg.default == null) { - def mult = arg.multiple ? "_*" : "" - def extSearch = "" - if (arg.default != null) { - extSearch = arg.default - } else if (arg.example != null) { - extSearch = arg.example - } - if (extSearch instanceof List) { - extSearch = extSearch[0] - } - def extSearchResult = extSearch.find("\\.[^\\.]+\$") - def ext = extSearchResult != null ? extSearchResult : "" - arg.default = "\$id.\$key.${arg.plainName}${mult}${ext}" - if (arg.multiple) { - arg.default = [arg.default] - } - } - - if (!arg.multiple) { - if (arg.default != null && arg.default instanceof List) { - arg.default = arg.default[0] - } - if (arg.example != null && arg.example instanceof List) { - arg.example = arg.example[0] - } - } - - if (arg.type == "boolean_true") { - arg.default = false - } - if (arg.type == "boolean_false") { - arg.default = true - } - - arg -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/addGlobalParams.nf' -def addGlobalArguments(config) { - def localConfig = [ - "argument_groups": [ - [ - "name": "Nextflow input-output arguments", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "arguments" : [ - [ - 'name': '--publish_dir', - 'required': true, - 'type': 'string', - 'description': 'Path to an output directory.', - 'example': 'output/', - 'multiple': false - ], - [ - 'name': '--param_list', - 'required': false, - 'type': 'string', - 'description': '''Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob. - | - |* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ ['id': 'foo', 'input': 'foo.txt'], ['id': 'bar', 'input': 'bar.txt'] ]`. - |* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`. - |* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]`. - |* A yaml blob can also be passed directly as a string. Example: `--param_list "[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]"`. - | - |When passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.'''.stripMargin(), - 'example': 'my_params.yaml', - 'multiple': false, - 'hidden': true - ] - // TODO: allow multiple: true in param_list? - // TODO: allow to specify a --param_list_regex to filter the param_list? - // TODO: allow to specify a --param_list_from_state to remap entries in the param_list? - ] - ] - ] - ] - - return processConfig(_mergeMap(config, localConfig)) -} - -def _mergeMap(Map lhs, Map rhs) { - return rhs.inject(lhs.clone()) { map, entry -> - if (map[entry.key] instanceof Map && entry.value instanceof Map) { - map[entry.key] = _mergeMap(map[entry.key], entry.value) - } else if (map[entry.key] instanceof Collection && entry.value instanceof Collection) { - map[entry.key] += entry.value - } else { - map[entry.key] = entry.value - } - return map - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/generateHelp.nf' -def _generateArgumentHelp(param) { - // alternatives are not supported - // def names = param.alternatives ::: List(param.name) - - def unnamedProps = [ - ["required parameter", param.required], - ["multiple values allowed", param.multiple], - ["output", param.direction.toLowerCase() == "output"], - ["file must exist", param.type == "file" && param.must_exist] - ].findAll{it[1]}.collect{it[0]} - - def dflt = null - if (param.default != null) { - if (param.default instanceof List) { - dflt = param.default.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - dflt = param.default.toString() - } - } - def example = null - if (param.example != null) { - if (param.example instanceof List) { - example = param.example.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - example = param.example.toString() - } - } - def min = param.min?.toString() - def max = param.max?.toString() - - def escapeChoice = { choice -> - def s1 = choice.replaceAll("\\n", "\\\\n") - def s2 = s1.replaceAll("\"", """\\\"""") - s2.contains(",") || s2 != choice ? "\"" + s2 + "\"" : s2 - } - def choices = param.choices == null ? - null : - "[ " + param.choices.collect{escapeChoice(it.toString())}.join(", ") + " ]" - - def namedPropsStr = [ - ["type", ([param.type] + unnamedProps).join(", ")], - ["default", dflt], - ["example", example], - ["choices", choices], - ["min", min], - ["max", max] - ] - .findAll{it[1]} - .collect{"\n " + it[0] + ": " + it[1].replaceAll("\n", "\\n")} - .join("") - - def descStr = param.description == null ? - "" : - _paragraphWrap("\n" + param.description.trim(), 80 - 8).join("\n ") - - "\n --" + param.plainName + - namedPropsStr + - descStr -} - -// Based on Helper.generateHelp() in Helper.scala -def _generateHelp(config) { - def fun = config - - // PART 1: NAME AND VERSION - def nameStr = fun.name + - (fun.version == null ? "" : " " + fun.version) - - // PART 2: DESCRIPTION - def descrStr = fun.description == null ? - "" : - "\n\n" + _paragraphWrap(fun.description.trim(), 80).join("\n") - - // PART 3: Usage - def usageStr = fun.usage == null ? - "" : - "\n\nUsage:\n" + fun.usage.trim() - - // PART 4: Options - def argGroupStrs = fun.allArgumentGroups.collect{argGroup -> - def name = argGroup.name - def descriptionStr = argGroup.description == null ? - "" : - "\n " + _paragraphWrap(argGroup.description.trim(), 80-4).join("\n ") + "\n" - def arguments = argGroup.arguments.collect{arg -> - arg instanceof String ? fun.allArguments.find{it.plainName == arg} : arg - }.findAll{it != null} - def argumentStrs = arguments.collect{param -> _generateArgumentHelp(param)} - - "\n\n$name:" + - descriptionStr + - argumentStrs.join("\n") - } - - // FINAL: combine - def out = nameStr + - descrStr + - usageStr + - argGroupStrs.join("") - - return out -} - -// based on Format._paragraphWrap -def _paragraphWrap(str, maxLength) { - def outLines = [] - str.split("\n").each{par -> - def words = par.split("\\s").toList() - - def word = null - def line = words.pop() - while(!words.isEmpty()) { - word = words.pop() - if (line.length() + word.length() + 1 <= maxLength) { - line = line + " " + word - } else { - outLines.add(line) - line = word - } - } - if (words.isEmpty()) { - outLines.add(line) - } - } - return outLines -} - -def helpMessage(config) { - if (params.containsKey("help") && params.help) { - def mergedConfig = addGlobalArguments(config) - def helpStr = _generateHelp(mergedConfig) - println(helpStr) - exit 0 - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/processConfig.nf' -def processConfig(config) { - // set defaults for arguments - config.arguments = - (config.arguments ?: []).collect{_processArgument(it)} - - // set defaults for argument_group arguments - config.argument_groups = - (config.argument_groups ?: []).collect{grp -> - grp.arguments = (grp.arguments ?: []).collect{_processArgument(it)} - grp - } - - // create combined arguments list - config.allArguments = - config.arguments + - config.argument_groups.collectMany{it.arguments} - - // add missing argument groups (based on Functionality::allArgumentGroups()) - def argGroups = config.argument_groups - if (argGroups.any{it.name.toLowerCase() == "arguments"}) { - argGroups = argGroups.collect{ grp -> - if (grp.name.toLowerCase() == "arguments") { - grp = grp + [ - arguments: grp.arguments + config.arguments - ] - } - grp - } - } else { - argGroups = argGroups + [ - name: "Arguments", - arguments: config.arguments - ] - } - config.allArgumentGroups = argGroups - - config -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/readConfig.nf' - -def readConfig(file) { - def config = readYaml(file ?: moduleDir.resolve("config.vsh.yaml")) - processConfig(config) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_resolveSiblingIfNotAbsolute.nf' -/** - * Resolve a path relative to the current file. - * - * @param str The path to resolve, as a String. - * @param parentPath The path to resolve relative to, as a Path. - * - * @return The path that may have been resovled, as a Path. - */ -def _resolveSiblingIfNotAbsolute(str, parentPath) { - if (str !instanceof String) { - return str - } - if (!_stringIsAbsolutePath(str)) { - return parentPath.resolveSibling(str) - } else { - return file(str, hidden: true) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_stringIsAbsolutePath.nf' -/** - * Check whether a path as a string is absolute. - * - * In the past, we tried using `file(., relative: true).isAbsolute()`, - * but the 'relative' option was added in 22.10.0. - * - * @param path The path to check, as a String. - * - * @return Whether the path is absolute, as a boolean. - */ -def _stringIsAbsolutePath(path) { - def _resolve_URL_PROTOCOL = ~/^([a-zA-Z][a-zA-Z0-9]*:)?\\/.+/ - - assert path instanceof String - return _resolve_URL_PROTOCOL.matcher(path).matches() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/collectTraces.nf' -class CustomTraceObserver implements nextflow.trace.TraceObserver { - List traces - - CustomTraceObserver(List traces) { - this.traces = traces - } - - @Override - void onProcessComplete(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } - - @Override - void onProcessCached(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } -} - -def collectTraces() { - def traces = Collections.synchronizedList([]) - - // add custom trace observer which stores traces in the traces object - session.observers.add(new CustomTraceObserver(traces)) - - traces -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/deepClone.nf' -/** - * Performs a deep clone of the given object. - * @param x an object - */ -def deepClone(x) { - iterateMap(x, {it instanceof Cloneable ? it.clone() : it}) -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getPublishDir.nf' -def getPublishDir() { - return params.containsKey("publish_dir") ? params.publish_dir : - params.containsKey("publishDir") ? params.publishDir : - null -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getRootDir.nf' - -// Recurse upwards until we find a '.build.yaml' file -def _findBuildYamlFile(pathPossiblySymlink) { - def path = pathPossiblySymlink.toRealPath() - def child = path.resolve(".build.yaml") - if (java.nio.file.Files.isDirectory(path) && java.nio.file.Files.exists(child)) { - return child - } else { - def parent = path.getParent() - if (parent == null) { - return null - } else { - return _findBuildYamlFile(parent) - } - } -} - -// get the root of the target folder -def getRootDir() { - def dir = _findBuildYamlFile(meta.resources_dir) - assert dir != null: "Could not find .build.yaml in the folder structure" - dir.getParent() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/iterateMap.nf' -/** - * Recursively apply a function over the leaves of an object. - * @param obj The object to iterate over. - * @param fun The function to apply to each value. - * @return The object with the function applied to each value. - */ -def iterateMap(obj, fun) { - if (obj instanceof List && obj !instanceof String) { - return obj.collect{item -> - iterateMap(item, fun) - } - } else if (obj instanceof Map) { - return obj.collectEntries{key, item -> - [key.toString(), iterateMap(item, fun)] - } - } else { - return fun(obj) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/niceView.nf' -/** - * A view for printing the event of each channel as a YAML blob. - * This is useful for debugging. - */ -def niceView() { - workflow niceViewWf { - take: input - main: - output = input - | view{toYamlBlob(it)} - emit: output - } - return niceViewWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readCsv.nf' - -def readCsv(file_path) { - def output = [] - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - - // todo: allow escaped quotes in string - // todo: allow single quotes? - def splitRegex = java.util.regex.Pattern.compile(''',(?=(?:[^"]*"[^"]*")*[^"]*$)''') - def removeQuote = java.util.regex.Pattern.compile('''"(.*)"''') - - def br = java.nio.file.Files.newBufferedReader(inputFile) - - def row = -1 - def header = null - while (br.ready() && header == null) { - def line = br.readLine() - row++ - if (!line.startsWith("#")) { - header = splitRegex.split(line, -1).collect{field -> - m = removeQuote.matcher(field) - m.find() ? m.replaceFirst('$1') : field - } - } - } - assert header != null: "CSV file should contain a header" - - while (br.ready()) { - def line = br.readLine() - row++ - if (line == null) { - br.close() - break - } - - if (!line.startsWith("#")) { - def predata = splitRegex.split(line, -1) - def data = predata.collect{field -> - if (field == "") { - return null - } - def m = removeQuote.matcher(field) - if (m.find()) { - return m.replaceFirst('$1') - } else { - return field - } - } - assert header.size() == data.size(): "Row $row should contain the same number as fields as the header" - - def dataMap = [header, data].transpose().collectEntries().findAll{it.value != null} - output.add(dataMap) - } - } - - output -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJson.nf' -def readJson(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parse(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJsonBlob.nf' -def readJsonBlob(str) { - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parseText(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readTaggedYaml.nf' -// Custom constructor to modify how certain objects are parsed from YAML -class CustomConstructor extends org.yaml.snakeyaml.constructor.Constructor { - Path root - - class ConstructPath extends org.yaml.snakeyaml.constructor.AbstractConstruct { - public Object construct(org.yaml.snakeyaml.nodes.Node node) { - String filename = (String) constructScalar(node); - if (root != null) { - return root.resolve(filename); - } - return java.nio.file.Paths.get(filename); - } - } - - CustomConstructor(org.yaml.snakeyaml.LoaderOptions options, Path root) { - super(options) - this.root = root - // Handling !file tag and parse it back to a File type - this.yamlConstructors.put(new org.yaml.snakeyaml.nodes.Tag("!file"), new ConstructPath()) - } -} - -def readTaggedYaml(Path path) { - def options = new org.yaml.snakeyaml.LoaderOptions() - def constructor = new CustomConstructor(options, path.getParent()) - def yaml = new org.yaml.snakeyaml.Yaml(constructor) - return yaml.load(path.text) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYaml.nf' -def readYaml(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYamlBlob.nf' -def readYamlBlob(str) { - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toJsonBlob.nf' -String toJsonBlob(data) { - return groovy.json.JsonOutput.toJson(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toTaggedYamlBlob.nf' -// Custom representer to modify how certain objects are represented in YAML -class CustomRepresenter extends org.yaml.snakeyaml.representer.Representer { - Path relativizer - - class RepresentPath implements org.yaml.snakeyaml.representer.Represent { - public String getFileName(Object obj) { - if (obj instanceof File) { - obj = ((File) obj).toPath(); - } - if (obj !instanceof Path) { - throw new IllegalArgumentException("Object: " + obj + " is not a Path or File"); - } - def path = (Path) obj; - - if (relativizer != null) { - return relativizer.relativize(path).toString() - } else { - return path.toString() - } - } - - public org.yaml.snakeyaml.nodes.Node representData(Object data) { - String filename = getFileName(data); - def tag = new org.yaml.snakeyaml.nodes.Tag("!file"); - return representScalar(tag, filename); - } - } - CustomRepresenter(org.yaml.snakeyaml.DumperOptions options, Path relativizer) { - super(options) - this.relativizer = relativizer - this.representers.put(sun.nio.fs.UnixPath, new RepresentPath()) - this.representers.put(Path, new RepresentPath()) - this.representers.put(File, new RepresentPath()) - } -} - -String toTaggedYamlBlob(data) { - return toRelativeTaggedYamlBlob(data, null) -} -String toRelativeTaggedYamlBlob(data, Path relativizer) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - def representer = new CustomRepresenter(options, relativizer) - def yaml = new org.yaml.snakeyaml.Yaml(representer, options) - return yaml.dump(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toYamlBlob.nf' -String toYamlBlob(data) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - options.setPrettyFlow(true) - def yaml = new org.yaml.snakeyaml.Yaml(options) - def cleanData = iterateMap(data, { it instanceof Path ? it.toString() : it }) - return yaml.dump(cleanData) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeJson.nf' -void writeJson(data, file) { - assert data: "writeJson: data should not be null" - assert file: "writeJson: file should not be null" - file.write(toJsonBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeYaml.nf' -void writeYaml(data, file) { - assert data: "writeYaml: data should not be null" - assert file: "writeYaml: file should not be null" - file.write(toYamlBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/findStates.nf' -def findStates(Map params, Map config) { - def auto_config = deepClone(config) - def auto_params = deepClone(params) - - auto_config = auto_config.clone() - // override arguments - auto_config.argument_groups = [] - auto_config.arguments = [ - [ - type: "string", - name: "--id", - description: "A dummy identifier", - required: false - ], - [ - type: "file", - name: "--input_states", - example: "/path/to/input/directory/**/state.yaml", - description: "Path to input directory containing the datasets to be integrated.", - required: true, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--filter", - example: "foo/.*/state.yaml", - description: "Regex to filter state files by path.", - required: false - ], - // to do: make this a yaml blob? - [ - type: "string", - name: "--rename_keys", - example: ["newKey1:oldKey1", "newKey2:oldKey2"], - description: "Rename keys in the detected input files. This is useful if the input files do not match the set of input arguments of the workflow.", - required: false, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--settings", - example: '{"output_dataset": "dataset.h5ad", "k": 10}', - description: "Global arguments as a JSON glob to be passed to all components.", - required: false - ] - ] - if (!(auto_params.containsKey("id"))) { - auto_params["id"] = "auto" - } - - // run auto config through processConfig once more - auto_config = processConfig(auto_config) - - workflow findStatesWf { - helpMessage(auto_config) - - output_ch = - channelFromParams(auto_params, auto_config) - | flatMap { autoId, args -> - - def globalSettings = args.settings ? readYamlBlob(args.settings) : [:] - - // look for state files in input dir - def stateFiles = args.input_states - - // filter state files by regex - if (args.filter) { - stateFiles = stateFiles.findAll{ stateFile -> - def stateFileStr = stateFile.toString() - def matcher = stateFileStr =~ args.filter - matcher.matches()} - } - - // read in states - def states = stateFiles.collect { stateFile -> - def state_ = readTaggedYaml(stateFile) - [state_.id, state_] - } - - // construct renameMap - if (args.rename_keys) { - def renameMap = args.rename_keys.collectEntries{renameString -> - def split = renameString.split(";") - assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey,newKey:oldKey'" - split - } - - // rename keys in state, only let states through which have all keys - // also add global settings - states = states.collectMany{id, state -> - def newState = [:] - - for (key in renameMap.keySet()) { - def origKey = renameMap[key] - if (!(state.containsKey(origKey))) { - return [] - } - newState[key] = state[origKey] - } - - [[id, globalSettings + newState]] - } - } - - states - } - emit: - output_ch - } - - return findStatesWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/joinStates.nf' -def joinStates(Closure apply_) { - workflow joinStatesWf { - take: input_ch - main: - output_ch = input_ch - | toSortedList - | filter{ it.size() > 0 } - | map{ tups -> - def ids = tups.collect{it[0]} - def states = tups.collect{it[1]} - apply_(ids, states) - } - - emit: output_ch - } - return joinStatesWf -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/publishStates.nf' -def collectFiles(obj) { - if (obj instanceof java.io.File || obj instanceof Path) { - return [obj] - } else if (obj instanceof List && obj !instanceof String) { - return obj.collectMany{item -> - collectFiles(item) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectFiles(item) - } - } else { - return [] - } -} - -/** - * Recurse through a state and collect all input files and their target output filenames. - * @param obj The state to recurse through. - * @param prefix The prefix to prepend to the output filenames. - */ -def collectInputOutputPaths(obj, prefix) { - if (obj instanceof File || obj instanceof Path) { - def path = obj instanceof Path ? obj : obj.toPath() - def ext = path.getFileName().toString().find("\\.[^\\.]+\$") ?: "" - def newFilename = prefix + ext - return [[obj, newFilename]] - } else if (obj instanceof List && obj !instanceof String) { - return obj.withIndex().collectMany{item, ix -> - collectInputOutputPaths(item, prefix + "_" + ix) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectInputOutputPaths(item, prefix + "." + key) - } - } else { - return [] - } -} - -def publishStates(Map args) { - def key_ = args.get("key") - def yamlTemplate_ = args.get("output_state", args.get("outputState", '$id.$key.state.yaml')) - - assert key_ != null : "publishStates: key must be specified" - - workflow publishStatesWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] - - // the input files and the target output filenames - def inputoutputFilenames_ = collectInputOutputPaths(state_, id_ + "." + key_).transpose() - def inputFiles_ = inputoutputFilenames_[0] - def outputFilenames_ = inputoutputFilenames_[1] - - def yamlFilename = yamlTemplate_ - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - - // TODO: do the pathnames in state_ match up with the outputFilenames_? - - // convert state to yaml blob - def yamlBlob_ = toRelativeTaggedYamlBlob([id: id_] + state_, java.nio.file.Paths.get(yamlFilename)) - - [id_, yamlBlob_, yamlFilename, inputFiles_, outputFilenames_] - } - | publishStatesProc - emit: input_ch - } - return publishStatesWf -} -process publishStatesProc { - // todo: check publishpath? - publishDir path: "${getPublishDir()}/", mode: "copy" - tag "$id" - input: - tuple val(id), val(yamlBlob), val(yamlFile), path(inputFiles, stageAs: "_inputfile?/*"), val(outputFiles) - output: - tuple val(id), path{[yamlFile] + outputFiles} - script: - def copyCommands = [ - inputFiles instanceof List ? inputFiles : [inputFiles], - outputFiles instanceof List ? outputFiles : [outputFiles] - ] - .transpose() - .collectMany{infile, outfile -> - if (infile.toString() != outfile.toString()) { - [ - "[ -d \"\$(dirname '${outfile.toString()}')\" ] || mkdir -p \"\$(dirname '${outfile.toString()}')\"", - "cp -r '${infile.toString()}' '${outfile.toString()}'" - ] - } else { - // no need to copy if infile is the same as outfile - [] - } - } - """ -mkdir -p "\$(dirname '${yamlFile}')" -echo "Storing state as yaml" -echo '${yamlBlob}' > '${yamlFile}' -echo "Copying output files to destination folder" -${copyCommands.join("\n ")} -""" -} - - -// this assumes that the state contains no other values other than those specified in the config -def publishStatesByConfig(Map args) { - def config = args.get("config") - assert config != null : "publishStatesByConfig: config must be specified" - - def key_ = args.get("key", config.name) - assert key_ != null : "publishStatesByConfig: key must be specified" - - workflow publishStatesSimpleWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] // e.g. [output: new File("myoutput.h5ad"), k: 10] - def origState_ = tup[2] // e.g. [output: '$id.$key.foo.h5ad'] - - // TODO: allow overriding the state.yaml template - // TODO TODO: if auto.publish == "state", add output_state as an argument - def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' - def yamlFilename = yamlTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() - - // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where - // - key is a String - // - value is any object that can be serialized to a Yaml (so a String/Integer/Long/Double/Boolean, a List, a Map, or a Path) - // - inputPath is a List[Path] - // - outputFilename is a List[String] - // - (key, value) are the tuples that will be saved to the state.yaml file - // - (inputPath, outputFilename) are the files that will be copied from src to dest (relative to the state.yaml) - def processedState = - config.allArguments - .findAll { it.direction == "output" } - .collectMany { par -> - def plainName_ = par.plainName - // if the state does not contain the key, it's an - // optional argument for which the component did - // not generate any output - if (!state_.containsKey(plainName_)) { - return [] - } - def value = state_[plainName_] - // if the parameter is not a file, it should be stored - // in the state as-is, but is not something that needs - // to be copied from the source path to the dest path - if (par.type != "file") { - return [[key: plainName_, value: value, inputPath: [], outputFilename: []]] - } - // if the orig state does not contain this filename, - // it's an optional argument for which the user specified - // that it should not be returned as a state - if (!origState_.containsKey(plainName_)) { - return [] - } - def filenameTemplate = origState_[plainName_] - // if the pararameter is multiple: true, fetch the template - if (par.multiple && filenameTemplate instanceof List) { - filenameTemplate = filenameTemplate[0] - } - // instantiate the template - def filename = filenameTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - if (par.multiple) { - // if the parameter is multiple: true, the filename - // should contain a wildcard '*' that is replaced with - // the index of the file - assert filename.contains("*") : "Module '${key_}' id '${id_}': Multiple output files specified, but no wildcard '*' in the filename: ${filename}" - def outputPerFile = value.withIndex().collect{ val, ix -> - def filename_ix = filename.replace("*", ix.toString()) - def value_ = java.nio.file.Paths.get(filename_ix) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = val instanceof File ? val.toPath() : val - [value: value_, inputPath: inputPath, outputFilename: filename_ix] - } - def transposedOutputs = ["value", "inputPath", "outputFilename"].collectEntries{ key -> - [key, outputPerFile.collect{dic -> dic[key]}] - } - return [[key: plainName_] + transposedOutputs] - } else { - def value_ = java.nio.file.Paths.get(filename) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = value instanceof File ? value.toPath() : value - return [[key: plainName_, value: value_, inputPath: [inputPath], outputFilename: [filename]]] - } - } - - def updatedState_ = processedState.collectEntries{[it.key, it.value]} - def inputPaths = processedState.collectMany{it.inputPath} - def outputFilenames = processedState.collectMany{it.outputFilename} - - // convert state to yaml blob - def yamlBlob_ = toTaggedYamlBlob([id: id_] + updatedState_) - - [id_, yamlBlob_, yamlFilename, inputPaths, outputFilenames] - } - | publishStatesProc - emit: input_ch - } - return publishStatesSimpleWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/setState.nf' -def setState(fun) { - assert fun instanceof Closure || fun instanceof Map || fun instanceof List : - "Error in setState: Expected process argument to be a Closure, a Map, or a List. Found: class ${fun.getClass()}" - - // if fun is a List, convert to map - if (fun instanceof List) { - // check whether fun is a list[string] - assert fun.every{it instanceof CharSequence} : "Error in setState: argument is a List, but not all elements are Strings" - fun = fun.collectEntries{[it, it]} - } - - // if fun is a map, convert to closure - if (fun instanceof Map) { - // check whether fun is a map[string, string] - assert fun.values().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all values are Strings" - assert fun.keySet().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all keys are Strings" - def funMap = fun.clone() - // turn the map into a closure to be used later on - fun = { id_, state_ -> - assert state_ instanceof Map : "Error in setState: the state is not a Map" - funMap.collectMany{newkey, origkey -> - if (state_.containsKey(origkey)) { - [[newkey, state_[origkey]]] - } else { - [] - } - }.collectEntries() - } - } - - map { tup -> - def id = tup[0] - def state = tup[1] - def unfilteredState = fun(id, state) - def newState = unfilteredState.findAll{key, val -> val != null} - [id, newState] + tup.drop(2) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processAuto.nf' -// TODO: unit test processAuto -def processAuto(Map auto) { - // remove null values - auto = auto.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = ["simplifyInput", "simplifyOutput", "transcript", "publish"] - def unexpectedKeys = auto.keySet() - expectedKeys - assert unexpectedKeys.isEmpty(), "unexpected keys in auto: '${unexpectedKeys.join("', '")}'" - - // check auto.simplifyInput - assert auto.simplifyInput instanceof Boolean, "auto.simplifyInput must be a boolean" - - // check auto.simplifyOutput - assert auto.simplifyOutput instanceof Boolean, "auto.simplifyOutput must be a boolean" - - // check auto.transcript - assert auto.transcript instanceof Boolean, "auto.transcript must be a boolean" - - // check auto.publish - assert auto.publish instanceof Boolean || auto.publish == "state", "auto.publish must be a boolean or 'state'" - - return auto.subMap(expectedKeys) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processDirectives.nf' -def assertMapKeys(map, expectedKeys, requiredKeys, mapName) { - assert map instanceof Map : "Expected argument '$mapName' to be a Map. Found: class ${map.getClass()}" - map.forEach { key, val -> - assert key in expectedKeys : "Unexpected key '$key' in ${mapName ? mapName + " " : ""}map" - } - requiredKeys.forEach { requiredKey -> - assert map.containsKey(requiredKey) : "Missing required key '$key' in ${mapName ? mapName + " " : ""}map" - } -} - -// TODO: unit test processDirectives -def processDirectives(Map drctv) { - // remove null values - drctv = drctv.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = [ - "accelerator", "afterScript", "beforeScript", "cache", "conda", "container", "containerOptions", "cpus", "disk", "echo", "errorStrategy", "executor", "machineType", "maxErrors", "maxForks", "maxRetries", "memory", "module", "penv", "pod", "publishDir", "queue", "label", "scratch", "storeDir", "stageInMode", "stageOutMode", "tag", "time" - ] - def unexpectedKeys = drctv.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Unexpected keys in process directive: '${unexpectedKeys.join("', '")}'" - - /* DIRECTIVE accelerator - accepted examples: - - [ limit: 4, type: "nvidia-tesla-k80" ] - */ - if (drctv.containsKey("accelerator")) { - assertMapKeys(drctv["accelerator"], ["type", "limit", "request", "runtime"], [], "accelerator") - } - - /* DIRECTIVE afterScript - accepted examples: - - "source /cluster/bin/cleanup" - */ - if (drctv.containsKey("afterScript")) { - assert drctv["afterScript"] instanceof CharSequence - } - - /* DIRECTIVE beforeScript - accepted examples: - - "source /cluster/bin/setup" - */ - if (drctv.containsKey("beforeScript")) { - assert drctv["beforeScript"] instanceof CharSequence - } - - /* DIRECTIVE cache - accepted examples: - - true - - false - - "deep" - - "lenient" - */ - if (drctv.containsKey("cache")) { - assert drctv["cache"] instanceof CharSequence || drctv["cache"] instanceof Boolean - if (drctv["cache"] instanceof CharSequence) { - assert drctv["cache"] in ["deep", "lenient"] : "Unexpected value for cache" - } - } - - /* DIRECTIVE conda - accepted examples: - - "bwa=0.7.15" - - "bwa=0.7.15 fastqc=0.11.5" - - ["bwa=0.7.15", "fastqc=0.11.5"] - */ - if (drctv.containsKey("conda")) { - if (drctv["conda"] instanceof List) { - drctv["conda"] = drctv["conda"].join(" ") - } - assert drctv["conda"] instanceof CharSequence - } - - /* DIRECTIVE container - accepted examples: - - "foo/bar:tag" - - [ registry: "reg", image: "im", tag: "ta" ] - is transformed to "reg/im:ta" - - [ image: "im" ] - is transformed to "im:latest" - */ - if (drctv.containsKey("container")) { - assert drctv["container"] instanceof Map || drctv["container"] instanceof CharSequence - if (drctv["container"] instanceof Map) { - def m = drctv["container"] - assertMapKeys(m, [ "registry", "image", "tag" ], ["image"], "container") - def part1 = - System.getenv('OVERRIDE_CONTAINER_REGISTRY') ? System.getenv('OVERRIDE_CONTAINER_REGISTRY') + "/" : - params.containsKey("override_container_registry") ? params["override_container_registry"] + "/" : // todo: remove? - m.registry ? m.registry + "/" : - "" - def part2 = m.image - def part3 = m.tag ? ":" + m.tag : ":latest" - drctv["container"] = part1 + part2 + part3 - } - } - - /* DIRECTIVE containerOptions - accepted examples: - - "--foo bar" - - ["--foo bar", "-f b"] - */ - if (drctv.containsKey("containerOptions")) { - if (drctv["containerOptions"] instanceof List) { - drctv["containerOptions"] = drctv["containerOptions"].join(" ") - } - assert drctv["containerOptions"] instanceof CharSequence - } - - /* DIRECTIVE cpus - accepted examples: - - 1 - - 10 - */ - if (drctv.containsKey("cpus")) { - assert drctv["cpus"] instanceof Integer - } - - /* DIRECTIVE disk - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("disk")) { - assert drctv["disk"] instanceof CharSequence - // assert drctv["disk"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE echo - accepted examples: - - true - - false - */ - if (drctv.containsKey("echo")) { - assert drctv["echo"] instanceof Boolean - } - - /* DIRECTIVE errorStrategy - accepted examples: - - "terminate" - - "finish" - */ - if (drctv.containsKey("errorStrategy")) { - assert drctv["errorStrategy"] instanceof CharSequence - assert drctv["errorStrategy"] in ["terminate", "finish", "ignore", "retry"] : "Unexpected value for errorStrategy" - } - - /* DIRECTIVE executor - accepted examples: - - "local" - - "sge" - */ - if (drctv.containsKey("executor")) { - assert drctv["executor"] instanceof CharSequence - assert drctv["executor"] in ["local", "sge", "uge", "lsf", "slurm", "pbs", "pbspro", "moab", "condor", "nqsii", "ignite", "k8s", "awsbatch", "google-pipelines"] : "Unexpected value for executor" - } - - /* DIRECTIVE machineType - accepted examples: - - "n1-highmem-8" - */ - if (drctv.containsKey("machineType")) { - assert drctv["machineType"] instanceof CharSequence - } - - /* DIRECTIVE maxErrors - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxErrors")) { - assert drctv["maxErrors"] instanceof Integer - } - - /* DIRECTIVE maxForks - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxForks")) { - assert drctv["maxForks"] instanceof Integer - } - - /* DIRECTIVE maxRetries - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxRetries")) { - assert drctv["maxRetries"] instanceof Integer - } - - /* DIRECTIVE memory - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("memory")) { - assert drctv["memory"] instanceof CharSequence - // assert drctv["memory"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE module - accepted examples: - - "ncbi-blast/2.2.27" - - "ncbi-blast/2.2.27:t_coffee/10.0" - - ["ncbi-blast/2.2.27", "t_coffee/10.0"] - */ - if (drctv.containsKey("module")) { - if (drctv["module"] instanceof List) { - drctv["module"] = drctv["module"].join(":") - } - assert drctv["module"] instanceof CharSequence - } - - /* DIRECTIVE penv - accepted examples: - - "smp" - */ - if (drctv.containsKey("penv")) { - assert drctv["penv"] instanceof CharSequence - } - - /* DIRECTIVE pod - accepted examples: - - [ label: "key", value: "val" ] - - [ annotation: "key", value: "val" ] - - [ env: "key", value: "val" ] - - [ [label: "l", value: "v"], [env: "e", value: "v"]] - */ - if (drctv.containsKey("pod")) { - if (drctv["pod"] instanceof Map) { - drctv["pod"] = [ drctv["pod"] ] - } - assert drctv["pod"] instanceof List - drctv["pod"].forEach { pod -> - assert pod instanceof Map - // TODO: should more checks be added? - // See https://www.nextflow.io/docs/latest/process.html?highlight=directives#pod - // e.g. does it contain 'label' and 'value', or 'annotation' and 'value', or ...? - } - } - - /* DIRECTIVE publishDir - accepted examples: - - [] - - [ [ path: "foo", enabled: true ], [ path: "bar", enabled: false ] ] - - "/path/to/dir" - is transformed to [[ path: "/path/to/dir" ]] - - [ path: "/path/to/dir", mode: "cache" ] - is transformed to [[ path: "/path/to/dir", mode: "cache" ]] - */ - // TODO: should we also look at params["publishDir"]? - if (drctv.containsKey("publishDir")) { - def pblsh = drctv["publishDir"] - - // check different options - assert pblsh instanceof List || pblsh instanceof Map || pblsh instanceof CharSequence - - // turn into list if not already so - // for some reason, 'if (!pblsh instanceof List) pblsh = [ pblsh ]' doesn't work. - pblsh = pblsh instanceof List ? pblsh : [ pblsh ] - - // check elements of publishDir - pblsh = pblsh.collect{ elem -> - // turn into map if not already so - elem = elem instanceof CharSequence ? [ path: elem ] : elem - - // check types and keys - assert elem instanceof Map : "Expected publish argument '$elem' to be a String or a Map. Found: class ${elem.getClass()}" - assertMapKeys(elem, [ "path", "mode", "overwrite", "pattern", "saveAs", "enabled" ], ["path"], "publishDir") - - // check elements in map - assert elem.containsKey("path") - assert elem["path"] instanceof CharSequence - if (elem.containsKey("mode")) { - assert elem["mode"] instanceof CharSequence - assert elem["mode"] in [ "symlink", "rellink", "link", "copy", "copyNoFollow", "move" ] - } - if (elem.containsKey("overwrite")) { - assert elem["overwrite"] instanceof Boolean - } - if (elem.containsKey("pattern")) { - assert elem["pattern"] instanceof CharSequence - } - if (elem.containsKey("saveAs")) { - assert elem["saveAs"] instanceof CharSequence //: "saveAs as a Closure is currently not supported. Surround your closure with single quotes to get the desired effect. Example: '\{ foo \}'" - } - if (elem.containsKey("enabled")) { - assert elem["enabled"] instanceof Boolean - } - - // return final result - elem - } - // store final directive - drctv["publishDir"] = pblsh - } - - /* DIRECTIVE queue - accepted examples: - - "long" - - "short,long" - - ["short", "long"] - */ - if (drctv.containsKey("queue")) { - if (drctv["queue"] instanceof List) { - drctv["queue"] = drctv["queue"].join(",") - } - assert drctv["queue"] instanceof CharSequence - } - - /* DIRECTIVE label - accepted examples: - - "big_mem" - - "big_cpu" - - ["big_mem", "big_cpu"] - */ - if (drctv.containsKey("label")) { - if (drctv["label"] instanceof CharSequence) { - drctv["label"] = [ drctv["label"] ] - } - assert drctv["label"] instanceof List - drctv["label"].forEach { label -> - assert label instanceof CharSequence - // assert label.matches("[a-zA-Z0-9]([a-zA-Z0-9_]*[a-zA-Z0-9])?") - // ^ does not allow closures - } - } - - /* DIRECTIVE scratch - accepted examples: - - true - - "/path/to/scratch" - - '$MY_PATH_TO_SCRATCH' - - "ram-disk" - */ - if (drctv.containsKey("scratch")) { - assert drctv["scratch"] == true || drctv["scratch"] instanceof CharSequence - } - - /* DIRECTIVE storeDir - accepted examples: - - "/path/to/storeDir" - */ - if (drctv.containsKey("storeDir")) { - assert drctv["storeDir"] instanceof CharSequence - } - - /* DIRECTIVE stageInMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageInMode")) { - assert drctv["stageInMode"] instanceof CharSequence - assert drctv["stageInMode"] in ["copy", "link", "symlink", "rellink"] - } - - /* DIRECTIVE stageOutMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageOutMode")) { - assert drctv["stageOutMode"] instanceof CharSequence - assert drctv["stageOutMode"] in ["copy", "move", "rsync"] - } - - /* DIRECTIVE tag - accepted examples: - - "foo" - - '$id' - */ - if (drctv.containsKey("tag")) { - assert drctv["tag"] instanceof CharSequence - } - - /* DIRECTIVE time - accepted examples: - - "1h" - - "2days" - - "1day 6hours 3minutes 30seconds" - */ - if (drctv.containsKey("time")) { - assert drctv["time"] instanceof CharSequence - // todo: validation regex? - } - - return drctv -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf' -def processWorkflowArgs(Map args, Map defaultWfArgs, Map meta) { - // override defaults with args - def workflowArgs = defaultWfArgs + args - - // check whether 'key' exists - assert workflowArgs.containsKey("key") : "Error in module '${meta.config.name}': key is a required argument" - - // if 'key' is a closure, apply it to the original key - if (workflowArgs["key"] instanceof Closure) { - workflowArgs["key"] = workflowArgs["key"](meta.config.name) - } - def key = workflowArgs["key"] - assert key instanceof CharSequence : "Expected process argument 'key' to be a String. Found: class ${key.getClass()}" - assert key ==~ /^[a-zA-Z_]\w*$/ : "Error in module '$key': Expected process argument 'key' to consist of only letters, digits or underscores. Found: ${key}" - - // check for any unexpected keys - def expectedKeys = ["key", "directives", "auto", "map", "mapId", "mapData", "mapPassthrough", "filter", "runIf", "fromState", "toState", "args", "renameKeys", "debug"] - def unexpectedKeys = workflowArgs.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Error in module '$key': unexpected arguments to the '.run()' function: '${unexpectedKeys.join("', '")}'" - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("directives") : "Error in module '$key': directives is a required argument" - assert workflowArgs["directives"] instanceof Map : "Error in module '$key': Expected process argument 'directives' to be a Map. Found: class ${workflowArgs['directives'].getClass()}" - workflowArgs["directives"] = processDirectives(defaultWfArgs.directives + workflowArgs["directives"]) - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("auto") : "Error in module '$key': auto is a required argument" - assert workflowArgs["auto"] instanceof Map : "Error in module '$key': Expected process argument 'auto' to be a Map. Found: class ${workflowArgs['auto'].getClass()}" - workflowArgs["auto"] = processAuto(defaultWfArgs.auto + workflowArgs["auto"]) - - // auto define publish, if so desired - if (workflowArgs.auto.publish == true && (workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : [:]).isEmpty()) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.publish is true, params.publish_dir needs to be defined.\n" + - // " Example: params.publish_dir = \"./output/\"" - def publishDir = getPublishDir() - - if (publishDir != null) { - workflowArgs.directives.publishDir = [[ - path: publishDir, - saveAs: "{ it.startsWith('.') ? null : it }", // don't publish hidden files, by default - mode: "copy" - ]] - } - } - - // auto define transcript, if so desired - if (workflowArgs.auto.transcript == true) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("transcriptsDir") || params.containsKey("transcripts_dir") || params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.transcript is true, either params.transcripts_dir or params.publish_dir needs to be defined.\n" + - // " Example: params.transcripts_dir = \"./transcripts/\"" - def transcriptsDir = - params.containsKey("transcripts_dir") ? params.transcripts_dir : - params.containsKey("transcriptsDir") ? params.transcriptsDir : - params.containsKey("publish_dir") ? params.publish_dir + "/_transcripts" : - params.containsKey("publishDir") ? params.publishDir + "/_transcripts" : - null - if (transcriptsDir != null) { - def timestamp = nextflow.Nextflow.getSession().getWorkflowMetadata().start.format('yyyy-MM-dd_HH-mm-ss') - def transcriptsPublishDir = [ - path: "$transcriptsDir/$timestamp/\${task.process.replaceAll(':', '-')}/\${id}/", - saveAs: "{ it.startsWith('.') ? it.replaceAll('^.', '') : null }", - mode: "copy" - ] - def publishDirs = workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : null ? workflowArgs.directives.publishDir : [] - workflowArgs.directives.publishDir = publishDirs + transcriptsPublishDir - } - } - - // if this is a stubrun, remove certain directives? - if (workflow.stubRun) { - workflowArgs.directives.keySet().removeAll(["publishDir", "cpus", "memory", "label"]) - } - - for (nam in ["map", "mapId", "mapData", "mapPassthrough", "filter", "runIf"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam]) { - assert workflowArgs[nam] instanceof Closure : "Error in module '$key': Expected process argument '$nam' to be null or a Closure. Found: class ${workflowArgs[nam].getClass()}" - } - } - - // TODO: should functions like 'map', 'mapId', 'mapData', 'mapPassthrough' be deprecated as well? - for (nam in ["map", "mapData", "mapPassthrough", "renameKeys"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam] != null) { - log.warn "module '$key': workflow argument '$nam' is deprecated and will be removed in Viash 0.9.0. Please use 'fromState' and 'toState' instead." - } - } - - // check fromState - workflowArgs["fromState"] = _processFromState(workflowArgs.get("fromState"), key, meta.config) - - // check toState - workflowArgs["toState"] = _processToState(workflowArgs.get("toState"), key, meta.config) - - // return output - return workflowArgs -} - -def _processFromState(fromState, key_, config_) { - assert fromState == null || fromState instanceof Closure || fromState instanceof Map || fromState instanceof List : - "Error in module '$key_': Expected process argument 'fromState' to be null, a Closure, a Map, or a List. Found: class ${fromState.getClass()}" - if (fromState == null) { - return null - } - - // if fromState is a List, convert to map - if (fromState instanceof List) { - // check whether fromstate is a list[string] - assert fromState.every{it instanceof CharSequence} : "Error in module '$key_': fromState is a List, but not all elements are Strings" - fromState = fromState.collectEntries{[it, it]} - } - - // if fromState is a map, convert to closure - if (fromState instanceof Map) { - // check whether fromstate is a map[string, string] - assert fromState.values().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all values are Strings" - assert fromState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all keys are Strings" - def fromStateMap = fromState.clone() - def requiredInputNames = meta.config.allArguments.findAll{it.required && it.direction == "Input"}.collect{it.plainName} - // turn the map into a closure to be used later on - fromState = { it -> - def state = it[1] - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def data = fromStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (state.containsKey(origkey)) { - [[newkey, state[origkey]]] - } else if (!requiredInputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': fromState key '$origkey' not found in current state") - } - }.collectEntries() - data - } - } - - return fromState -} - -def _processToState(toState, key_, config_) { - if (toState == null) { - toState = { tup -> tup[1] } - } - - // toState should be a closure, map[string, string], or list[string] - assert toState instanceof Closure || toState instanceof Map || toState instanceof List : - "Error in module '$key_': Expected process argument 'toState' to be a Closure, a Map, or a List. Found: class ${toState.getClass()}" - - // if toState is a List, convert to map - if (toState instanceof List) { - // check whether toState is a list[string] - assert toState.every{it instanceof CharSequence} : "Error in module '$key_': toState is a List, but not all elements are Strings" - toState = toState.collectEntries{[it, it]} - } - - // if toState is a map, convert to closure - if (toState instanceof Map) { - // check whether toState is a map[string, string] - assert toState.values().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all values are Strings" - assert toState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all keys are Strings" - def toStateMap = toState.clone() - def requiredOutputNames = config_.allArguments.findAll{it.required && it.direction == "Output"}.collect{it.plainName} - // turn the map into a closure to be used later on - toState = { it -> - def output = it[1] - def state = it[2] - assert output instanceof Map : "Error in module '$key_': the output is not a Map" - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def extraEntries = toStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (output.containsKey(origkey)) { - [[newkey, output[origkey]]] - } else if (!requiredOutputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': toState key '$origkey' not found in current output") - } - }.collectEntries() - state + extraEntries - } - } - - return toState -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/workflowFactory.nf' -def _debug(workflowArgs, debugKey) { - if (workflowArgs.debug) { - view { "process '${workflowArgs.key}' $debugKey tuple: $it" } - } else { - map { it } - } -} - -// depends on: innerWorkflowFactory -def workflowFactory(Map args, Map defaultWfArgs, Map meta) { - def workflowArgs = processWorkflowArgs(args, defaultWfArgs, meta) - def key_ = workflowArgs["key"] - - workflow workflowInstance { - take: input_ - - main: - def chModified = input_ - | checkUniqueIds([:]) - | _debug(workflowArgs, "input") - | map { tuple -> - tuple = deepClone(tuple) - - if (workflowArgs.map) { - tuple = workflowArgs.map(tuple) - } - if (workflowArgs.mapId) { - tuple[0] = workflowArgs.mapId(tuple[0]) - } - if (workflowArgs.mapData) { - tuple[1] = workflowArgs.mapData(tuple[1]) - } - if (workflowArgs.mapPassthrough) { - tuple = tuple.take(2) + workflowArgs.mapPassthrough(tuple.drop(2)) - } - - // check tuple - assert tuple instanceof List : - "Error in module '${key_}': element in channel should be a tuple [id, data, ...otherargs...]\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: List. Found: tuple.getClass() is ${tuple.getClass()}" - assert tuple.size() >= 2 : - "Error in module '${key_}': expected length of tuple in input channel to be two or greater.\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: tuple.size() == ${tuple.size()}" - - // check id field - if (tuple[0] instanceof GString) { - tuple[0] = tuple[0].toString() - } - assert tuple[0] instanceof CharSequence : - "Error in module '${key_}': first element of tuple in channel should be a String\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: ${tuple[0]}" - - // match file to input file - if (workflowArgs.auto.simplifyInput && (tuple[1] instanceof Path || tuple[1] instanceof List)) { - def inputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - - assert inputFiles.size() == 1 : - "Error in module '${key_}' id '${tuple[0]}'.\n" + - " Anonymous file inputs are only allowed when the process has exactly one file input.\n" + - " Expected: inputFiles.size() == 1. Found: inputFiles.size() is ${inputFiles.size()}" - - tuple[1] = [[ inputFiles[0].plainName, tuple[1] ]].collectEntries() - } - - // check data field - assert tuple[1] instanceof Map : - "Error in module '${key_}' id '${tuple[0]}': second element of tuple in channel should be a Map\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // rename keys of data field in tuple - if (workflowArgs.renameKeys) { - assert workflowArgs.renameKeys instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class: Map. Found: renameKeys.getClass() is ${workflowArgs.renameKeys.getClass()}" - assert tuple[1] instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // TODO: allow renameKeys to be a function? - workflowArgs.renameKeys.each { newKey, oldKey -> - assert newKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of newKey: String. Found: newKey.getClass() is ${newKey.getClass()}" - assert oldKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of oldKey: String. Found: oldKey.getClass() is ${oldKey.getClass()}" - assert tuple[1].containsKey(oldKey) : - "Error renaming data keys in module '${key}' id '${tuple[0]}'.\n" + - " Key '$oldKey' is missing in the data map. tuple[1].keySet() is '${tuple[1].keySet()}'" - tuple[1].put(newKey, tuple[1][oldKey]) - } - tuple[1].keySet().removeAll(workflowArgs.renameKeys.collect{ newKey, oldKey -> oldKey }) - } - tuple - } - - def chModifiedFiltered = workflowArgs.filter ? - chModified | filter{workflowArgs.filter(it)} : - chModified - - def chRun = null - def chPassthrough = null - if (workflowArgs.runIf) { - def runIfBranch = chModifiedFiltered.branch{ tup -> - run: workflowArgs.runIf(tup[0], tup[1]) - passthrough: true - } - chRun = runIfBranch.run - chPassthrough = runIfBranch.passthrough - } else { - chRun = chModifiedFiltered - chPassthrough = Channel.empty() - } - - def chArgs = workflowArgs.fromState ? - chRun | map{ - def new_data = workflowArgs.fromState(it.take(2)) - [it[0], new_data] - } : - chRun | map {tup -> tup.take(2)} - - // fill in defaults - def chArgsWithDefaults = chArgs - | map { tuple -> - def id_ = tuple[0] - def data_ = tuple[1] - - // TODO: could move fromState to here - - // fetch default params from functionality - def defaultArgs = meta.config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - // fetch overrides in params - def paramArgs = meta.config.allArguments - .findAll { par -> - def argKey = key_ + "__" + par.plainName - params.containsKey(argKey) - } - .collectEntries { [ it.plainName, params[key_ + "__" + it.plainName] ] } - - // fetch overrides in data - def dataArgs = meta.config.allArguments - .findAll { data_.containsKey(it.plainName) } - .collectEntries { [ it.plainName, data_[it.plainName] ] } - - // combine params - def combinedArgs = defaultArgs + paramArgs + workflowArgs.args + dataArgs - - // remove arguments with explicit null values - combinedArgs - .removeAll{_, val -> val == null || val == "viash_no_value" || val == "force_null"} - - combinedArgs = _processInputValues(combinedArgs, meta.config, id_, key_) - - [id_, combinedArgs] + tuple.drop(2) - } - - // TODO: move some of the _meta.join_id wrangling to the safeJoin() function. - def chInitialOutput = chArgsWithDefaults - | _debug(workflowArgs, "processed") - // run workflow - | innerWorkflowFactory(workflowArgs) - // check output tuple - | map { id_, output_ -> - - // see if output map contains metadata - def meta_ = - output_ instanceof Map && output_.containsKey("_meta") ? - output_["_meta"] : - [:] - def join_id = meta_.join_id ?: id_ - - // remove metadata - output_ = output_.findAll{k, v -> k != "_meta"} - - // check value types - output_ = _processOutputValues(output_, meta.config, id_, key_) - - // simplify output if need be - if (workflowArgs.auto.simplifyOutput && output_.size() == 1) { - output_ = output_.values()[0] - } - - [join_id, id_, output_] - } - // | view{"chInitialOutput: ${it.take(3)}"} - - // join the output [prev_id, new_id, output] with the previous state [prev_id, state, ...] - def chNewState = safeJoin(chInitialOutput, chModifiedFiltered, key_) - // input tuple format: [join_id, id, output, prev_state, ...] - // output tuple format: [join_id, id, new_state, ...] - | map{ tup -> - def new_state = workflowArgs.toState(tup.drop(1).take(3)) - tup.take(2) + [new_state] + tup.drop(4) - } - - if (workflowArgs.auto.publish == "state") { - def chPublish = chNewState - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [join_id, id, new_state] - | map{ tup -> - tup.take(3) - } - - safeJoin(chPublish, chArgsWithDefaults, key_) - // input tuple format: [join_id, id, new_state, orig_state, ...] - // output tuple format: [id, new_state, orig_state] - | map { tup -> - tup.drop(1).take(3) - } - | publishStatesByConfig(key: key_, config: meta.config) - } - - // remove join_id and meta - chReturn = chNewState - | map { tup -> - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [id, new_state, ...] - tup.drop(1) - } - | _debug(workflowArgs, "output") - | concat(chPassthrough) - - emit: chReturn - } - - def wf = workflowInstance.cloneWithName(key_) - - // add factory function - wf.metaClass.run = { runArgs -> - workflowFactory(runArgs, workflowArgs, meta) - } - // add config to module for later introspection - wf.metaClass.config = meta.config - - return wf -} - -nextflow.enable.dsl=2 - -// START COMPONENT-SPECIFIC CODE - -// create meta object -meta = [ - "resources_dir": moduleDir.toRealPath().normalize(), - "config": processConfig(readJsonBlob('''{ - "name" : "samtools_sort", - "namespace" : "samtools", - "version" : "v0.1.0", - "argument_groups" : [ - { - "name" : "Inputs", - "arguments" : [ - { - "type" : "file", - "name" : "--input", - "description" : "SAM/BAM/CRAM input file.", - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Outputs", - "arguments" : [ - { - "type" : "file", - "name" : "--output", - "description" : "Write final output to file.\n", - "example" : [ - "out.bam" - ], - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "output", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "string", - "name" : "--output_fmt", - "alternatives" : [ - "-O" - ], - "description" : "Specify output format (SAM, BAM, CRAM).\n", - "example" : [ - "BAM" - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "string", - "name" : "--output_fmt_option", - "description" : "Specify a single output file format option in the form\nof OPTION or OPTION=VALUE.\n", - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--reference", - "description" : "Reference sequence FASTA FILE.\n", - "example" : [ - "ref.fa" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--write_index", - "description" : "Automatically index the output files.\n", - "direction" : "input" - }, - { - "type" : "string", - "name" : "--prefix", - "alternatives" : [ - "-T" - ], - "description" : "Write temporary files to PREFIX.nnnn.bam.\n", - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--no_PG", - "description" : "Do not add a PG line.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--template_coordinate", - "description" : "Sort by template-coordinate.\n", - "direction" : "input" - }, - { - "type" : "string", - "name" : "--input_fmt_option", - "description" : "Specify a single input file format option in the form\nof OPTION or OPTION=VALUE.\n", - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Options", - "arguments" : [ - { - "type" : "integer", - "name" : "--compression", - "alternatives" : [ - "-l" - ], - "description" : "Set compression level, from 0 (uncompressed) to 9 (best).\n", - "default" : [ - 0 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--uncompressed", - "alternatives" : [ - "-u" - ], - "description" : "Output uncompressed data (equivalent to --compression 0).\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--minimiser", - "alternatives" : [ - "-M" - ], - "description" : "Use minimiser for clustering unaligned/unplaced reads.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--not_reverse", - "alternatives" : [ - "-R" - ], - "description" : "Do not use reverse strand (only compatible with --minimiser)\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--kmer_size", - "alternatives" : [ - "-K" - ], - "description" : "Kmer size to use for minimiser.\n", - "example" : [ - 20 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--order", - "alternatives" : [ - "-I" - ], - "description" : "Order minimisers by their position in FILE FASTA.\n", - "example" : [ - "ref.fa" - ], - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--window", - "alternatives" : [ - "-w" - ], - "description" : "Window size for minimiser INDEXING VIA --order REF.FA.\n", - "example" : [ - 100 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--homopolymers", - "alternatives" : [ - "-H" - ], - "description" : "Squash homopolymers when computing minimiser.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--natural_sort", - "alternatives" : [ - "-n" - ], - "description" : "Sort by read name (natural): cannot be used with samtools index.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--ascii_sort", - "alternatives" : [ - "-N" - ], - "description" : "Sort by read name (ASCII): cannot be used with samtools index.\n", - "direction" : "input" - }, - { - "type" : "string", - "name" : "--tag", - "alternatives" : [ - "-t" - ], - "description" : "Sort by value of TAG. Uses position as secondary index \n(or read name if --natural_sort is set).\n", - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - } - ], - "resources" : [ - { - "type" : "bash_script", - "path" : "script.sh", - "is_executable" : true - } - ], - "description" : "Sort SAM/BAM/CRAM file.", - "test_resources" : [ - { - "type" : "bash_script", - "path" : "test.sh", - "is_executable" : true - }, - { - "type" : "file", - "path" : "test_data" - } - ], - "status" : "enabled", - "requirements" : { - "commands" : [ - "ps" - ] - }, - "keywords" : [ - "sort", - "bam", - "sam", - "cram" - ], - "license" : "MIT/Expat", - "references" : { - "doi" : [ - "10.1093/bioinformatics/btp352", - "10.1093/gigascience/giab008" - ] - }, - "links" : { - "repository" : "https://github.com/samtools/samtools", - "homepage" : "https://www.htslib.org/", - "documentation" : "https://www.htslib.org/doc/samtools-sort.html" - }, - "runners" : [ - { - "type" : "executable", - "id" : "executable", - "docker_setup_strategy" : "ifneedbepullelsecachedbuild" - }, - { - "type" : "nextflow", - "id" : "nextflow", - "directives" : { - "tag" : "$id" - }, - "auto" : { - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false - }, - "config" : { - "labels" : { - "mem1gb" : "memory = 1000000000.B", - "mem2gb" : "memory = 2000000000.B", - "mem5gb" : "memory = 5000000000.B", - "mem10gb" : "memory = 10000000000.B", - "mem20gb" : "memory = 20000000000.B", - "mem50gb" : "memory = 50000000000.B", - "mem100gb" : "memory = 100000000000.B", - "mem200gb" : "memory = 200000000000.B", - "mem500gb" : "memory = 500000000000.B", - "mem1tb" : "memory = 1000000000000.B", - "mem2tb" : "memory = 2000000000000.B", - "mem5tb" : "memory = 5000000000000.B", - "mem10tb" : "memory = 10000000000000.B", - "mem20tb" : "memory = 20000000000000.B", - "mem50tb" : "memory = 50000000000000.B", - "mem100tb" : "memory = 100000000000000.B", - "mem200tb" : "memory = 200000000000000.B", - "mem500tb" : "memory = 500000000000000.B", - "mem1gib" : "memory = 1073741824.B", - "mem2gib" : "memory = 2147483648.B", - "mem4gib" : "memory = 4294967296.B", - "mem8gib" : "memory = 8589934592.B", - "mem16gib" : "memory = 17179869184.B", - "mem32gib" : "memory = 34359738368.B", - "mem64gib" : "memory = 68719476736.B", - "mem128gib" : "memory = 137438953472.B", - "mem256gib" : "memory = 274877906944.B", - "mem512gib" : "memory = 549755813888.B", - "mem1tib" : "memory = 1099511627776.B", - "mem2tib" : "memory = 2199023255552.B", - "mem4tib" : "memory = 4398046511104.B", - "mem8tib" : "memory = 8796093022208.B", - "mem16tib" : "memory = 17592186044416.B", - "mem32tib" : "memory = 35184372088832.B", - "mem64tib" : "memory = 70368744177664.B", - "mem128tib" : "memory = 140737488355328.B", - "mem256tib" : "memory = 281474976710656.B", - "mem512tib" : "memory = 562949953421312.B", - "cpu1" : "cpus = 1", - "cpu2" : "cpus = 2", - "cpu5" : "cpus = 5", - "cpu10" : "cpus = 10", - "cpu20" : "cpus = 20", - "cpu50" : "cpus = 50", - "cpu100" : "cpus = 100", - "cpu200" : "cpus = 200", - "cpu500" : "cpus = 500", - "cpu1000" : "cpus = 1000" - } - }, - "debug" : false, - "container" : "docker" - } - ], - "engines" : [ - { - "type" : "docker", - "id" : "docker", - "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", - "target_registry" : "images.viash-hub.com", - "target_tag" : "v0.1.0", - "namespace_separator" : "/", - "setup" : [ - { - "type" : "docker", - "run" : [ - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\\\nsed 's#Using ##;s# \\\\([0-9\\\\.]*\\\\)$#: \\\\1#' > /var/software_versions.txt\n" - ] - } - ] - }, - { - "type" : "native", - "id" : "native" - } - ], - "build_info" : { - "config" : "/workdir/root/repo/src/samtools/samtools_sort/config.vsh.yaml", - "runner" : "nextflow", - "engine" : "docker|native", - "output" : "target/nextflow/samtools/samtools_sort", - "viash_version" : "0.9.0-RC6", - "git_commit" : "b84b29747d0635f2ac83ea63b496be9a9edb6724", - "git_remote" : "https://github.com/viash-hub/biobox" - }, - "package_config" : { - "name" : "biobox", - "version" : "v0.1.0", - "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC6", - "source" : "src", - "target" : "target", - "config_mods" : [ - ".requirements.commands := ['ps']\n", - ".engines += { type: \\"native\\" }", - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - ], - "keywords" : [ - "bioinformatics", - "modules", - "sequencing" - ], - "license" : "MIT", - "organization" : "vsh", - "links" : { - "repository" : "https://github.com/viash-hub/biobox", - "issue_tracker" : "https://github.com/viash-hub/biobox/issues" - } - } -}''')) -] - -// resolve dependencies dependencies (if any) - - -// inner workflow -// inner workflow hook -def innerWorkflowFactory(args) { - def rawScript = '''set -e -tempscript=".viash_script.sh" -cat > "$tempscript" << VIASHMAIN -#!/bin/bash - -## VIASH START -# The following code has been auto-generated by Viash. -$( if [ ! -z ${VIASH_PAR_INPUT+x} ]; then echo "${VIASH_PAR_INPUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_input='&'#" ; else echo "# par_input="; fi ) -$( if [ ! -z ${VIASH_PAR_OUTPUT+x} ]; then echo "${VIASH_PAR_OUTPUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_output='&'#" ; else echo "# par_output="; fi ) -$( if [ ! -z ${VIASH_PAR_OUTPUT_FMT+x} ]; then echo "${VIASH_PAR_OUTPUT_FMT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_output_fmt='&'#" ; else echo "# par_output_fmt="; fi ) -$( if [ ! -z ${VIASH_PAR_OUTPUT_FMT_OPTION+x} ]; then echo "${VIASH_PAR_OUTPUT_FMT_OPTION}" | sed "s#'#'\\"'\\"'#g;s#.*#par_output_fmt_option='&'#" ; else echo "# par_output_fmt_option="; fi ) -$( if [ ! -z ${VIASH_PAR_REFERENCE+x} ]; then echo "${VIASH_PAR_REFERENCE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_reference='&'#" ; else echo "# par_reference="; fi ) -$( if [ ! -z ${VIASH_PAR_WRITE_INDEX+x} ]; then echo "${VIASH_PAR_WRITE_INDEX}" | sed "s#'#'\\"'\\"'#g;s#.*#par_write_index='&'#" ; else echo "# par_write_index="; fi ) -$( if [ ! -z ${VIASH_PAR_PREFIX+x} ]; then echo "${VIASH_PAR_PREFIX}" | sed "s#'#'\\"'\\"'#g;s#.*#par_prefix='&'#" ; else echo "# par_prefix="; fi ) -$( if [ ! -z ${VIASH_PAR_NO_PG+x} ]; then echo "${VIASH_PAR_NO_PG}" | sed "s#'#'\\"'\\"'#g;s#.*#par_no_PG='&'#" ; else echo "# par_no_PG="; fi ) -$( if [ ! -z ${VIASH_PAR_TEMPLATE_COORDINATE+x} ]; then echo "${VIASH_PAR_TEMPLATE_COORDINATE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_template_coordinate='&'#" ; else echo "# par_template_coordinate="; fi ) -$( if [ ! -z ${VIASH_PAR_INPUT_FMT_OPTION+x} ]; then echo "${VIASH_PAR_INPUT_FMT_OPTION}" | sed "s#'#'\\"'\\"'#g;s#.*#par_input_fmt_option='&'#" ; else echo "# par_input_fmt_option="; fi ) -$( if [ ! -z ${VIASH_PAR_COMPRESSION+x} ]; then echo "${VIASH_PAR_COMPRESSION}" | sed "s#'#'\\"'\\"'#g;s#.*#par_compression='&'#" ; else echo "# par_compression="; fi ) -$( if [ ! -z ${VIASH_PAR_UNCOMPRESSED+x} ]; then echo "${VIASH_PAR_UNCOMPRESSED}" | sed "s#'#'\\"'\\"'#g;s#.*#par_uncompressed='&'#" ; else echo "# par_uncompressed="; fi ) -$( if [ ! -z ${VIASH_PAR_MINIMISER+x} ]; then echo "${VIASH_PAR_MINIMISER}" | sed "s#'#'\\"'\\"'#g;s#.*#par_minimiser='&'#" ; else echo "# par_minimiser="; fi ) -$( if [ ! -z ${VIASH_PAR_NOT_REVERSE+x} ]; then echo "${VIASH_PAR_NOT_REVERSE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_not_reverse='&'#" ; else echo "# par_not_reverse="; fi ) -$( if [ ! -z ${VIASH_PAR_KMER_SIZE+x} ]; then echo "${VIASH_PAR_KMER_SIZE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_kmer_size='&'#" ; else echo "# par_kmer_size="; fi ) -$( if [ ! -z ${VIASH_PAR_ORDER+x} ]; then echo "${VIASH_PAR_ORDER}" | sed "s#'#'\\"'\\"'#g;s#.*#par_order='&'#" ; else echo "# par_order="; fi ) -$( if [ ! -z ${VIASH_PAR_WINDOW+x} ]; then echo "${VIASH_PAR_WINDOW}" | sed "s#'#'\\"'\\"'#g;s#.*#par_window='&'#" ; else echo "# par_window="; fi ) -$( if [ ! -z ${VIASH_PAR_HOMOPOLYMERS+x} ]; then echo "${VIASH_PAR_HOMOPOLYMERS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_homopolymers='&'#" ; else echo "# par_homopolymers="; fi ) -$( if [ ! -z ${VIASH_PAR_NATURAL_SORT+x} ]; then echo "${VIASH_PAR_NATURAL_SORT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_natural_sort='&'#" ; else echo "# par_natural_sort="; fi ) -$( if [ ! -z ${VIASH_PAR_ASCII_SORT+x} ]; then echo "${VIASH_PAR_ASCII_SORT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_ascii_sort='&'#" ; else echo "# par_ascii_sort="; fi ) -$( if [ ! -z ${VIASH_PAR_TAG+x} ]; then echo "${VIASH_PAR_TAG}" | sed "s#'#'\\"'\\"'#g;s#.*#par_tag='&'#" ; else echo "# par_tag="; fi ) -$( if [ ! -z ${VIASH_META_NAME+x} ]; then echo "${VIASH_META_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_name='&'#" ; else echo "# meta_name="; fi ) -$( if [ ! -z ${VIASH_META_FUNCTIONALITY_NAME+x} ]; then echo "${VIASH_META_FUNCTIONALITY_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_functionality_name='&'#" ; else echo "# meta_functionality_name="; fi ) -$( if [ ! -z ${VIASH_META_RESOURCES_DIR+x} ]; then echo "${VIASH_META_RESOURCES_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_resources_dir='&'#" ; else echo "# meta_resources_dir="; fi ) -$( if [ ! -z ${VIASH_META_EXECUTABLE+x} ]; then echo "${VIASH_META_EXECUTABLE}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_executable='&'#" ; else echo "# meta_executable="; fi ) -$( if [ ! -z ${VIASH_META_CONFIG+x} ]; then echo "${VIASH_META_CONFIG}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_config='&'#" ; else echo "# meta_config="; fi ) -$( if [ ! -z ${VIASH_META_TEMP_DIR+x} ]; then echo "${VIASH_META_TEMP_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_temp_dir='&'#" ; else echo "# meta_temp_dir="; fi ) -$( if [ ! -z ${VIASH_META_CPUS+x} ]; then echo "${VIASH_META_CPUS}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_cpus='&'#" ; else echo "# meta_cpus="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_B+x} ]; then echo "${VIASH_META_MEMORY_B}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_b='&'#" ; else echo "# meta_memory_b="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KB+x} ]; then echo "${VIASH_META_MEMORY_KB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kb='&'#" ; else echo "# meta_memory_kb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MB+x} ]; then echo "${VIASH_META_MEMORY_MB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mb='&'#" ; else echo "# meta_memory_mb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GB+x} ]; then echo "${VIASH_META_MEMORY_GB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gb='&'#" ; else echo "# meta_memory_gb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TB+x} ]; then echo "${VIASH_META_MEMORY_TB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tb='&'#" ; else echo "# meta_memory_tb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PB+x} ]; then echo "${VIASH_META_MEMORY_PB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pb='&'#" ; else echo "# meta_memory_pb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KIB+x} ]; then echo "${VIASH_META_MEMORY_KIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kib='&'#" ; else echo "# meta_memory_kib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MIB+x} ]; then echo "${VIASH_META_MEMORY_MIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mib='&'#" ; else echo "# meta_memory_mib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GIB+x} ]; then echo "${VIASH_META_MEMORY_GIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gib='&'#" ; else echo "# meta_memory_gib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TIB+x} ]; then echo "${VIASH_META_MEMORY_TIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tib='&'#" ; else echo "# meta_memory_tib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PIB+x} ]; then echo "${VIASH_META_MEMORY_PIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pib='&'#" ; else echo "# meta_memory_pib="; fi ) - -## VIASH END - -set -e - -[[ "\\$par_uncompressed" == "false" ]] && unset par_uncompressed -[[ "\\$par_minimiser" == "false" ]] && unset par_minimiser -[[ "\\$par_not_reverse" == "false" ]] && unset par_not_reverse -[[ "\\$par_homopolymers" == "false" ]] && unset par_homopolymers -[[ "\\$par_natural_sort" == "false" ]] && unset par_natural_sort -[[ "\\$par_ascii_sort" == "false" ]] && unset par_ascii_sort -[[ "\\$par_template_coordinate" == "false" ]] && unset par_template_coordinate -[[ "\\$par_write_index" == "false" ]] && unset par_write_index -[[ "\\$par_no_PG" == "false" ]] && unset par_no_PG - - -samtools sort \\\\ - \\${par_compression:+-l "\\$par_compression"} \\\\ - \\${par_uncompressed:+-u} \\\\ - \\${par_minimiser:+-M} \\\\ - \\${par_not_reverse:+-R} \\\\ - \\${par_kmer_size:+-K "\\$par_kmer_size"} \\\\ - \\${par_order:+-I "\\$par_order"} \\\\ - \\${par_window:+-w "\\$par_window"} \\\\ - \\${par_homopolymers:+-H} \\\\ - \\${par_natural_sort:+-n} \\\\ - \\${par_ascii_sort:+-N} \\\\ - \\${par_tag:+-t "\\$par_tag"} \\\\ - \\${par_input_fmt_option:+--input-fmt-option "\\$par_input_fmt_option"} \\\\ - \\${par_template_coordinate:+--template-coordinate} \\\\ - \\${par_write_index:+--write-index} \\\\ - \\${par_prefix:+-T "\\$par_prefix"} \\\\ - \\${par_no_PG:+--no-PG} \\\\ - \\${par_output_fmt:+-O "\\$par_output_fmt"} \\\\ - \\${par_output_fmt_option:+--output-fmt-option "\\$par_output_fmt_option"} \\\\ - \\${par_reference:+--reference "\\$par_reference"} \\\\ - -o "\\$par_output" \\\\ - "\\$par_input" - -# save text files containing the output of samtools view for later comparison -samtools view "\\$par_output" -o "\\$par_output".txt -VIASHMAIN -bash "$tempscript" -''' - - return vdsl3WorkflowFactory(args, meta, rawScript) -} - - - -/** - * Generate a workflow for VDSL3 modules. - * - * This function is called by the workflowFactory() function. - * - * Input channel: [id, input_map] - * Output channel: [id, output_map] - * - * Internally, this workflow will convert the input channel - * to a format which the Nextflow module will be able to handle. - */ -def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { - def key = args["key"] - def processObj = null - - workflow processWf { - take: input_ - main: - - if (processObj == null) { - processObj = _vdsl3ProcessFactory(args, meta, rawScript) - } - - output_ = input_ - | map { tuple -> - def id = tuple[0] - def data_ = tuple[1] - - if (workflow.stubRun) { - // add id if missing - data_ = [id: 'stub'] + data_ - } - - // process input files separately - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { par -> - def val = data_.containsKey(par.plainName) ? data_[par.plainName] : [] - def inputFiles = [] - if (val == null) { - inputFiles = [] - } else if (val instanceof List) { - inputFiles = val - } else if (val instanceof Path) { - inputFiles = [ val ] - } else { - inputFiles = [] - } - if (!workflow.stubRun) { - // throw error when an input file doesn't exist - inputFiles.each{ file -> - assert file.exists() : - "Error in module '${key}' id '${id}' argument '${par.plainName}'.\n" + - " Required input file does not exist.\n" + - " Path: '$file'.\n" + - " Expected input file to exist" - } - } - inputFiles - } - - // remove input files - def argsExclInputFiles = meta.config.allArguments - .findAll { (it.type != "file" || it.direction != "input") && data_.containsKey(it.plainName) } - .collectEntries { par -> - def parName = par.plainName - def val = data_[parName] - if (par.multiple && val instanceof Collection) { - val = val.join(par.multiple_sep) - } - if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) - } - [parName, val] - } - - [ id ] + inputPaths + [ argsExclInputFiles, meta.resources_dir ] - } - | processObj - | map { output -> - def outputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .indexed() - .collectEntries{ index, par -> - def out = output[index + 1] - // strip dummy '.exitcode' file from output (see nextflow-io/nextflow#2678) - if (!out instanceof List || out.size() <= 1) { - if (par.multiple) { - out = [] - } else { - assert !par.required : - "Error in module '${key}' id '${output[0]}' argument '${par.plainName}'.\n" + - " Required output file is missing" - out = null - } - } else if (out.size() == 2 && !par.multiple) { - out = out[1] - } else { - out = out.drop(1) - } - [ par.plainName, out ] - } - - // drop null outputs - outputFiles.removeAll{it.value == null} - - [ output[0], outputFiles ] - } - emit: output_ - } - - return processWf -} - -// depends on: session? -def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { - // autodetect process key - def wfKey = workflowArgs["key"] - def procKeyPrefix = "${wfKey}_process" - def scriptMeta = nextflow.script.ScriptMeta.current() - def existing = scriptMeta.getProcessNames().findAll{it.startsWith(procKeyPrefix)} - def numbers = existing.collect{it.replace(procKeyPrefix, "0").toInteger()} - def newNumber = (numbers + [-1]).max() + 1 - - def procKey = newNumber == 0 ? procKeyPrefix : "$procKeyPrefix$newNumber" - - if (newNumber > 0) { - log.warn "Key for module '${wfKey}' is duplicated.\n", - "If you run a component multiple times in the same workflow,\n" + - "it's recommended you set a unique key for every call,\n" + - "for example: ${wfKey}.run(key: \"foo\")." - } - - // subset directives and convert to list of tuples - def drctv = workflowArgs.directives - - // TODO: unit test the two commands below - // convert publish array into tags - def valueToStr = { val -> - // ignore closures - if (val instanceof CharSequence) { - if (!val.matches('^[{].*[}]$')) { - '"' + val + '"' - } else { - val - } - } else if (val instanceof List) { - "[" + val.collect{valueToStr(it)}.join(", ") + "]" - } else if (val instanceof Map) { - "[" + val.collect{k, v -> k + ": " + valueToStr(v)}.join(", ") + "]" - } else { - val.inspect() - } - } - - // multiple entries allowed: label, publishdir - def drctvStrs = drctv.collect { key, value -> - if (key in ["label", "publishDir"]) { - value.collect{ val -> - if (val instanceof Map) { - "\n$key " + val.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else if (val == null) { - "" - } else { - "\n$key " + valueToStr(val) - } - }.join() - } else if (value instanceof Map) { - "\n$key " + value.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else { - "\n$key " + valueToStr(value) - } - }.join() - - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { ', path(viash_par_' + it.plainName + ', stageAs: "_viash_par/' + it.plainName + '_?/*")' } - .join() - - def outputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - // insert dummy into every output (see nextflow-io/nextflow#2678) - if (!par.multiple) { - ', path{[".exitcode", args.' + par.plainName + ']}' - } else { - ', path{[".exitcode"] + args.' + par.plainName + '}' - } - } - .join() - - // TODO: move this functionality somewhere else? - if (workflowArgs.auto.transcript) { - outputPaths = outputPaths + ', path{[".exitcode", ".command*"]}' - } else { - outputPaths = outputPaths + ', path{[".exitcode"]}' - } - - // create dirs for output files (based on BashWrapper.createParentFiles) - def createParentStr = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" && it.create_parent } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // construct inputFileExports - def inputFileExports = meta.config.allArguments - .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } - .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" - } - - // NOTE: if using docker, use /tmp instead of tmpDir! - def tmpDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('VIASH_TMPDIR') ?: - System.getenv('VIASH_TEMPDIR') ?: - System.getenv('VIASH_TMP') ?: - System.getenv('TEMP') ?: - System.getenv('TMPDIR') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMP') ?: - '/tmp' - ).toAbsolutePath() - - // construct stub - def stub = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"touch2 \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"].replace(\"_*\", \"_0\") : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // escape script - def escapedScript = rawScript.replace('\\', '\\\\').replace('$', '\\$').replace('"""', '\\"\\"\\"') - - // publishdir assert - def assertStr = (workflowArgs.auto.publish == true) || workflowArgs.auto.transcript ? - """\nassert task.publishDir.size() > 0: "if auto.publish is true, params.publish_dir needs to be defined.\\n Example: --publish_dir './output/'" """ : - "" - - // generate process string - def procStr = - """nextflow.enable.dsl=2 - | - |process $procKey {$drctvStrs - |input: - | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") - |output: - | tuple val("\$id")$outputPaths, optional: true - |stub: - |\"\"\" - |touch2() { mkdir -p "\\\$(dirname "\\\$1")" && touch "\\\$1" ; } - |$stub - |\"\"\" - |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } - |def parInject = args - | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} - | .join("\\n") - |\"\"\" - |# meta exports - |export VIASH_META_RESOURCES_DIR="\${resourcesDir}" - |export VIASH_META_TEMP_DIR="${['docker', 'podman', 'charliecloud'].any{ it == workflow.containerEngine } ? '/tmp' : tmpDir}" - |export VIASH_META_NAME="${meta.config.name}" - |# export VIASH_META_EXECUTABLE="\\\$VIASH_META_RESOURCES_DIR/\\\$VIASH_META_NAME" - |export VIASH_META_CONFIG="\\\$VIASH_META_RESOURCES_DIR/.config.vsh.yaml" - |\${task.cpus ? "export VIASH_META_CPUS=\$task.cpus" : "" } - |\${task.memory?.bytes != null ? "export VIASH_META_MEMORY_B=\$task.memory.bytes" : "" } - |if [ ! -z \\\${VIASH_META_MEMORY_B+x} ]; then - | export VIASH_META_MEMORY_KB=\\\$(( (\\\$VIASH_META_MEMORY_B+999) / 1000 )) - | export VIASH_META_MEMORY_MB=\\\$(( (\\\$VIASH_META_MEMORY_KB+999) / 1000 )) - | export VIASH_META_MEMORY_GB=\\\$(( (\\\$VIASH_META_MEMORY_MB+999) / 1000 )) - | export VIASH_META_MEMORY_TB=\\\$(( (\\\$VIASH_META_MEMORY_GB+999) / 1000 )) - | export VIASH_META_MEMORY_PB=\\\$(( (\\\$VIASH_META_MEMORY_TB+999) / 1000 )) - | export VIASH_META_MEMORY_KIB=\\\$(( (\\\$VIASH_META_MEMORY_B+1023) / 1024 )) - | export VIASH_META_MEMORY_MIB=\\\$(( (\\\$VIASH_META_MEMORY_KIB+1023) / 1024 )) - | export VIASH_META_MEMORY_GIB=\\\$(( (\\\$VIASH_META_MEMORY_MIB+1023) / 1024 )) - | export VIASH_META_MEMORY_TIB=\\\$(( (\\\$VIASH_META_MEMORY_GIB+1023) / 1024 )) - | export VIASH_META_MEMORY_PIB=\\\$(( (\\\$VIASH_META_MEMORY_TIB+1023) / 1024 )) - |fi - | - |# meta synonyms - |export VIASH_TEMP="\\\$VIASH_META_TEMP_DIR" - |export TEMP_DIR="\\\$VIASH_META_TEMP_DIR" - | - |# create output dirs if need be - |function mkdir_parent { - | for file in "\\\$@"; do - | mkdir -p "\\\$(dirname "\\\$file")" - | done - |} - |$createParentStr - | - |# argument exports${inputFileExports.join()} - |\$parInject - | - |# process script - |${escapedScript} - |\"\"\" - |} - |""".stripMargin() - - // TODO: print on debug - // if (workflowArgs.debug == true) { - // println("######################\n$procStr\n######################") - // } - - // write process to temp file - def tempFile = java.nio.file.Files.createTempFile("viash-process-${procKey}-", ".nf") - addShutdownHook { java.nio.file.Files.deleteIfExists(tempFile) } - tempFile.text = procStr - - // create process from temp file - def binding = new nextflow.script.ScriptBinding([:]) - def session = nextflow.Nextflow.getSession() - def parser = new nextflow.script.ScriptParser(session) - .setModule(true) - .setBinding(binding) - def moduleScript = parser.runScript(tempFile) - .getScript() - - // register module in meta - def module = new nextflow.script.IncludeDef.Module(name: procKey) - scriptMeta.addModule(moduleScript, module.name, module.alias) - - // retrieve and return process from meta - return scriptMeta.getProcess(procKey) -} - -// defaults -meta["defaults"] = [ - // key to be used to trace the process and determine output names - key: null, - - // fixed arguments to be passed to script - args: [:], - - // default directives - directives: readJsonBlob('''{ - "container" : { - "registry" : "images.viash-hub.com", - "image" : "vsh/biobox/samtools/samtools_sort", - "tag" : "v0.1.0" - }, - "tag" : "$id" -}'''), - - // auto settings - auto: readJsonBlob('''{ - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false -}'''), - - // Apply a map over the incoming tuple - // Example: `{ tup -> [ tup[0], [input: tup[1].output] ] + tup.drop(2) }` - map: null, - - // Apply a map over the ID element of a tuple (i.e. the first element) - // Example: `{ id -> id + "_foo" }` - mapId: null, - - // Apply a map over the data element of a tuple (i.e. the second element) - // Example: `{ data -> [ input: data.output ] }` - mapData: null, - - // Apply a map over the passthrough elements of a tuple (i.e. the tuple excl. the first two elements) - // Example: `{ pt -> pt.drop(1) }` - mapPassthrough: null, - - // Filter the channel - // Example: `{ tup -> tup[0] == "foo" }` - filter: null, - - // Choose whether or not to run the component on the tuple if the condition is true. - // Otherwise, the tuple will be passed through. - // Example: `{ tup -> tup[0] != "skip_this" }` - runIf: null, - - // Rename keys in the data field of the tuple (i.e. the second element) - // Will likely be deprecated in favour of `fromState`. - // Example: `[ "new_key": "old_key" ]` - renameKeys: null, - - // Fetch data from the state and pass it to the module without altering the current state. - // - // `fromState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be passed to the module as is. - // - If it is a `List[String]`, the data will be the values of the state at the given keys. - // - If it is a `Map[String, String]`, the data will be the values of the state at the given keys, with the keys renamed according to the map. - // - If it is a function, the tuple (`[id, state]`) in the channel will be passed to the function, and the result will be used as the data. - // - // Example: `{ id, state -> [input: state.fastq_file] }` - // Default: `null` - fromState: null, - - // Determine how the state should be updated after the module has been run. - // - // `toState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be replaced with the output of the module. - // - If it is a `List[String]`, the state will be updated with the values of the data at the given keys. - // - If it is a `Map[String, String]`, the state will be updated with the values of the data at the given keys, with the keys renamed according to the map. - // - If it is a function, a tuple (`[id, output, state]`) will be passed to the function, and the result will be used as the new state. - // - // Example: `{ id, output, state -> state + [counts: state.output] }` - // Default: `{ id, output, state -> output }` - toState: null, - - // Whether or not to print debug messages - // Default: `false` - debug: false -] - -// initialise default workflow -meta["workflow"] = workflowFactory([key: meta.config.name], meta.defaults, meta) - -// add workflow to environment -nextflow.script.ScriptMeta.current().addDefinition(meta.workflow) - -// anonymous workflow for running this module as a standalone -workflow { - // add id argument if it's not already in the config - // TODO: deep copy - def newConfig = deepClone(meta.config) - def newParams = deepClone(params) - - def argsContainsId = newConfig.allArguments.any{it.plainName == "id"} - if (!argsContainsId) { - def idArg = [ - 'name': '--id', - 'required': false, - 'type': 'string', - 'description': 'A unique id for every entry.', - 'multiple': false - ] - newConfig.arguments.add(0, idArg) - newConfig = processConfig(newConfig) - } - if (!newParams.containsKey("id")) { - newParams.id = "run" - } - - helpMessage(newConfig) - - channelFromParams(newParams, newConfig) - // make sure id is not in the state if id is not in the args - | map {id, state -> - if (!argsContainsId) { - [id, state.findAll{k, v -> k != "id"}] - } else { - [id, state] - } - } - | meta.workflow.run( - auto: [ publish: "state" ] - ) -} - -// END COMPONENT-SPECIFIC CODE diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/nextflow.config deleted file mode 100644 index 2248d9e..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/nextflow.config +++ /dev/null @@ -1,125 +0,0 @@ -manifest { - name = 'samtools/samtools_sort' - mainScript = 'main.nf' - nextflowVersion = '!>=20.12.1-edge' - version = 'v0.1.0' - description = 'Sort SAM/BAM/CRAM file.' -} - -process.container = 'nextflow/bash:latest' - -// detect tempdir -tempDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMPDIR') ?: - '/tmp' -).toAbsolutePath() - -profiles { - no_publish { - process { - withName: '.*' { - publishDir = [ - enabled: false - ] - } - } - } - mount_temp { - docker.temp = tempDir - podman.temp = tempDir - charliecloud.temp = tempDir - } - docker { - docker.enabled = true - // docker.userEmulation = true - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - singularity { - singularity.enabled = true - singularity.autoMounts = true - docker.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - podman { - podman.enabled = true - docker.enabled = false - singularity.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - shifter { - shifter.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - charliecloud.enabled = false - } - charliecloud { - charliecloud.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - } -} - -process{ - withLabel: mem1gb { memory = 1000000000.B } - withLabel: mem2gb { memory = 2000000000.B } - withLabel: mem5gb { memory = 5000000000.B } - withLabel: mem10gb { memory = 10000000000.B } - withLabel: mem20gb { memory = 20000000000.B } - withLabel: mem50gb { memory = 50000000000.B } - withLabel: mem100gb { memory = 100000000000.B } - withLabel: mem200gb { memory = 200000000000.B } - withLabel: mem500gb { memory = 500000000000.B } - withLabel: mem1tb { memory = 1000000000000.B } - withLabel: mem2tb { memory = 2000000000000.B } - withLabel: mem5tb { memory = 5000000000000.B } - withLabel: mem10tb { memory = 10000000000000.B } - withLabel: mem20tb { memory = 20000000000000.B } - withLabel: mem50tb { memory = 50000000000000.B } - withLabel: mem100tb { memory = 100000000000000.B } - withLabel: mem200tb { memory = 200000000000000.B } - withLabel: mem500tb { memory = 500000000000000.B } - withLabel: mem1gib { memory = 1073741824.B } - withLabel: mem2gib { memory = 2147483648.B } - withLabel: mem4gib { memory = 4294967296.B } - withLabel: mem8gib { memory = 8589934592.B } - withLabel: mem16gib { memory = 17179869184.B } - withLabel: mem32gib { memory = 34359738368.B } - withLabel: mem64gib { memory = 68719476736.B } - withLabel: mem128gib { memory = 137438953472.B } - withLabel: mem256gib { memory = 274877906944.B } - withLabel: mem512gib { memory = 549755813888.B } - withLabel: mem1tib { memory = 1099511627776.B } - withLabel: mem2tib { memory = 2199023255552.B } - withLabel: mem4tib { memory = 4398046511104.B } - withLabel: mem8tib { memory = 8796093022208.B } - withLabel: mem16tib { memory = 17592186044416.B } - withLabel: mem32tib { memory = 35184372088832.B } - withLabel: mem64tib { memory = 70368744177664.B } - withLabel: mem128tib { memory = 140737488355328.B } - withLabel: mem256tib { memory = 281474976710656.B } - withLabel: mem512tib { memory = 562949953421312.B } - withLabel: cpu1 { cpus = 1 } - withLabel: cpu2 { cpus = 2 } - withLabel: cpu5 { cpus = 5 } - withLabel: cpu10 { cpus = 10 } - withLabel: cpu20 { cpus = 20 } - withLabel: cpu50 { cpus = 50 } - withLabel: cpu100 { cpus = 100 } - withLabel: cpu200 { cpus = 200 } - withLabel: cpu500 { cpus = 500 } - withLabel: cpu1000 { cpus = 1000 } -} - - diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/nextflow_schema.json deleted file mode 100644 index 74147b3..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/nextflow_schema.json +++ /dev/null @@ -1,309 +0,0 @@ -{ -"$schema": "http://json-schema.org/draft-07/schema", -"title": "samtools_sort", -"description": "Sort SAM/BAM/CRAM file.", -"type": "object", -"definitions": { - - - - "inputs" : { - "title": "Inputs", - "type": "object", - "description": "No description", - "properties": { - - - "input": { - "type": - "string", - "description": "Type: `file`, required. SAM/BAM/CRAM input file", - "help_text": "Type: `file`, required. SAM/BAM/CRAM input file." - - } - - -} -}, - - - "outputs" : { - "title": "Outputs", - "type": "object", - "description": "No description", - "properties": { - - - "output": { - "type": - "string", - "description": "Type: `file`, required, default: `$id.$key.output.bam`, example: `out.bam`. Write final output to file", - "help_text": "Type: `file`, required, default: `$id.$key.output.bam`, example: `out.bam`. Write final output to file.\n" - , - "default": "$id.$key.output.bam" - } - - - , - "output_fmt": { - "type": - "string", - "description": "Type: `string`, example: `BAM`. Specify output format (SAM, BAM, CRAM)", - "help_text": "Type: `string`, example: `BAM`. Specify output format (SAM, BAM, CRAM).\n" - - } - - - , - "output_fmt_option": { - "type": - "string", - "description": "Type: `string`. Specify a single output file format option in the form\nof OPTION or OPTION=VALUE", - "help_text": "Type: `string`. Specify a single output file format option in the form\nof OPTION or OPTION=VALUE.\n" - - } - - - , - "reference": { - "type": - "string", - "description": "Type: `file`, example: `ref.fa`. Reference sequence FASTA FILE", - "help_text": "Type: `file`, example: `ref.fa`. Reference sequence FASTA FILE.\n" - - } - - - , - "write_index": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Automatically index the output files", - "help_text": "Type: `boolean_true`, default: `false`. Automatically index the output files.\n" - , - "default": "False" - } - - - , - "prefix": { - "type": - "string", - "description": "Type: `string`. Write temporary files to PREFIX", - "help_text": "Type: `string`. Write temporary files to PREFIX.nnnn.bam.\n" - - } - - - , - "no_PG": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Do not add a PG line", - "help_text": "Type: `boolean_true`, default: `false`. Do not add a PG line.\n" - , - "default": "False" - } - - - , - "template_coordinate": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Sort by template-coordinate", - "help_text": "Type: `boolean_true`, default: `false`. Sort by template-coordinate.\n" - , - "default": "False" - } - - - , - "input_fmt_option": { - "type": - "string", - "description": "Type: `string`. Specify a single input file format option in the form\nof OPTION or OPTION=VALUE", - "help_text": "Type: `string`. Specify a single input file format option in the form\nof OPTION or OPTION=VALUE.\n" - - } - - -} -}, - - - "options" : { - "title": "Options", - "type": "object", - "description": "No description", - "properties": { - - - "compression": { - "type": - "integer", - "description": "Type: `integer`, default: `0`. Set compression level, from 0 (uncompressed) to 9 (best)", - "help_text": "Type: `integer`, default: `0`. Set compression level, from 0 (uncompressed) to 9 (best).\n" - , - "default": "0" - } - - - , - "uncompressed": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Output uncompressed data (equivalent to --compression 0)", - "help_text": "Type: `boolean_true`, default: `false`. Output uncompressed data (equivalent to --compression 0).\n" - , - "default": "False" - } - - - , - "minimiser": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Use minimiser for clustering unaligned/unplaced reads", - "help_text": "Type: `boolean_true`, default: `false`. Use minimiser for clustering unaligned/unplaced reads.\n" - , - "default": "False" - } - - - , - "not_reverse": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Do not use reverse strand (only compatible with --minimiser)\n", - "help_text": "Type: `boolean_true`, default: `false`. Do not use reverse strand (only compatible with --minimiser)\n" - , - "default": "False" - } - - - , - "kmer_size": { - "type": - "integer", - "description": "Type: `integer`, example: `20`. Kmer size to use for minimiser", - "help_text": "Type: `integer`, example: `20`. Kmer size to use for minimiser.\n" - - } - - - , - "order": { - "type": - "string", - "description": "Type: `file`, example: `ref.fa`. Order minimisers by their position in FILE FASTA", - "help_text": "Type: `file`, example: `ref.fa`. Order minimisers by their position in FILE FASTA.\n" - - } - - - , - "window": { - "type": - "integer", - "description": "Type: `integer`, example: `100`. Window size for minimiser INDEXING VIA --order REF", - "help_text": "Type: `integer`, example: `100`. Window size for minimiser INDEXING VIA --order REF.FA.\n" - - } - - - , - "homopolymers": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Squash homopolymers when computing minimiser", - "help_text": "Type: `boolean_true`, default: `false`. Squash homopolymers when computing minimiser.\n" - , - "default": "False" - } - - - , - "natural_sort": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Sort by read name (natural): cannot be used with samtools index", - "help_text": "Type: `boolean_true`, default: `false`. Sort by read name (natural): cannot be used with samtools index.\n" - , - "default": "False" - } - - - , - "ascii_sort": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Sort by read name (ASCII): cannot be used with samtools index", - "help_text": "Type: `boolean_true`, default: `false`. Sort by read name (ASCII): cannot be used with samtools index.\n" - , - "default": "False" - } - - - , - "tag": { - "type": - "string", - "description": "Type: `string`. Sort by value of TAG", - "help_text": "Type: `string`. Sort by value of TAG. Uses position as secondary index \n(or read name if --natural_sort is set).\n" - - } - - -} -}, - - - "nextflow input-output arguments" : { - "title": "Nextflow input-output arguments", - "type": "object", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "properties": { - - - "publish_dir": { - "type": - "string", - "description": "Type: `string`, required, example: `output/`. Path to an output directory", - "help_text": "Type: `string`, required, example: `output/`. Path to an output directory." - - } - - - , - "param_list": { - "type": - "string", - "description": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel", - "help_text": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob.\n\n* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ [\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027], [\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027] ]`.\n* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`.\n* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]`.\n* A yaml blob can also be passed directly as a string. Example: `--param_list \"[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]\"`.\n\nWhen passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.", - "hidden": true - - } - - -} -} -}, -"allOf": [ - - { - "$ref": "#/definitions/inputs" - }, - - { - "$ref": "#/definitions/outputs" - }, - - { - "$ref": "#/definitions/options" - }, - - { - "$ref": "#/definitions/nextflow input-output arguments" - } -] -} diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/.config.vsh.yaml deleted file mode 100644 index c9523df..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/.config.vsh.yaml +++ /dev/null @@ -1,406 +0,0 @@ -name: "samtools_stats" -namespace: "samtools" -version: "v0.1.0" -argument_groups: -- name: "Inputs" - arguments: - - type: "file" - name: "--input" - description: "Input file.\n" - info: null - must_exist: true - create_parent: true - required: true - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--bai" - description: "Index file.\n" - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--fasta" - description: "Reference file the CRAM was created with.\n" - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--coverage" - alternatives: - - "-c" - description: "Coverage distribution min,max,step [1,1000,1].\n" - info: null - required: false - direction: "input" - multiple: true - multiple_sep: "," - - type: "boolean_true" - name: "--remove_dups" - alternatives: - - "-d" - description: "Exclude from statistics reads marked as duplicates.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--customized_index_file" - alternatives: - - "-X" - description: "Use a customized index file.\n" - info: null - direction: "input" - - type: "string" - name: "--required_flag" - alternatives: - - "-f" - description: "Required flag, 0 for unset. See also `samtools flags`.\n" - info: null - default: - - "0" - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "string" - name: "--filtering_flag" - alternatives: - - "-F" - description: "Filtering flag, 0 for unset. See also `samtools flags`.\n" - info: null - default: - - "0" - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "double" - name: "--GC_depth" - description: "The size of GC-depth bins (decreasing bin size increases memory\ - \ requirement).\n" - info: null - default: - - 20000.0 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--insert_size" - alternatives: - - "-i" - description: "Maximum insert size.\n" - info: null - default: - - 8000 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "string" - name: "--id" - alternatives: - - "-I" - description: "Include only listed read group or sample name.\n" - info: null - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--read_length" - alternatives: - - "-l" - description: "Include in the statistics only reads with the given read length.\n" - info: null - default: - - -1 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "double" - name: "--most_inserts" - alternatives: - - "-m" - description: "Report only the main part of inserts.\n" - info: null - default: - - 0.99 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "string" - name: "--split_prefix" - alternatives: - - "-P" - description: "Path or string prefix for filepaths output by --split (default is\ - \ input filename).\n" - info: null - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "integer" - name: "--trim_quality" - alternatives: - - "-q" - description: "The BWA trimming parameter.\n" - info: null - default: - - 0 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--ref_seq" - alternatives: - - "-r" - description: "Reference sequence (required for GC-depth and mismatches-per-cycle\ - \ calculation).\n" - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "string" - name: "--split" - alternatives: - - "-S" - description: "Also write statistics to separate files split by tagged field.\n" - info: null - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--target_regions" - alternatives: - - "-t" - description: "Do stats in these regions only. Tab-delimited file chr,from,to,\ - \ 1-based, inclusive.\n" - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "boolean_true" - name: "--sparse" - alternatives: - - "-x" - description: "Suppress outputting IS rows where there are no insertions.\n" - info: null - direction: "input" - - type: "boolean_true" - name: "--remove_overlaps" - alternatives: - - "-p" - description: "Remove overlaps of paired-end reads from coverage and base count\ - \ computations.\n" - info: null - direction: "input" - - type: "integer" - name: "--cov_threshold" - alternatives: - - "-g" - description: "Only bases with coverage above this value will be included in the\ - \ target percentage computation.\n" - info: null - default: - - 0 - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "string" - name: "--input_fmt_option" - description: "Specify a single input file format option in the form of OPTION\ - \ or OPTION=VALUE.\n" - info: null - required: false - direction: "input" - multiple: false - multiple_sep: ";" - - type: "file" - name: "--reference" - description: "Reference sequence FASTA FILE.\n" - info: null - must_exist: true - create_parent: true - required: false - direction: "input" - multiple: false - multiple_sep: ";" -- name: "Outputs" - arguments: - - type: "file" - name: "--output" - alternatives: - - "-o" - description: "Output file.\n" - info: null - default: - - "out.txt" - must_exist: true - create_parent: true - required: true - direction: "output" - multiple: false - multiple_sep: ";" -resources: -- type: "bash_script" - path: "script.sh" - is_executable: true -description: "Reports alignment summary statistics for a BAM file." -test_resources: -- type: "bash_script" - path: "test.sh" - is_executable: true -- type: "file" - path: "test_data" -info: null -status: "enabled" -requirements: - commands: - - "ps" -keywords: -- "statistics" -- "counts" -- "bam" -- "sam" -- "cram" -license: "MIT/Expat" -references: - doi: - - "10.1093/bioinformatics/btp352" - - "10.1093/gigascience/giab008" -links: - repository: "https://github.com/samtools/samtools" - homepage: "https://www.htslib.org/" - documentation: "https://www.htslib.org/doc/samtools-stats.html" -runners: -- type: "executable" - id: "executable" - docker_setup_strategy: "ifneedbepullelsecachedbuild" -- type: "nextflow" - id: "nextflow" - directives: - tag: "$id" - auto: - simplifyInput: true - simplifyOutput: false - transcript: false - publish: false - config: - labels: - mem1gb: "memory = 1000000000.B" - mem2gb: "memory = 2000000000.B" - mem5gb: "memory = 5000000000.B" - mem10gb: "memory = 10000000000.B" - mem20gb: "memory = 20000000000.B" - mem50gb: "memory = 50000000000.B" - mem100gb: "memory = 100000000000.B" - mem200gb: "memory = 200000000000.B" - mem500gb: "memory = 500000000000.B" - mem1tb: "memory = 1000000000000.B" - mem2tb: "memory = 2000000000000.B" - mem5tb: "memory = 5000000000000.B" - mem10tb: "memory = 10000000000000.B" - mem20tb: "memory = 20000000000000.B" - mem50tb: "memory = 50000000000000.B" - mem100tb: "memory = 100000000000000.B" - mem200tb: "memory = 200000000000000.B" - mem500tb: "memory = 500000000000000.B" - mem1gib: "memory = 1073741824.B" - mem2gib: "memory = 2147483648.B" - mem4gib: "memory = 4294967296.B" - mem8gib: "memory = 8589934592.B" - mem16gib: "memory = 17179869184.B" - mem32gib: "memory = 34359738368.B" - mem64gib: "memory = 68719476736.B" - mem128gib: "memory = 137438953472.B" - mem256gib: "memory = 274877906944.B" - mem512gib: "memory = 549755813888.B" - mem1tib: "memory = 1099511627776.B" - mem2tib: "memory = 2199023255552.B" - mem4tib: "memory = 4398046511104.B" - mem8tib: "memory = 8796093022208.B" - mem16tib: "memory = 17592186044416.B" - mem32tib: "memory = 35184372088832.B" - mem64tib: "memory = 70368744177664.B" - mem128tib: "memory = 140737488355328.B" - mem256tib: "memory = 281474976710656.B" - mem512tib: "memory = 562949953421312.B" - cpu1: "cpus = 1" - cpu2: "cpus = 2" - cpu5: "cpus = 5" - cpu10: "cpus = 10" - cpu20: "cpus = 20" - cpu50: "cpus = 50" - cpu100: "cpus = 100" - cpu200: "cpus = 200" - cpu500: "cpus = 500" - cpu1000: "cpus = 1000" - debug: false - container: "docker" -engines: -- type: "docker" - id: "docker" - image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" - target_registry: "images.viash-hub.com" - target_tag: "v0.1.0" - namespace_separator: "/" - setup: - - type: "docker" - run: - - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\nsed 's#Using\ - \ ##;s# \\([0-9\\.]*\\)$#: \\1#' > /var/software_versions.txt\n" - entrypoint: [] - cmd: null -- type: "native" - id: "native" -build_info: - config: "src/samtools/samtools_stats/config.vsh.yaml" - runner: "nextflow" - engine: "docker|native" - output: "target/nextflow/samtools/samtools_stats" - executable: "target/nextflow/samtools/samtools_stats/main.nf" - viash_version: "0.9.0-RC6" - git_commit: "b84b29747d0635f2ac83ea63b496be9a9edb6724" - git_remote: "https://github.com/viash-hub/biobox" -package_config: - name: "biobox" - version: "v0.1.0" - description: "A collection of bioinformatics tools for working with sequence data.\n" - info: null - viash_version: "0.9.0-RC6" - source: "src" - target: "target" - config_mods: - - ".requirements.commands := ['ps']\n" - - ".engines += { type: \"native\" }" - - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - keywords: - - "bioinformatics" - - "modules" - - "sequencing" - license: "MIT" - organization: "vsh" - links: - repository: "https://github.com/viash-hub/biobox" - issue_tracker: "https://github.com/viash-hub/biobox/issues" diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/main.nf b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/main.nf deleted file mode 100644 index 167148f..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/main.nf +++ /dev/null @@ -1,3836 +0,0 @@ -// samtools_stats v0.1.0 -// -// This wrapper script is auto-generated by viash 0.9.0-RC6 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. -// -// The component may contain files which fall under a different license. The -// authors of this component should specify the license in the header of such -// files, or include a separate license file detailing the licenses of all included -// files. - -//////////////////////////// -// VDSL3 helper functions // -//////////////////////////// - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_checkArgumentType.nf' -class UnexpectedArgumentTypeException extends Exception { - String errorIdentifier - String stage - String plainName - String expectedClass - String foundClass - - // ${key ? " in module '$key'" : ""}${id ? " id '$id'" : ""} - UnexpectedArgumentTypeException(String errorIdentifier, String stage, String plainName, String expectedClass, String foundClass) { - super("Error${errorIdentifier ? " $errorIdentifier" : ""}:${stage ? " $stage" : "" } argument '${plainName}' has the wrong type. " + - "Expected type: ${expectedClass}. Found type: ${foundClass}") - this.errorIdentifier = errorIdentifier - this.stage = stage - this.plainName = plainName - this.expectedClass = expectedClass - this.foundClass = foundClass - } -} - -/** - * Checks if the given value is of the expected type. If not, an exception is thrown. - * - * @param stage The stage of the argument (input or output) - * @param par The parameter definition - * @param value The value to check - * @param errorIdentifier The identifier to use in the error message - * @return The value, if it is of the expected type - * @throws UnexpectedArgumentTypeException If the value is not of the expected type -*/ -def _checkArgumentType(String stage, Map par, Object value, String errorIdentifier) { - // expectedClass will only be != null if value is not of the expected type - def expectedClass = null - def foundClass = null - - // todo: split if need be - - if (!par.required && value == null) { - expectedClass = null - } else if (par.multiple) { - if (value !instanceof Collection) { - value = [value] - } - - // split strings - value = value.collectMany{ val -> - if (val instanceof String) { - // collect() to ensure that the result is a List and not simply an array - val.split(par.multiple_sep).collect() - } else { - [val] - } - } - - // process globs - if (par.type == "file" && par.direction == "input") { - value = value.collect{ it instanceof String ? file(it, hidden: true) : it }.flatten() - } - - // check types of elements in list - try { - value = value.collect { listVal -> - _checkArgumentType(stage, par + [multiple: false], listVal, errorIdentifier) - } - } catch (UnexpectedArgumentTypeException e) { - expectedClass = "List[${e.expectedClass}]" - foundClass = "List[${e.foundClass}]" - } - } else if (par.type == "string") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else if (par.type == "integer") { - // cast to integer if need be - if (value instanceof String) { - try { - value = value.toInteger() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigInteger) { - value = value.intValue() - } - expectedClass = value instanceof Integer ? null : "Integer" - } else if (par.type == "long") { - // cast to long if need be - if (value instanceof String) { - try { - value = value.toLong() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof Integer) { - value = value.toLong() - } - expectedClass = value instanceof Long ? null : "Long" - } else if (par.type == "double") { - // cast to double if need be - if (value instanceof String) { - try { - value = value.toDouble() - } catch (NumberFormatException e) { - // do nothing - } - } - if (value instanceof java.math.BigDecimal) { - value = value.doubleValue() - } - if (value instanceof Float) { - value = value.toDouble() - } - expectedClass = value instanceof Double ? null : "Double" - } else if (par.type == "boolean" | par.type == "boolean_true" | par.type == "boolean_false") { - // cast to boolean if need be - if (value instanceof String) { - def valueLower = value.toLowerCase() - if (valueLower == "true") { - value = true - } else if (valueLower == "false") { - value = false - } - } - expectedClass = value instanceof Boolean ? null : "Boolean" - } else if (par.type == "file" && (par.direction == "input" || stage == "output")) { - // cast to path if need be - if (value instanceof String) { - value = file(value, hidden: true) - } - if (value instanceof File) { - value = value.toPath() - } - expectedClass = value instanceof Path ? null : "Path" - } else if (par.type == "file" && stage == "input" && par.direction == "output") { - // cast to string if need be - if (value instanceof GString) { - value = value.toString() - } - expectedClass = value instanceof String ? null : "String" - } else { - // didn't find a match for par.type - expectedClass = par.type - } - - if (expectedClass != null) { - if (foundClass == null) { - foundClass = value.getClass().getName() - } - throw new UnexpectedArgumentTypeException(errorIdentifier, stage, par.plainName, expectedClass, foundClass) - } - - return value -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processInputValues.nf' -Map _processInputValues(Map inputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.required) { - assert inputs.containsKey(arg.plainName) && inputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required input argument '${arg.plainName}' is missing" - } - } - - inputs = inputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid input argument" - - value = _checkArgumentType("input", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return inputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/arguments/_processOutputValues.nf' -Map _processOutputValues(Map outputs, Map config, String id, String key) { - if (!workflow.stubRun) { - config.allArguments.each { arg -> - if (arg.direction == "output" && arg.required) { - assert outputs.containsKey(arg.plainName) && outputs.get(arg.plainName) != null : - "Error in module '${key}' id '${id}': required output argument '${arg.plainName}' is missing" - } - } - - outputs = outputs.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && it.direction == "output" } - assert par != null : "Error in module '${key}' id '${id}': '${name}' is not a valid output argument" - - value = _checkArgumentType("output", par, value, "in module '$key' id '$id'") - - [ name, value ] - } - } - return outputs -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/IDChecker.nf' -class IDChecker { - final def items = [] as Set - - @groovy.transform.WithWriteLock - boolean observe(String item) { - if (items.contains(item)) { - return false - } else { - items << item - return true - } - } - - @groovy.transform.WithReadLock - boolean contains(String item) { - return items.contains(item) - } - - @groovy.transform.WithReadLock - Set getItems() { - return items.clone() - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_checkUniqueIds.nf' - -/** - * Check if the ids are unique across parameter sets - * - * @param parameterSets a list of parameter sets. - */ -private void _checkUniqueIds(List>> parameterSets) { - def ppIds = parameterSets.collect{it[0]} - assert ppIds.size() == ppIds.unique().size() : "All argument sets should have unique ids. Detected ids: $ppIds" -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_getChild.nf' - -// helper functions for reading params from file // -def _getChild(parent, child) { - if (child.contains("://") || java.nio.file.Paths.get(child).isAbsolute()) { - child - } else { - def parentAbsolute = java.nio.file.Paths.get(parent).toAbsolutePath().toString() - parentAbsolute.replaceAll('/[^/]*$', "/") + child - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_parseParamList.nf' -/** - * Figure out the param list format based on the file extension - * - * @param param_list A String containing the path to the parameter list file. - * - * @return A String containing the format of the parameter list file. - */ -def _paramListGuessFormat(param_list) { - if (param_list !instanceof String) { - "asis" - } else if (param_list.endsWith(".csv")) { - "csv" - } else if (param_list.endsWith(".json") || param_list.endsWith(".jsn")) { - "json" - } else if (param_list.endsWith(".yaml") || param_list.endsWith(".yml")) { - "yaml" - } else { - "yaml_blob" - } -} - - -/** - * Read the param list - * - * @param param_list One of the following: - * - A String containing the path to the parameter list file (csv, json or yaml), - * - A yaml blob of a list of maps (yaml_blob), - * - Or a groovy list of maps (asis). - * @param config A Map of the Viash configuration. - * - * @return A List of Maps containing the parameters. - */ -def _parseParamList(param_list, Map config) { - // first determine format by extension - def paramListFormat = _paramListGuessFormat(param_list) - - def paramListPath = (paramListFormat != "asis" && paramListFormat != "yaml_blob") ? - file(param_list, hidden: true) : - null - - // get the correct parser function for the detected params_list format - def paramSets = [] - if (paramListFormat == "asis") { - paramSets = param_list - } else if (paramListFormat == "yaml_blob") { - paramSets = readYamlBlob(param_list) - } else if (paramListFormat == "yaml") { - paramSets = readYaml(paramListPath) - } else if (paramListFormat == "json") { - paramSets = readJson(paramListPath) - } else if (paramListFormat == "csv") { - paramSets = readCsv(paramListPath) - } else { - error "Format of provided --param_list not recognised.\n" + - "Found: '$paramListFormat'.\n" + - "Expected: a csv file, a json file, a yaml file,\n" + - "a yaml blob or a groovy list of maps." - } - - // data checks - assert paramSets instanceof List: "--param_list should contain a list of maps" - for (value in paramSets) { - assert value instanceof Map: "--param_list should contain a list of maps" - } - - // id is argument - def idIsArgument = config.allArguments.any{it.plainName == "id"} - - // Reformat from List to List> by adding the ID as first element of a Tuple2 - paramSets = paramSets.collect({ data -> - def id = data.id - if (!idIsArgument) { - data = data.findAll{k, v -> k != "id"} - } - [id, data] - }) - - // Split parameters with 'multiple: true' - paramSets = paramSets.collect({ id, data -> - data = _splitParams(data, config) - [id, data] - }) - - // The paths of input files inside a param_list file may have been specified relatively to the - // location of the param_list file. These paths must be made absolute. - if (paramListPath) { - paramSets = paramSets.collect({ id, data -> - def new_data = data.collectEntries{ parName, parValue -> - def par = config.allArguments.find{it.plainName == parName} - if (par && par.type == "file" && par.direction == "input") { - if (parValue instanceof Collection) { - parValue = parValue.collectMany{path -> - def x = _resolveSiblingIfNotAbsolute(path, paramListPath) - x instanceof Collection ? x : [x] - } - } else { - parValue = _resolveSiblingIfNotAbsolute(parValue, paramListPath) - } - } - [parName, parValue] - } - [id, new_data] - }) - } - - return paramSets -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/_splitParams.nf' -/** - * Split parameters for arguments that accept multiple values using their separator - * - * @param paramList A Map containing parameters to split. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A Map of parameters where the parameter values have been split into a list using - * their seperator. - */ -Map _splitParams(Map parValues, Map config){ - def parsedParamValues = parValues.collectEntries { parName, parValue -> - def parameterSettings = config.allArguments.find({it.plainName == parName}) - - if (!parameterSettings) { - // if argument is not found, do not alter - return [parName, parValue] - } - if (parameterSettings.multiple) { // Check if parameter can accept multiple values - if (parValue instanceof Collection) { - parValue = parValue.collect{it instanceof String ? it.split(parameterSettings.multiple_sep) : it } - } else if (parValue instanceof String) { - parValue = parValue.split(parameterSettings.multiple_sep) - } else if (parValue == null) { - parValue = [] - } else { - parValue = [ parValue ] - } - parValue = parValue.flatten() - } - // For all parameters check if multiple values are only passed for - // arguments that allow it. Quietly simplify lists of length 1. - if (!parameterSettings.multiple && parValue instanceof Collection) { - assert parValue.size() == 1 : - "Error: argument ${parName} has too many values.\n" + - " Expected amount: 1. Found: ${parValue.size()}" - parValue = parValue[0] - } - [parName, parValue] - } - return parsedParamValues -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/channelFromParams.nf' -/** - * Parse nextflow parameters based on settings defined in a viash config. - * Return a list of parameter sets, each parameter set corresponding to - * an event in a nextflow channel. The output from this function can be used - * with Channel.fromList to create a nextflow channel with Vdsl3 formatted - * events. - * - * This function performs: - * - A filtering of the params which can be found in the config file. - * - Process the params_list argument which allows a user to to initialise - * a Vsdl3 channel with multiple parameter sets. Possible formats are - * csv, json, yaml, or simply a yaml_blob. A csv should have column names - * which correspond to the different arguments of this pipeline. A json or a yaml - * file should be a list of maps, each of which has keys corresponding to the - * arguments of the pipeline. A yaml blob can also be passed directly as a parameter. - * When passing a csv, json or yaml, relative path names are relativized to the - * location of the parameter file. - * - Combine the parameter sets into a vdsl3 Channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A list of parameters with the first element of the event being - * the event ID and the second element containing a map of the parsed parameters. - */ - -private List>> _paramsToParamSets(Map params, Map config){ - // todo: fetch key from run args - def key_ = config.name - - /* parse regular parameters (not in param_list) */ - /*************************************************/ - def globalParams = config.allArguments - .findAll { params.containsKey(it.plainName) } - .collectEntries { [ it.plainName, params[it.plainName] ] } - def globalID = params.get("id", null) - - /* process params_list arguments */ - /*********************************/ - def paramList = params.containsKey("param_list") && params.param_list != null ? - params.param_list : [] - // if (paramList instanceof String) { - // paramList = [paramList] - // } - // def paramSets = paramList.collectMany{ _parseParamList(it, config) } - // TODO: be able to process param_list when it is a list of strings - def paramSets = _parseParamList(paramList, config) - if (paramSets.isEmpty()) { - paramSets = [[null, [:]]] - } - - /* combine arguments into channel */ - /**********************************/ - def processedParams = paramSets.indexed().collect{ index, tup -> - // Process ID - def id = tup[0] ?: globalID - - if (workflow.stubRun && !id) { - // if stub run, explicitly add an id if missing - id = "stub${index}" - } - assert id != null: "Each parameter set should have at least an 'id'" - - // Process params - def parValues = globalParams + tup[1] - // // Remove parameters which are null, if the default is also null - // parValues = parValues.collectEntries{paramName, paramValue -> - // parameterSettings = config.functionality.allArguments.find({it.plainName == paramName}) - // if ( paramValue != null || parameterSettings.get("default", null) != null ) { - // [paramName, paramValue] - // } - // } - parValues = parValues.collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - assert par != null : "Error in module '${key_}' id '${id}': '${name}' is not a valid input argument" - - if (par == null) { - return [:] - } - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - - [ name, value ] - } - - [id, parValues] - } - - // Check if ids (first element of each list) is unique - _checkUniqueIds(processedParams) - return processedParams -} - -/** - * Parse nextflow parameters based on settings defined in a viash config - * and return a nextflow channel. - * - * @param params Input parameters. Can optionaly contain a 'param_list' key that - * provides a list of arguments that can be split up into multiple events - * in the output channel possible formats of param_lists are: a csv file, - * json file, a yaml file or a yaml blob. Each parameters set (event) must - * have a unique ID. - * @param config A Map of the Viash configuration. This Map can be generated from the config file - * using the readConfig() function. - * - * @return A nextflow Channel with events. Events are formatted as a tuple that contains - * first contains the ID of the event and as second element holds a parameter map. - * - * - */ -def channelFromParams(Map params, Map config) { - def processedParams = _paramsToParamSets(params, config) - return Channel.fromList(processedParams) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/checkUniqueIds.nf' -def checkUniqueIds(Map args) { - def stopOnError = args.stopOnError == null ? args.stopOnError : true - - def idChecker = new IDChecker() - - return filter { tup -> - if (!idChecker.observe(tup[0])) { - if (stopOnError) { - error "Duplicate id: ${tup[0]}" - } else { - log.warn "Duplicate id: ${tup[0]}, removing duplicate entry" - return false - } - } - return true - } -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/preprocessInputs.nf' -// This helper file will be deprecated soon -preprocessInputsDeprecationWarningPrinted = false - -def preprocessInputsDeprecationWarning() { - if (!preprocessInputsDeprecationWarningPrinted) { - preprocessInputsDeprecationWarningPrinted = true - System.err.println("Warning: preprocessInputs() is deprecated and will be removed in Viash 0.9.0.") - } -} - -/** - * Generate a nextflow Workflow that allows processing a channel of - * Vdsl3 formatted events and apply a Viash config to them: - * - Gather default parameters from the Viash config and make - * sure that they are correctly formatted (see applyConfig method). - * - Format the input parameters (also using the applyConfig method). - * - Apply the default parameter to the input parameters. - * - Do some assertions: - * ~ Check if the event IDs in the channel are unique. - * - * The events in the channel are formatted as tuples, with the - * first element of the tuples being a unique id of the parameter set, - * and the second element containg the the parameters themselves. - * Optional extra elements of the tuples will be passed to the output as is. - * - * @param args A map that must contain a 'config' key that points - * to a parsed config (see readConfig()). Optionally, a - * 'key' key can be provided which can be used to create a unique - * name for the workflow process. - * - * @return A workflow that allows processing a channel of Vdsl3 formatted events - * and apply a Viash config to them. - */ -def preprocessInputs(Map args) { - preprocessInputsDeprecationWarning() - - def config = args.config - assert config instanceof Map : - "Error in preprocessInputs: config must be a map. " + - "Expected class: Map. Found: config.getClass() is ${config.getClass()}" - def key_ = args.key ?: config.name - - // Get different parameter types (used throughout this function) - def defaultArgs = config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - map { tup -> - def id = tup[0] - def data = tup[1] - def passthrough = tup.drop(2) - - def new_data = (defaultArgs + data).collectEntries { name, value -> - def par = config.allArguments.find { it.plainName == name && (it.direction == "input" || it.type == "file") } - - if (par != null) { - value = _checkArgumentType("input", par, value, "in module '$key_' id '$id'") - } - - [ name, value ] - } - - [ id, new_data ] + passthrough - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runComponents.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component config. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component config. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component config. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component config. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runComponents(Map args) { - log.warn("runComponents is deprecated, use runEach instead") - assert args.components: "runComponents should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runComponents" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runComponentsWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def comp_config = comp_.config - - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_config) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - // def new_id = id_(tup[0], tup[1], comp_config) - def new_id = tup[0] - if (id_ instanceof String) { - new_id = id_ - } else if (id_ instanceof Closure) { - new_id = id_(new_id, tup[1], comp_config) - } - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_config) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_config) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runComponentsWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/runEach.nf' -/** - * Run a list of components on a stream of data. - * - * @param components: list of Viash VDSL3 modules to run - * @param fromState: a closure, a map or a list of keys to extract from the input data. - * If a closure, it will be called with the id, the data and the component itself. - * @param toState: a closure, a map or a list of keys to extract from the output data - * If a closure, it will be called with the id, the output data, the old state and the component itself. - * @param filter: filter function to apply to the input. - * It will be called with the id, the data and the component itself. - * @param id: id to use for the output data - * If a closure, it will be called with the id, the data and the component itself. - * @param auto: auto options to pass to the components - * - * @return: a workflow that runs the components - **/ -def runEach(Map args) { - assert args.components: "runEach should be passed a list of components to run" - - def components_ = args.components - if (components_ !instanceof List) { - components_ = [ components_ ] - } - assert components_.size() > 0: "pass at least one component to runEach" - - def fromState_ = args.fromState - def toState_ = args.toState - def filter_ = args.filter - def id_ = args.id - - workflow runEachWf { - take: input_ch - main: - - // generate one channel per method - out_chs = components_.collect{ comp_ -> - def filter_ch = filter_ - ? input_ch | filter{tup -> - filter_(tup[0], tup[1], comp_) - } - : input_ch - def id_ch = id_ - ? filter_ch | map{tup -> - def new_id = id_ - if (new_id instanceof Closure) { - new_id = new_id(tup[0], tup[1], comp_) - } - assert new_id instanceof String : "Error in runEach: id should be a String or a Closure that returns a String. Expected: id instanceof String. Found: ${new_id.getClass()}" - [new_id] + tup.drop(1) - } - : filter_ch - def data_ch = id_ch | map{tup -> - def new_data = tup[1] - if (fromState_ instanceof Map) { - new_data = fromState_.collectEntries{ key0, key1 -> - [key0, new_data[key1]] - } - } else if (fromState_ instanceof List) { - new_data = fromState_.collectEntries{ key -> - [key, new_data[key]] - } - } else if (fromState_ instanceof Closure) { - new_data = fromState_(tup[0], new_data, comp_) - } - tup.take(1) + [new_data] + tup.drop(1) - } - def out_ch = data_ch - | comp_.run( - auto: (args.auto ?: [:]) + [simplifyInput: false, simplifyOutput: false] - ) - def post_ch = toState_ - ? out_ch | map{tup -> - def output = tup[1] - def old_state = tup[2] - def new_state = null - if (toState_ instanceof Map) { - new_state = old_state + toState_.collectEntries{ key0, key1 -> - [key0, output[key1]] - } - } else if (toState_ instanceof List) { - new_state = old_state + toState_.collectEntries{ key -> - [key, output[key]] - } - } else if (toState_ instanceof Closure) { - new_state = toState_(tup[0], output, old_state, comp_) - } - [tup[0], new_state] + tup.drop(3) - } - : out_ch - - post_ch - } - - // mix all results - output_ch = - (out_chs.size == 1) - ? out_chs[0] - : out_chs[0].mix(*out_chs.drop(1)) - - emit: output_ch - } - - return runEachWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/channel/safeJoin.nf' -/** - * Join sourceChannel to targetChannel - * - * This function joins the sourceChannel to the targetChannel. - * However, each id in the targetChannel must be present in the - * sourceChannel. If _meta.join_id exists in the targetChannel, that is - * used as an id instead. If the id doesn't match any id in the sourceChannel, - * an error is thrown. - */ - -def safeJoin(targetChannel, sourceChannel, key) { - def sourceIDs = new IDChecker() - - def sourceCheck = sourceChannel - | map { tup -> - sourceIDs.observe(tup[0]) - tup - } - def targetCheck = targetChannel - | map { tup -> - def id = tup[0] - - if (!sourceIDs.contains(id)) { - error ( - "Error in module '${key}' when merging output with original state.\n" + - " Reason: output with id '${id}' could not be joined with source channel.\n" + - " If the IDs in the output channel differ from the input channel,\n" + - " please set `tup[1]._meta.join_id to the original ID.\n" + - " Original IDs in input channel: ['${sourceIDs.getItems().join("', '")}'].\n" + - " Unexpected ID in the output channel: '${id}'.\n" + - " Example input event: [\"id\", [input: file(...)]],\n" + - " Example output event: [\"newid\", [output: file(...), _meta: [join_id: \"id\"]]]" - ) - } - // TODO: add link to our documentation on how to fix this - - tup - } - - sourceCheck.cross(targetChannel) - | map{ left, right -> - right + left.drop(1) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/_processArgument.nf' -def _processArgument(arg) { - arg.multiple = arg.multiple != null ? arg.multiple : false - arg.required = arg.required != null ? arg.required : false - arg.direction = arg.direction != null ? arg.direction : "input" - arg.multiple_sep = arg.multiple_sep != null ? arg.multiple_sep : ";" - arg.plainName = arg.name.replaceAll("^-*", "") - - if (arg.type == "file") { - arg.must_exist = arg.must_exist != null ? arg.must_exist : true - arg.create_parent = arg.create_parent != null ? arg.create_parent : true - } - - // add default values to output files which haven't already got a default - if (arg.type == "file" && arg.direction == "output" && arg.default == null) { - def mult = arg.multiple ? "_*" : "" - def extSearch = "" - if (arg.default != null) { - extSearch = arg.default - } else if (arg.example != null) { - extSearch = arg.example - } - if (extSearch instanceof List) { - extSearch = extSearch[0] - } - def extSearchResult = extSearch.find("\\.[^\\.]+\$") - def ext = extSearchResult != null ? extSearchResult : "" - arg.default = "\$id.\$key.${arg.plainName}${mult}${ext}" - if (arg.multiple) { - arg.default = [arg.default] - } - } - - if (!arg.multiple) { - if (arg.default != null && arg.default instanceof List) { - arg.default = arg.default[0] - } - if (arg.example != null && arg.example instanceof List) { - arg.example = arg.example[0] - } - } - - if (arg.type == "boolean_true") { - arg.default = false - } - if (arg.type == "boolean_false") { - arg.default = true - } - - arg -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/addGlobalParams.nf' -def addGlobalArguments(config) { - def localConfig = [ - "argument_groups": [ - [ - "name": "Nextflow input-output arguments", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "arguments" : [ - [ - 'name': '--publish_dir', - 'required': true, - 'type': 'string', - 'description': 'Path to an output directory.', - 'example': 'output/', - 'multiple': false - ], - [ - 'name': '--param_list', - 'required': false, - 'type': 'string', - 'description': '''Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob. - | - |* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ ['id': 'foo', 'input': 'foo.txt'], ['id': 'bar', 'input': 'bar.txt'] ]`. - |* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`. - |* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]`. - |* A yaml blob can also be passed directly as a string. Example: `--param_list "[ {'id': 'foo', 'input': 'foo.txt'}, {'id': 'bar', 'input': 'bar.txt'} ]"`. - | - |When passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.'''.stripMargin(), - 'example': 'my_params.yaml', - 'multiple': false, - 'hidden': true - ] - // TODO: allow multiple: true in param_list? - // TODO: allow to specify a --param_list_regex to filter the param_list? - // TODO: allow to specify a --param_list_from_state to remap entries in the param_list? - ] - ] - ] - ] - - return processConfig(_mergeMap(config, localConfig)) -} - -def _mergeMap(Map lhs, Map rhs) { - return rhs.inject(lhs.clone()) { map, entry -> - if (map[entry.key] instanceof Map && entry.value instanceof Map) { - map[entry.key] = _mergeMap(map[entry.key], entry.value) - } else if (map[entry.key] instanceof Collection && entry.value instanceof Collection) { - map[entry.key] += entry.value - } else { - map[entry.key] = entry.value - } - return map - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/generateHelp.nf' -def _generateArgumentHelp(param) { - // alternatives are not supported - // def names = param.alternatives ::: List(param.name) - - def unnamedProps = [ - ["required parameter", param.required], - ["multiple values allowed", param.multiple], - ["output", param.direction.toLowerCase() == "output"], - ["file must exist", param.type == "file" && param.must_exist] - ].findAll{it[1]}.collect{it[0]} - - def dflt = null - if (param.default != null) { - if (param.default instanceof List) { - dflt = param.default.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - dflt = param.default.toString() - } - } - def example = null - if (param.example != null) { - if (param.example instanceof List) { - example = param.example.join(param.multiple_sep != null ? param.multiple_sep : ", ") - } else { - example = param.example.toString() - } - } - def min = param.min?.toString() - def max = param.max?.toString() - - def escapeChoice = { choice -> - def s1 = choice.replaceAll("\\n", "\\\\n") - def s2 = s1.replaceAll("\"", """\\\"""") - s2.contains(",") || s2 != choice ? "\"" + s2 + "\"" : s2 - } - def choices = param.choices == null ? - null : - "[ " + param.choices.collect{escapeChoice(it.toString())}.join(", ") + " ]" - - def namedPropsStr = [ - ["type", ([param.type] + unnamedProps).join(", ")], - ["default", dflt], - ["example", example], - ["choices", choices], - ["min", min], - ["max", max] - ] - .findAll{it[1]} - .collect{"\n " + it[0] + ": " + it[1].replaceAll("\n", "\\n")} - .join("") - - def descStr = param.description == null ? - "" : - _paragraphWrap("\n" + param.description.trim(), 80 - 8).join("\n ") - - "\n --" + param.plainName + - namedPropsStr + - descStr -} - -// Based on Helper.generateHelp() in Helper.scala -def _generateHelp(config) { - def fun = config - - // PART 1: NAME AND VERSION - def nameStr = fun.name + - (fun.version == null ? "" : " " + fun.version) - - // PART 2: DESCRIPTION - def descrStr = fun.description == null ? - "" : - "\n\n" + _paragraphWrap(fun.description.trim(), 80).join("\n") - - // PART 3: Usage - def usageStr = fun.usage == null ? - "" : - "\n\nUsage:\n" + fun.usage.trim() - - // PART 4: Options - def argGroupStrs = fun.allArgumentGroups.collect{argGroup -> - def name = argGroup.name - def descriptionStr = argGroup.description == null ? - "" : - "\n " + _paragraphWrap(argGroup.description.trim(), 80-4).join("\n ") + "\n" - def arguments = argGroup.arguments.collect{arg -> - arg instanceof String ? fun.allArguments.find{it.plainName == arg} : arg - }.findAll{it != null} - def argumentStrs = arguments.collect{param -> _generateArgumentHelp(param)} - - "\n\n$name:" + - descriptionStr + - argumentStrs.join("\n") - } - - // FINAL: combine - def out = nameStr + - descrStr + - usageStr + - argGroupStrs.join("") - - return out -} - -// based on Format._paragraphWrap -def _paragraphWrap(str, maxLength) { - def outLines = [] - str.split("\n").each{par -> - def words = par.split("\\s").toList() - - def word = null - def line = words.pop() - while(!words.isEmpty()) { - word = words.pop() - if (line.length() + word.length() + 1 <= maxLength) { - line = line + " " + word - } else { - outLines.add(line) - line = word - } - } - if (words.isEmpty()) { - outLines.add(line) - } - } - return outLines -} - -def helpMessage(config) { - if (params.containsKey("help") && params.help) { - def mergedConfig = addGlobalArguments(config) - def helpStr = _generateHelp(mergedConfig) - println(helpStr) - exit 0 - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/processConfig.nf' -def processConfig(config) { - // set defaults for arguments - config.arguments = - (config.arguments ?: []).collect{_processArgument(it)} - - // set defaults for argument_group arguments - config.argument_groups = - (config.argument_groups ?: []).collect{grp -> - grp.arguments = (grp.arguments ?: []).collect{_processArgument(it)} - grp - } - - // create combined arguments list - config.allArguments = - config.arguments + - config.argument_groups.collectMany{it.arguments} - - // add missing argument groups (based on Functionality::allArgumentGroups()) - def argGroups = config.argument_groups - if (argGroups.any{it.name.toLowerCase() == "arguments"}) { - argGroups = argGroups.collect{ grp -> - if (grp.name.toLowerCase() == "arguments") { - grp = grp + [ - arguments: grp.arguments + config.arguments - ] - } - grp - } - } else { - argGroups = argGroups + [ - name: "Arguments", - arguments: config.arguments - ] - } - config.allArgumentGroups = argGroups - - config -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/config/readConfig.nf' - -def readConfig(file) { - def config = readYaml(file ?: moduleDir.resolve("config.vsh.yaml")) - processConfig(config) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_resolveSiblingIfNotAbsolute.nf' -/** - * Resolve a path relative to the current file. - * - * @param str The path to resolve, as a String. - * @param parentPath The path to resolve relative to, as a Path. - * - * @return The path that may have been resovled, as a Path. - */ -def _resolveSiblingIfNotAbsolute(str, parentPath) { - if (str !instanceof String) { - return str - } - if (!_stringIsAbsolutePath(str)) { - return parentPath.resolveSibling(str) - } else { - return file(str, hidden: true) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/_stringIsAbsolutePath.nf' -/** - * Check whether a path as a string is absolute. - * - * In the past, we tried using `file(., relative: true).isAbsolute()`, - * but the 'relative' option was added in 22.10.0. - * - * @param path The path to check, as a String. - * - * @return Whether the path is absolute, as a boolean. - */ -def _stringIsAbsolutePath(path) { - def _resolve_URL_PROTOCOL = ~/^([a-zA-Z][a-zA-Z0-9]*:)?\\/.+/ - - assert path instanceof String - return _resolve_URL_PROTOCOL.matcher(path).matches() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/collectTraces.nf' -class CustomTraceObserver implements nextflow.trace.TraceObserver { - List traces - - CustomTraceObserver(List traces) { - this.traces = traces - } - - @Override - void onProcessComplete(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } - - @Override - void onProcessCached(nextflow.processor.TaskHandler handler, nextflow.trace.TraceRecord trace) { - def trace2 = trace.store.clone() - trace2.script = null - traces.add(trace2) - } -} - -def collectTraces() { - def traces = Collections.synchronizedList([]) - - // add custom trace observer which stores traces in the traces object - session.observers.add(new CustomTraceObserver(traces)) - - traces -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/deepClone.nf' -/** - * Performs a deep clone of the given object. - * @param x an object - */ -def deepClone(x) { - iterateMap(x, {it instanceof Cloneable ? it.clone() : it}) -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getPublishDir.nf' -def getPublishDir() { - return params.containsKey("publish_dir") ? params.publish_dir : - params.containsKey("publishDir") ? params.publishDir : - null -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/getRootDir.nf' - -// Recurse upwards until we find a '.build.yaml' file -def _findBuildYamlFile(pathPossiblySymlink) { - def path = pathPossiblySymlink.toRealPath() - def child = path.resolve(".build.yaml") - if (java.nio.file.Files.isDirectory(path) && java.nio.file.Files.exists(child)) { - return child - } else { - def parent = path.getParent() - if (parent == null) { - return null - } else { - return _findBuildYamlFile(parent) - } - } -} - -// get the root of the target folder -def getRootDir() { - def dir = _findBuildYamlFile(meta.resources_dir) - assert dir != null: "Could not find .build.yaml in the folder structure" - dir.getParent() -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/iterateMap.nf' -/** - * Recursively apply a function over the leaves of an object. - * @param obj The object to iterate over. - * @param fun The function to apply to each value. - * @return The object with the function applied to each value. - */ -def iterateMap(obj, fun) { - if (obj instanceof List && obj !instanceof String) { - return obj.collect{item -> - iterateMap(item, fun) - } - } else if (obj instanceof Map) { - return obj.collectEntries{key, item -> - [key.toString(), iterateMap(item, fun)] - } - } else { - return fun(obj) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/functions/niceView.nf' -/** - * A view for printing the event of each channel as a YAML blob. - * This is useful for debugging. - */ -def niceView() { - workflow niceViewWf { - take: input - main: - output = input - | view{toYamlBlob(it)} - emit: output - } - return niceViewWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readCsv.nf' - -def readCsv(file_path) { - def output = [] - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - - // todo: allow escaped quotes in string - // todo: allow single quotes? - def splitRegex = java.util.regex.Pattern.compile(''',(?=(?:[^"]*"[^"]*")*[^"]*$)''') - def removeQuote = java.util.regex.Pattern.compile('''"(.*)"''') - - def br = java.nio.file.Files.newBufferedReader(inputFile) - - def row = -1 - def header = null - while (br.ready() && header == null) { - def line = br.readLine() - row++ - if (!line.startsWith("#")) { - header = splitRegex.split(line, -1).collect{field -> - m = removeQuote.matcher(field) - m.find() ? m.replaceFirst('$1') : field - } - } - } - assert header != null: "CSV file should contain a header" - - while (br.ready()) { - def line = br.readLine() - row++ - if (line == null) { - br.close() - break - } - - if (!line.startsWith("#")) { - def predata = splitRegex.split(line, -1) - def data = predata.collect{field -> - if (field == "") { - return null - } - def m = removeQuote.matcher(field) - if (m.find()) { - return m.replaceFirst('$1') - } else { - return field - } - } - assert header.size() == data.size(): "Row $row should contain the same number as fields as the header" - - def dataMap = [header, data].transpose().collectEntries().findAll{it.value != null} - output.add(dataMap) - } - } - - output -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJson.nf' -def readJson(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parse(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readJsonBlob.nf' -def readJsonBlob(str) { - def jsonSlurper = new groovy.json.JsonSlurper() - jsonSlurper.parseText(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readTaggedYaml.nf' -// Custom constructor to modify how certain objects are parsed from YAML -class CustomConstructor extends org.yaml.snakeyaml.constructor.Constructor { - Path root - - class ConstructPath extends org.yaml.snakeyaml.constructor.AbstractConstruct { - public Object construct(org.yaml.snakeyaml.nodes.Node node) { - String filename = (String) constructScalar(node); - if (root != null) { - return root.resolve(filename); - } - return java.nio.file.Paths.get(filename); - } - } - - CustomConstructor(org.yaml.snakeyaml.LoaderOptions options, Path root) { - super(options) - this.root = root - // Handling !file tag and parse it back to a File type - this.yamlConstructors.put(new org.yaml.snakeyaml.nodes.Tag("!file"), new ConstructPath()) - } -} - -def readTaggedYaml(Path path) { - def options = new org.yaml.snakeyaml.LoaderOptions() - def constructor = new CustomConstructor(options, path.getParent()) - def yaml = new org.yaml.snakeyaml.Yaml(constructor) - return yaml.load(path.text) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYaml.nf' -def readYaml(file_path) { - def inputFile = file_path !instanceof Path ? file(file_path, hidden: true) : file_path - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(inputFile) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/readYamlBlob.nf' -def readYamlBlob(str) { - def yamlSlurper = new org.yaml.snakeyaml.Yaml() - yamlSlurper.load(str) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toJsonBlob.nf' -String toJsonBlob(data) { - return groovy.json.JsonOutput.toJson(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toTaggedYamlBlob.nf' -// Custom representer to modify how certain objects are represented in YAML -class CustomRepresenter extends org.yaml.snakeyaml.representer.Representer { - Path relativizer - - class RepresentPath implements org.yaml.snakeyaml.representer.Represent { - public String getFileName(Object obj) { - if (obj instanceof File) { - obj = ((File) obj).toPath(); - } - if (obj !instanceof Path) { - throw new IllegalArgumentException("Object: " + obj + " is not a Path or File"); - } - def path = (Path) obj; - - if (relativizer != null) { - return relativizer.relativize(path).toString() - } else { - return path.toString() - } - } - - public org.yaml.snakeyaml.nodes.Node representData(Object data) { - String filename = getFileName(data); - def tag = new org.yaml.snakeyaml.nodes.Tag("!file"); - return representScalar(tag, filename); - } - } - CustomRepresenter(org.yaml.snakeyaml.DumperOptions options, Path relativizer) { - super(options) - this.relativizer = relativizer - this.representers.put(sun.nio.fs.UnixPath, new RepresentPath()) - this.representers.put(Path, new RepresentPath()) - this.representers.put(File, new RepresentPath()) - } -} - -String toTaggedYamlBlob(data) { - return toRelativeTaggedYamlBlob(data, null) -} -String toRelativeTaggedYamlBlob(data, Path relativizer) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - def representer = new CustomRepresenter(options, relativizer) - def yaml = new org.yaml.snakeyaml.Yaml(representer, options) - return yaml.dump(data) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/toYamlBlob.nf' -String toYamlBlob(data) { - def options = new org.yaml.snakeyaml.DumperOptions() - options.setDefaultFlowStyle(org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK) - options.setPrettyFlow(true) - def yaml = new org.yaml.snakeyaml.Yaml(options) - def cleanData = iterateMap(data, { it instanceof Path ? it.toString() : it }) - return yaml.dump(cleanData) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeJson.nf' -void writeJson(data, file) { - assert data: "writeJson: data should not be null" - assert file: "writeJson: file should not be null" - file.write(toJsonBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/readwrite/writeYaml.nf' -void writeYaml(data, file) { - assert data: "writeYaml: data should not be null" - assert file: "writeYaml: file should not be null" - file.write(toYamlBlob(data)) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/findStates.nf' -def findStates(Map params, Map config) { - def auto_config = deepClone(config) - def auto_params = deepClone(params) - - auto_config = auto_config.clone() - // override arguments - auto_config.argument_groups = [] - auto_config.arguments = [ - [ - type: "string", - name: "--id", - description: "A dummy identifier", - required: false - ], - [ - type: "file", - name: "--input_states", - example: "/path/to/input/directory/**/state.yaml", - description: "Path to input directory containing the datasets to be integrated.", - required: true, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--filter", - example: "foo/.*/state.yaml", - description: "Regex to filter state files by path.", - required: false - ], - // to do: make this a yaml blob? - [ - type: "string", - name: "--rename_keys", - example: ["newKey1:oldKey1", "newKey2:oldKey2"], - description: "Rename keys in the detected input files. This is useful if the input files do not match the set of input arguments of the workflow.", - required: false, - multiple: true, - multiple_sep: ";" - ], - [ - type: "string", - name: "--settings", - example: '{"output_dataset": "dataset.h5ad", "k": 10}', - description: "Global arguments as a JSON glob to be passed to all components.", - required: false - ] - ] - if (!(auto_params.containsKey("id"))) { - auto_params["id"] = "auto" - } - - // run auto config through processConfig once more - auto_config = processConfig(auto_config) - - workflow findStatesWf { - helpMessage(auto_config) - - output_ch = - channelFromParams(auto_params, auto_config) - | flatMap { autoId, args -> - - def globalSettings = args.settings ? readYamlBlob(args.settings) : [:] - - // look for state files in input dir - def stateFiles = args.input_states - - // filter state files by regex - if (args.filter) { - stateFiles = stateFiles.findAll{ stateFile -> - def stateFileStr = stateFile.toString() - def matcher = stateFileStr =~ args.filter - matcher.matches()} - } - - // read in states - def states = stateFiles.collect { stateFile -> - def state_ = readTaggedYaml(stateFile) - [state_.id, state_] - } - - // construct renameMap - if (args.rename_keys) { - def renameMap = args.rename_keys.collectEntries{renameString -> - def split = renameString.split(";") - assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey,newKey:oldKey'" - split - } - - // rename keys in state, only let states through which have all keys - // also add global settings - states = states.collectMany{id, state -> - def newState = [:] - - for (key in renameMap.keySet()) { - def origKey = renameMap[key] - if (!(state.containsKey(origKey))) { - return [] - } - newState[key] = state[origKey] - } - - [[id, globalSettings + newState]] - } - } - - states - } - emit: - output_ch - } - - return findStatesWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/joinStates.nf' -def joinStates(Closure apply_) { - workflow joinStatesWf { - take: input_ch - main: - output_ch = input_ch - | toSortedList - | filter{ it.size() > 0 } - | map{ tups -> - def ids = tups.collect{it[0]} - def states = tups.collect{it[1]} - apply_(ids, states) - } - - emit: output_ch - } - return joinStatesWf -} -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/publishStates.nf' -def collectFiles(obj) { - if (obj instanceof java.io.File || obj instanceof Path) { - return [obj] - } else if (obj instanceof List && obj !instanceof String) { - return obj.collectMany{item -> - collectFiles(item) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectFiles(item) - } - } else { - return [] - } -} - -/** - * Recurse through a state and collect all input files and their target output filenames. - * @param obj The state to recurse through. - * @param prefix The prefix to prepend to the output filenames. - */ -def collectInputOutputPaths(obj, prefix) { - if (obj instanceof File || obj instanceof Path) { - def path = obj instanceof Path ? obj : obj.toPath() - def ext = path.getFileName().toString().find("\\.[^\\.]+\$") ?: "" - def newFilename = prefix + ext - return [[obj, newFilename]] - } else if (obj instanceof List && obj !instanceof String) { - return obj.withIndex().collectMany{item, ix -> - collectInputOutputPaths(item, prefix + "_" + ix) - } - } else if (obj instanceof Map) { - return obj.collectMany{key, item -> - collectInputOutputPaths(item, prefix + "." + key) - } - } else { - return [] - } -} - -def publishStates(Map args) { - def key_ = args.get("key") - def yamlTemplate_ = args.get("output_state", args.get("outputState", '$id.$key.state.yaml')) - - assert key_ != null : "publishStates: key must be specified" - - workflow publishStatesWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] - - // the input files and the target output filenames - def inputoutputFilenames_ = collectInputOutputPaths(state_, id_ + "." + key_).transpose() - def inputFiles_ = inputoutputFilenames_[0] - def outputFilenames_ = inputoutputFilenames_[1] - - def yamlFilename = yamlTemplate_ - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - - // TODO: do the pathnames in state_ match up with the outputFilenames_? - - // convert state to yaml blob - def yamlBlob_ = toRelativeTaggedYamlBlob([id: id_] + state_, java.nio.file.Paths.get(yamlFilename)) - - [id_, yamlBlob_, yamlFilename, inputFiles_, outputFilenames_] - } - | publishStatesProc - emit: input_ch - } - return publishStatesWf -} -process publishStatesProc { - // todo: check publishpath? - publishDir path: "${getPublishDir()}/", mode: "copy" - tag "$id" - input: - tuple val(id), val(yamlBlob), val(yamlFile), path(inputFiles, stageAs: "_inputfile?/*"), val(outputFiles) - output: - tuple val(id), path{[yamlFile] + outputFiles} - script: - def copyCommands = [ - inputFiles instanceof List ? inputFiles : [inputFiles], - outputFiles instanceof List ? outputFiles : [outputFiles] - ] - .transpose() - .collectMany{infile, outfile -> - if (infile.toString() != outfile.toString()) { - [ - "[ -d \"\$(dirname '${outfile.toString()}')\" ] || mkdir -p \"\$(dirname '${outfile.toString()}')\"", - "cp -r '${infile.toString()}' '${outfile.toString()}'" - ] - } else { - // no need to copy if infile is the same as outfile - [] - } - } - """ -mkdir -p "\$(dirname '${yamlFile}')" -echo "Storing state as yaml" -echo '${yamlBlob}' > '${yamlFile}' -echo "Copying output files to destination folder" -${copyCommands.join("\n ")} -""" -} - - -// this assumes that the state contains no other values other than those specified in the config -def publishStatesByConfig(Map args) { - def config = args.get("config") - assert config != null : "publishStatesByConfig: config must be specified" - - def key_ = args.get("key", config.name) - assert key_ != null : "publishStatesByConfig: key must be specified" - - workflow publishStatesSimpleWf { - take: input_ch - main: - input_ch - | map { tup -> - def id_ = tup[0] - def state_ = tup[1] // e.g. [output: new File("myoutput.h5ad"), k: 10] - def origState_ = tup[2] // e.g. [output: '$id.$key.foo.h5ad'] - - // TODO: allow overriding the state.yaml template - // TODO TODO: if auto.publish == "state", add output_state as an argument - def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' - def yamlFilename = yamlTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() - - // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where - // - key is a String - // - value is any object that can be serialized to a Yaml (so a String/Integer/Long/Double/Boolean, a List, a Map, or a Path) - // - inputPath is a List[Path] - // - outputFilename is a List[String] - // - (key, value) are the tuples that will be saved to the state.yaml file - // - (inputPath, outputFilename) are the files that will be copied from src to dest (relative to the state.yaml) - def processedState = - config.allArguments - .findAll { it.direction == "output" } - .collectMany { par -> - def plainName_ = par.plainName - // if the state does not contain the key, it's an - // optional argument for which the component did - // not generate any output - if (!state_.containsKey(plainName_)) { - return [] - } - def value = state_[plainName_] - // if the parameter is not a file, it should be stored - // in the state as-is, but is not something that needs - // to be copied from the source path to the dest path - if (par.type != "file") { - return [[key: plainName_, value: value, inputPath: [], outputFilename: []]] - } - // if the orig state does not contain this filename, - // it's an optional argument for which the user specified - // that it should not be returned as a state - if (!origState_.containsKey(plainName_)) { - return [] - } - def filenameTemplate = origState_[plainName_] - // if the pararameter is multiple: true, fetch the template - if (par.multiple && filenameTemplate instanceof List) { - filenameTemplate = filenameTemplate[0] - } - // instantiate the template - def filename = filenameTemplate - .replaceAll('\\$id', id_) - .replaceAll('\\$key', key_) - if (par.multiple) { - // if the parameter is multiple: true, the filename - // should contain a wildcard '*' that is replaced with - // the index of the file - assert filename.contains("*") : "Module '${key_}' id '${id_}': Multiple output files specified, but no wildcard '*' in the filename: ${filename}" - def outputPerFile = value.withIndex().collect{ val, ix -> - def filename_ix = filename.replace("*", ix.toString()) - def value_ = java.nio.file.Paths.get(filename_ix) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = val instanceof File ? val.toPath() : val - [value: value_, inputPath: inputPath, outputFilename: filename_ix] - } - def transposedOutputs = ["value", "inputPath", "outputFilename"].collectEntries{ key -> - [key, outputPerFile.collect{dic -> dic[key]}] - } - return [[key: plainName_] + transposedOutputs] - } else { - def value_ = java.nio.file.Paths.get(filename) - // if id contains a slash - if (yamlDir != null) { - value_ = yamlDir.relativize(value_) - } - def inputPath = value instanceof File ? value.toPath() : value - return [[key: plainName_, value: value_, inputPath: [inputPath], outputFilename: [filename]]] - } - } - - def updatedState_ = processedState.collectEntries{[it.key, it.value]} - def inputPaths = processedState.collectMany{it.inputPath} - def outputFilenames = processedState.collectMany{it.outputFilename} - - // convert state to yaml blob - def yamlBlob_ = toTaggedYamlBlob([id: id_] + updatedState_) - - [id_, yamlBlob_, yamlFilename, inputPaths, outputFilenames] - } - | publishStatesProc - emit: input_ch - } - return publishStatesSimpleWf -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/states/setState.nf' -def setState(fun) { - assert fun instanceof Closure || fun instanceof Map || fun instanceof List : - "Error in setState: Expected process argument to be a Closure, a Map, or a List. Found: class ${fun.getClass()}" - - // if fun is a List, convert to map - if (fun instanceof List) { - // check whether fun is a list[string] - assert fun.every{it instanceof CharSequence} : "Error in setState: argument is a List, but not all elements are Strings" - fun = fun.collectEntries{[it, it]} - } - - // if fun is a map, convert to closure - if (fun instanceof Map) { - // check whether fun is a map[string, string] - assert fun.values().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all values are Strings" - assert fun.keySet().every{it instanceof CharSequence} : "Error in setState: argument is a Map, but not all keys are Strings" - def funMap = fun.clone() - // turn the map into a closure to be used later on - fun = { id_, state_ -> - assert state_ instanceof Map : "Error in setState: the state is not a Map" - funMap.collectMany{newkey, origkey -> - if (state_.containsKey(origkey)) { - [[newkey, state_[origkey]]] - } else { - [] - } - }.collectEntries() - } - } - - map { tup -> - def id = tup[0] - def state = tup[1] - def unfilteredState = fun(id, state) - def newState = unfilteredState.findAll{key, val -> val != null} - [id, newState] + tup.drop(2) - } -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processAuto.nf' -// TODO: unit test processAuto -def processAuto(Map auto) { - // remove null values - auto = auto.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = ["simplifyInput", "simplifyOutput", "transcript", "publish"] - def unexpectedKeys = auto.keySet() - expectedKeys - assert unexpectedKeys.isEmpty(), "unexpected keys in auto: '${unexpectedKeys.join("', '")}'" - - // check auto.simplifyInput - assert auto.simplifyInput instanceof Boolean, "auto.simplifyInput must be a boolean" - - // check auto.simplifyOutput - assert auto.simplifyOutput instanceof Boolean, "auto.simplifyOutput must be a boolean" - - // check auto.transcript - assert auto.transcript instanceof Boolean, "auto.transcript must be a boolean" - - // check auto.publish - assert auto.publish instanceof Boolean || auto.publish == "state", "auto.publish must be a boolean or 'state'" - - return auto.subMap(expectedKeys) -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processDirectives.nf' -def assertMapKeys(map, expectedKeys, requiredKeys, mapName) { - assert map instanceof Map : "Expected argument '$mapName' to be a Map. Found: class ${map.getClass()}" - map.forEach { key, val -> - assert key in expectedKeys : "Unexpected key '$key' in ${mapName ? mapName + " " : ""}map" - } - requiredKeys.forEach { requiredKey -> - assert map.containsKey(requiredKey) : "Missing required key '$key' in ${mapName ? mapName + " " : ""}map" - } -} - -// TODO: unit test processDirectives -def processDirectives(Map drctv) { - // remove null values - drctv = drctv.findAll{k, v -> v != null} - - // check for unexpected keys - def expectedKeys = [ - "accelerator", "afterScript", "beforeScript", "cache", "conda", "container", "containerOptions", "cpus", "disk", "echo", "errorStrategy", "executor", "machineType", "maxErrors", "maxForks", "maxRetries", "memory", "module", "penv", "pod", "publishDir", "queue", "label", "scratch", "storeDir", "stageInMode", "stageOutMode", "tag", "time" - ] - def unexpectedKeys = drctv.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Unexpected keys in process directive: '${unexpectedKeys.join("', '")}'" - - /* DIRECTIVE accelerator - accepted examples: - - [ limit: 4, type: "nvidia-tesla-k80" ] - */ - if (drctv.containsKey("accelerator")) { - assertMapKeys(drctv["accelerator"], ["type", "limit", "request", "runtime"], [], "accelerator") - } - - /* DIRECTIVE afterScript - accepted examples: - - "source /cluster/bin/cleanup" - */ - if (drctv.containsKey("afterScript")) { - assert drctv["afterScript"] instanceof CharSequence - } - - /* DIRECTIVE beforeScript - accepted examples: - - "source /cluster/bin/setup" - */ - if (drctv.containsKey("beforeScript")) { - assert drctv["beforeScript"] instanceof CharSequence - } - - /* DIRECTIVE cache - accepted examples: - - true - - false - - "deep" - - "lenient" - */ - if (drctv.containsKey("cache")) { - assert drctv["cache"] instanceof CharSequence || drctv["cache"] instanceof Boolean - if (drctv["cache"] instanceof CharSequence) { - assert drctv["cache"] in ["deep", "lenient"] : "Unexpected value for cache" - } - } - - /* DIRECTIVE conda - accepted examples: - - "bwa=0.7.15" - - "bwa=0.7.15 fastqc=0.11.5" - - ["bwa=0.7.15", "fastqc=0.11.5"] - */ - if (drctv.containsKey("conda")) { - if (drctv["conda"] instanceof List) { - drctv["conda"] = drctv["conda"].join(" ") - } - assert drctv["conda"] instanceof CharSequence - } - - /* DIRECTIVE container - accepted examples: - - "foo/bar:tag" - - [ registry: "reg", image: "im", tag: "ta" ] - is transformed to "reg/im:ta" - - [ image: "im" ] - is transformed to "im:latest" - */ - if (drctv.containsKey("container")) { - assert drctv["container"] instanceof Map || drctv["container"] instanceof CharSequence - if (drctv["container"] instanceof Map) { - def m = drctv["container"] - assertMapKeys(m, [ "registry", "image", "tag" ], ["image"], "container") - def part1 = - System.getenv('OVERRIDE_CONTAINER_REGISTRY') ? System.getenv('OVERRIDE_CONTAINER_REGISTRY') + "/" : - params.containsKey("override_container_registry") ? params["override_container_registry"] + "/" : // todo: remove? - m.registry ? m.registry + "/" : - "" - def part2 = m.image - def part3 = m.tag ? ":" + m.tag : ":latest" - drctv["container"] = part1 + part2 + part3 - } - } - - /* DIRECTIVE containerOptions - accepted examples: - - "--foo bar" - - ["--foo bar", "-f b"] - */ - if (drctv.containsKey("containerOptions")) { - if (drctv["containerOptions"] instanceof List) { - drctv["containerOptions"] = drctv["containerOptions"].join(" ") - } - assert drctv["containerOptions"] instanceof CharSequence - } - - /* DIRECTIVE cpus - accepted examples: - - 1 - - 10 - */ - if (drctv.containsKey("cpus")) { - assert drctv["cpus"] instanceof Integer - } - - /* DIRECTIVE disk - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("disk")) { - assert drctv["disk"] instanceof CharSequence - // assert drctv["disk"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE echo - accepted examples: - - true - - false - */ - if (drctv.containsKey("echo")) { - assert drctv["echo"] instanceof Boolean - } - - /* DIRECTIVE errorStrategy - accepted examples: - - "terminate" - - "finish" - */ - if (drctv.containsKey("errorStrategy")) { - assert drctv["errorStrategy"] instanceof CharSequence - assert drctv["errorStrategy"] in ["terminate", "finish", "ignore", "retry"] : "Unexpected value for errorStrategy" - } - - /* DIRECTIVE executor - accepted examples: - - "local" - - "sge" - */ - if (drctv.containsKey("executor")) { - assert drctv["executor"] instanceof CharSequence - assert drctv["executor"] in ["local", "sge", "uge", "lsf", "slurm", "pbs", "pbspro", "moab", "condor", "nqsii", "ignite", "k8s", "awsbatch", "google-pipelines"] : "Unexpected value for executor" - } - - /* DIRECTIVE machineType - accepted examples: - - "n1-highmem-8" - */ - if (drctv.containsKey("machineType")) { - assert drctv["machineType"] instanceof CharSequence - } - - /* DIRECTIVE maxErrors - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxErrors")) { - assert drctv["maxErrors"] instanceof Integer - } - - /* DIRECTIVE maxForks - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxForks")) { - assert drctv["maxForks"] instanceof Integer - } - - /* DIRECTIVE maxRetries - accepted examples: - - 1 - - 3 - */ - if (drctv.containsKey("maxRetries")) { - assert drctv["maxRetries"] instanceof Integer - } - - /* DIRECTIVE memory - accepted examples: - - "1 GB" - - "2TB" - - "3.2KB" - - "10.B" - */ - if (drctv.containsKey("memory")) { - assert drctv["memory"] instanceof CharSequence - // assert drctv["memory"].matches("[0-9]+(\\.[0-9]*)? *[KMGTPEZY]?B") - // ^ does not allow closures - } - - /* DIRECTIVE module - accepted examples: - - "ncbi-blast/2.2.27" - - "ncbi-blast/2.2.27:t_coffee/10.0" - - ["ncbi-blast/2.2.27", "t_coffee/10.0"] - */ - if (drctv.containsKey("module")) { - if (drctv["module"] instanceof List) { - drctv["module"] = drctv["module"].join(":") - } - assert drctv["module"] instanceof CharSequence - } - - /* DIRECTIVE penv - accepted examples: - - "smp" - */ - if (drctv.containsKey("penv")) { - assert drctv["penv"] instanceof CharSequence - } - - /* DIRECTIVE pod - accepted examples: - - [ label: "key", value: "val" ] - - [ annotation: "key", value: "val" ] - - [ env: "key", value: "val" ] - - [ [label: "l", value: "v"], [env: "e", value: "v"]] - */ - if (drctv.containsKey("pod")) { - if (drctv["pod"] instanceof Map) { - drctv["pod"] = [ drctv["pod"] ] - } - assert drctv["pod"] instanceof List - drctv["pod"].forEach { pod -> - assert pod instanceof Map - // TODO: should more checks be added? - // See https://www.nextflow.io/docs/latest/process.html?highlight=directives#pod - // e.g. does it contain 'label' and 'value', or 'annotation' and 'value', or ...? - } - } - - /* DIRECTIVE publishDir - accepted examples: - - [] - - [ [ path: "foo", enabled: true ], [ path: "bar", enabled: false ] ] - - "/path/to/dir" - is transformed to [[ path: "/path/to/dir" ]] - - [ path: "/path/to/dir", mode: "cache" ] - is transformed to [[ path: "/path/to/dir", mode: "cache" ]] - */ - // TODO: should we also look at params["publishDir"]? - if (drctv.containsKey("publishDir")) { - def pblsh = drctv["publishDir"] - - // check different options - assert pblsh instanceof List || pblsh instanceof Map || pblsh instanceof CharSequence - - // turn into list if not already so - // for some reason, 'if (!pblsh instanceof List) pblsh = [ pblsh ]' doesn't work. - pblsh = pblsh instanceof List ? pblsh : [ pblsh ] - - // check elements of publishDir - pblsh = pblsh.collect{ elem -> - // turn into map if not already so - elem = elem instanceof CharSequence ? [ path: elem ] : elem - - // check types and keys - assert elem instanceof Map : "Expected publish argument '$elem' to be a String or a Map. Found: class ${elem.getClass()}" - assertMapKeys(elem, [ "path", "mode", "overwrite", "pattern", "saveAs", "enabled" ], ["path"], "publishDir") - - // check elements in map - assert elem.containsKey("path") - assert elem["path"] instanceof CharSequence - if (elem.containsKey("mode")) { - assert elem["mode"] instanceof CharSequence - assert elem["mode"] in [ "symlink", "rellink", "link", "copy", "copyNoFollow", "move" ] - } - if (elem.containsKey("overwrite")) { - assert elem["overwrite"] instanceof Boolean - } - if (elem.containsKey("pattern")) { - assert elem["pattern"] instanceof CharSequence - } - if (elem.containsKey("saveAs")) { - assert elem["saveAs"] instanceof CharSequence //: "saveAs as a Closure is currently not supported. Surround your closure with single quotes to get the desired effect. Example: '\{ foo \}'" - } - if (elem.containsKey("enabled")) { - assert elem["enabled"] instanceof Boolean - } - - // return final result - elem - } - // store final directive - drctv["publishDir"] = pblsh - } - - /* DIRECTIVE queue - accepted examples: - - "long" - - "short,long" - - ["short", "long"] - */ - if (drctv.containsKey("queue")) { - if (drctv["queue"] instanceof List) { - drctv["queue"] = drctv["queue"].join(",") - } - assert drctv["queue"] instanceof CharSequence - } - - /* DIRECTIVE label - accepted examples: - - "big_mem" - - "big_cpu" - - ["big_mem", "big_cpu"] - */ - if (drctv.containsKey("label")) { - if (drctv["label"] instanceof CharSequence) { - drctv["label"] = [ drctv["label"] ] - } - assert drctv["label"] instanceof List - drctv["label"].forEach { label -> - assert label instanceof CharSequence - // assert label.matches("[a-zA-Z0-9]([a-zA-Z0-9_]*[a-zA-Z0-9])?") - // ^ does not allow closures - } - } - - /* DIRECTIVE scratch - accepted examples: - - true - - "/path/to/scratch" - - '$MY_PATH_TO_SCRATCH' - - "ram-disk" - */ - if (drctv.containsKey("scratch")) { - assert drctv["scratch"] == true || drctv["scratch"] instanceof CharSequence - } - - /* DIRECTIVE storeDir - accepted examples: - - "/path/to/storeDir" - */ - if (drctv.containsKey("storeDir")) { - assert drctv["storeDir"] instanceof CharSequence - } - - /* DIRECTIVE stageInMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageInMode")) { - assert drctv["stageInMode"] instanceof CharSequence - assert drctv["stageInMode"] in ["copy", "link", "symlink", "rellink"] - } - - /* DIRECTIVE stageOutMode - accepted examples: - - "copy" - - "link" - */ - if (drctv.containsKey("stageOutMode")) { - assert drctv["stageOutMode"] instanceof CharSequence - assert drctv["stageOutMode"] in ["copy", "move", "rsync"] - } - - /* DIRECTIVE tag - accepted examples: - - "foo" - - '$id' - */ - if (drctv.containsKey("tag")) { - assert drctv["tag"] instanceof CharSequence - } - - /* DIRECTIVE time - accepted examples: - - "1h" - - "2days" - - "1day 6hours 3minutes 30seconds" - */ - if (drctv.containsKey("time")) { - assert drctv["time"] instanceof CharSequence - // todo: validation regex? - } - - return drctv -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf' -def processWorkflowArgs(Map args, Map defaultWfArgs, Map meta) { - // override defaults with args - def workflowArgs = defaultWfArgs + args - - // check whether 'key' exists - assert workflowArgs.containsKey("key") : "Error in module '${meta.config.name}': key is a required argument" - - // if 'key' is a closure, apply it to the original key - if (workflowArgs["key"] instanceof Closure) { - workflowArgs["key"] = workflowArgs["key"](meta.config.name) - } - def key = workflowArgs["key"] - assert key instanceof CharSequence : "Expected process argument 'key' to be a String. Found: class ${key.getClass()}" - assert key ==~ /^[a-zA-Z_]\w*$/ : "Error in module '$key': Expected process argument 'key' to consist of only letters, digits or underscores. Found: ${key}" - - // check for any unexpected keys - def expectedKeys = ["key", "directives", "auto", "map", "mapId", "mapData", "mapPassthrough", "filter", "runIf", "fromState", "toState", "args", "renameKeys", "debug"] - def unexpectedKeys = workflowArgs.keySet() - expectedKeys - assert unexpectedKeys.isEmpty() : "Error in module '$key': unexpected arguments to the '.run()' function: '${unexpectedKeys.join("', '")}'" - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("directives") : "Error in module '$key': directives is a required argument" - assert workflowArgs["directives"] instanceof Map : "Error in module '$key': Expected process argument 'directives' to be a Map. Found: class ${workflowArgs['directives'].getClass()}" - workflowArgs["directives"] = processDirectives(defaultWfArgs.directives + workflowArgs["directives"]) - - // check whether directives exists and apply defaults - assert workflowArgs.containsKey("auto") : "Error in module '$key': auto is a required argument" - assert workflowArgs["auto"] instanceof Map : "Error in module '$key': Expected process argument 'auto' to be a Map. Found: class ${workflowArgs['auto'].getClass()}" - workflowArgs["auto"] = processAuto(defaultWfArgs.auto + workflowArgs["auto"]) - - // auto define publish, if so desired - if (workflowArgs.auto.publish == true && (workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : [:]).isEmpty()) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.publish is true, params.publish_dir needs to be defined.\n" + - // " Example: params.publish_dir = \"./output/\"" - def publishDir = getPublishDir() - - if (publishDir != null) { - workflowArgs.directives.publishDir = [[ - path: publishDir, - saveAs: "{ it.startsWith('.') ? null : it }", // don't publish hidden files, by default - mode: "copy" - ]] - } - } - - // auto define transcript, if so desired - if (workflowArgs.auto.transcript == true) { - // can't assert at this level thanks to the no_publish profile - // assert params.containsKey("transcriptsDir") || params.containsKey("transcripts_dir") || params.containsKey("publishDir") || params.containsKey("publish_dir") : - // "Error in module '${workflowArgs['key']}': if auto.transcript is true, either params.transcripts_dir or params.publish_dir needs to be defined.\n" + - // " Example: params.transcripts_dir = \"./transcripts/\"" - def transcriptsDir = - params.containsKey("transcripts_dir") ? params.transcripts_dir : - params.containsKey("transcriptsDir") ? params.transcriptsDir : - params.containsKey("publish_dir") ? params.publish_dir + "/_transcripts" : - params.containsKey("publishDir") ? params.publishDir + "/_transcripts" : - null - if (transcriptsDir != null) { - def timestamp = nextflow.Nextflow.getSession().getWorkflowMetadata().start.format('yyyy-MM-dd_HH-mm-ss') - def transcriptsPublishDir = [ - path: "$transcriptsDir/$timestamp/\${task.process.replaceAll(':', '-')}/\${id}/", - saveAs: "{ it.startsWith('.') ? it.replaceAll('^.', '') : null }", - mode: "copy" - ] - def publishDirs = workflowArgs.directives.publishDir != null ? workflowArgs.directives.publishDir : null ? workflowArgs.directives.publishDir : [] - workflowArgs.directives.publishDir = publishDirs + transcriptsPublishDir - } - } - - // if this is a stubrun, remove certain directives? - if (workflow.stubRun) { - workflowArgs.directives.keySet().removeAll(["publishDir", "cpus", "memory", "label"]) - } - - for (nam in ["map", "mapId", "mapData", "mapPassthrough", "filter", "runIf"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam]) { - assert workflowArgs[nam] instanceof Closure : "Error in module '$key': Expected process argument '$nam' to be null or a Closure. Found: class ${workflowArgs[nam].getClass()}" - } - } - - // TODO: should functions like 'map', 'mapId', 'mapData', 'mapPassthrough' be deprecated as well? - for (nam in ["map", "mapData", "mapPassthrough", "renameKeys"]) { - if (workflowArgs.containsKey(nam) && workflowArgs[nam] != null) { - log.warn "module '$key': workflow argument '$nam' is deprecated and will be removed in Viash 0.9.0. Please use 'fromState' and 'toState' instead." - } - } - - // check fromState - workflowArgs["fromState"] = _processFromState(workflowArgs.get("fromState"), key, meta.config) - - // check toState - workflowArgs["toState"] = _processToState(workflowArgs.get("toState"), key, meta.config) - - // return output - return workflowArgs -} - -def _processFromState(fromState, key_, config_) { - assert fromState == null || fromState instanceof Closure || fromState instanceof Map || fromState instanceof List : - "Error in module '$key_': Expected process argument 'fromState' to be null, a Closure, a Map, or a List. Found: class ${fromState.getClass()}" - if (fromState == null) { - return null - } - - // if fromState is a List, convert to map - if (fromState instanceof List) { - // check whether fromstate is a list[string] - assert fromState.every{it instanceof CharSequence} : "Error in module '$key_': fromState is a List, but not all elements are Strings" - fromState = fromState.collectEntries{[it, it]} - } - - // if fromState is a map, convert to closure - if (fromState instanceof Map) { - // check whether fromstate is a map[string, string] - assert fromState.values().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all values are Strings" - assert fromState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': fromState is a Map, but not all keys are Strings" - def fromStateMap = fromState.clone() - def requiredInputNames = meta.config.allArguments.findAll{it.required && it.direction == "Input"}.collect{it.plainName} - // turn the map into a closure to be used later on - fromState = { it -> - def state = it[1] - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def data = fromStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (state.containsKey(origkey)) { - [[newkey, state[origkey]]] - } else if (!requiredInputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': fromState key '$origkey' not found in current state") - } - }.collectEntries() - data - } - } - - return fromState -} - -def _processToState(toState, key_, config_) { - if (toState == null) { - toState = { tup -> tup[1] } - } - - // toState should be a closure, map[string, string], or list[string] - assert toState instanceof Closure || toState instanceof Map || toState instanceof List : - "Error in module '$key_': Expected process argument 'toState' to be a Closure, a Map, or a List. Found: class ${toState.getClass()}" - - // if toState is a List, convert to map - if (toState instanceof List) { - // check whether toState is a list[string] - assert toState.every{it instanceof CharSequence} : "Error in module '$key_': toState is a List, but not all elements are Strings" - toState = toState.collectEntries{[it, it]} - } - - // if toState is a map, convert to closure - if (toState instanceof Map) { - // check whether toState is a map[string, string] - assert toState.values().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all values are Strings" - assert toState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all keys are Strings" - def toStateMap = toState.clone() - def requiredOutputNames = config_.allArguments.findAll{it.required && it.direction == "Output"}.collect{it.plainName} - // turn the map into a closure to be used later on - toState = { it -> - def output = it[1] - def state = it[2] - assert output instanceof Map : "Error in module '$key_': the output is not a Map" - assert state instanceof Map : "Error in module '$key_': the state is not a Map" - def extraEntries = toStateMap.collectMany{newkey, origkey -> - // check whether newkey corresponds to a required argument - if (output.containsKey(origkey)) { - [[newkey, output[origkey]]] - } else if (!requiredOutputNames.contains(origkey)) { - [] - } else { - throw new Exception("Error in module '$key_': toState key '$origkey' not found in current output") - } - }.collectEntries() - state + extraEntries - } - } - - return toState -} - -// helper file: 'src/main/resources/io/viash/runners/nextflow/workflowFactory/workflowFactory.nf' -def _debug(workflowArgs, debugKey) { - if (workflowArgs.debug) { - view { "process '${workflowArgs.key}' $debugKey tuple: $it" } - } else { - map { it } - } -} - -// depends on: innerWorkflowFactory -def workflowFactory(Map args, Map defaultWfArgs, Map meta) { - def workflowArgs = processWorkflowArgs(args, defaultWfArgs, meta) - def key_ = workflowArgs["key"] - - workflow workflowInstance { - take: input_ - - main: - def chModified = input_ - | checkUniqueIds([:]) - | _debug(workflowArgs, "input") - | map { tuple -> - tuple = deepClone(tuple) - - if (workflowArgs.map) { - tuple = workflowArgs.map(tuple) - } - if (workflowArgs.mapId) { - tuple[0] = workflowArgs.mapId(tuple[0]) - } - if (workflowArgs.mapData) { - tuple[1] = workflowArgs.mapData(tuple[1]) - } - if (workflowArgs.mapPassthrough) { - tuple = tuple.take(2) + workflowArgs.mapPassthrough(tuple.drop(2)) - } - - // check tuple - assert tuple instanceof List : - "Error in module '${key_}': element in channel should be a tuple [id, data, ...otherargs...]\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: List. Found: tuple.getClass() is ${tuple.getClass()}" - assert tuple.size() >= 2 : - "Error in module '${key_}': expected length of tuple in input channel to be two or greater.\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: tuple.size() == ${tuple.size()}" - - // check id field - if (tuple[0] instanceof GString) { - tuple[0] = tuple[0].toString() - } - assert tuple[0] instanceof CharSequence : - "Error in module '${key_}': first element of tuple in channel should be a String\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Found: ${tuple[0]}" - - // match file to input file - if (workflowArgs.auto.simplifyInput && (tuple[1] instanceof Path || tuple[1] instanceof List)) { - def inputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - - assert inputFiles.size() == 1 : - "Error in module '${key_}' id '${tuple[0]}'.\n" + - " Anonymous file inputs are only allowed when the process has exactly one file input.\n" + - " Expected: inputFiles.size() == 1. Found: inputFiles.size() is ${inputFiles.size()}" - - tuple[1] = [[ inputFiles[0].plainName, tuple[1] ]].collectEntries() - } - - // check data field - assert tuple[1] instanceof Map : - "Error in module '${key_}' id '${tuple[0]}': second element of tuple in channel should be a Map\n" + - " Example: [\"id\", [input: file('foo.txt'), arg: 10]].\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // rename keys of data field in tuple - if (workflowArgs.renameKeys) { - assert workflowArgs.renameKeys instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class: Map. Found: renameKeys.getClass() is ${workflowArgs.renameKeys.getClass()}" - assert tuple[1] instanceof Map : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Expected class: Map. Found: tuple[1].getClass() is ${tuple[1].getClass()}" - - // TODO: allow renameKeys to be a function? - workflowArgs.renameKeys.each { newKey, oldKey -> - assert newKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of newKey: String. Found: newKey.getClass() is ${newKey.getClass()}" - assert oldKey instanceof CharSequence : - "Error renaming data keys in module '${key_}' id '${tuple[0]}'.\n" + - " Example: renameKeys: ['new_key': 'old_key'].\n" + - " Expected class of oldKey: String. Found: oldKey.getClass() is ${oldKey.getClass()}" - assert tuple[1].containsKey(oldKey) : - "Error renaming data keys in module '${key}' id '${tuple[0]}'.\n" + - " Key '$oldKey' is missing in the data map. tuple[1].keySet() is '${tuple[1].keySet()}'" - tuple[1].put(newKey, tuple[1][oldKey]) - } - tuple[1].keySet().removeAll(workflowArgs.renameKeys.collect{ newKey, oldKey -> oldKey }) - } - tuple - } - - def chModifiedFiltered = workflowArgs.filter ? - chModified | filter{workflowArgs.filter(it)} : - chModified - - def chRun = null - def chPassthrough = null - if (workflowArgs.runIf) { - def runIfBranch = chModifiedFiltered.branch{ tup -> - run: workflowArgs.runIf(tup[0], tup[1]) - passthrough: true - } - chRun = runIfBranch.run - chPassthrough = runIfBranch.passthrough - } else { - chRun = chModifiedFiltered - chPassthrough = Channel.empty() - } - - def chArgs = workflowArgs.fromState ? - chRun | map{ - def new_data = workflowArgs.fromState(it.take(2)) - [it[0], new_data] - } : - chRun | map {tup -> tup.take(2)} - - // fill in defaults - def chArgsWithDefaults = chArgs - | map { tuple -> - def id_ = tuple[0] - def data_ = tuple[1] - - // TODO: could move fromState to here - - // fetch default params from functionality - def defaultArgs = meta.config.allArguments - .findAll { it.containsKey("default") } - .collectEntries { [ it.plainName, it.default ] } - - // fetch overrides in params - def paramArgs = meta.config.allArguments - .findAll { par -> - def argKey = key_ + "__" + par.plainName - params.containsKey(argKey) - } - .collectEntries { [ it.plainName, params[key_ + "__" + it.plainName] ] } - - // fetch overrides in data - def dataArgs = meta.config.allArguments - .findAll { data_.containsKey(it.plainName) } - .collectEntries { [ it.plainName, data_[it.plainName] ] } - - // combine params - def combinedArgs = defaultArgs + paramArgs + workflowArgs.args + dataArgs - - // remove arguments with explicit null values - combinedArgs - .removeAll{_, val -> val == null || val == "viash_no_value" || val == "force_null"} - - combinedArgs = _processInputValues(combinedArgs, meta.config, id_, key_) - - [id_, combinedArgs] + tuple.drop(2) - } - - // TODO: move some of the _meta.join_id wrangling to the safeJoin() function. - def chInitialOutput = chArgsWithDefaults - | _debug(workflowArgs, "processed") - // run workflow - | innerWorkflowFactory(workflowArgs) - // check output tuple - | map { id_, output_ -> - - // see if output map contains metadata - def meta_ = - output_ instanceof Map && output_.containsKey("_meta") ? - output_["_meta"] : - [:] - def join_id = meta_.join_id ?: id_ - - // remove metadata - output_ = output_.findAll{k, v -> k != "_meta"} - - // check value types - output_ = _processOutputValues(output_, meta.config, id_, key_) - - // simplify output if need be - if (workflowArgs.auto.simplifyOutput && output_.size() == 1) { - output_ = output_.values()[0] - } - - [join_id, id_, output_] - } - // | view{"chInitialOutput: ${it.take(3)}"} - - // join the output [prev_id, new_id, output] with the previous state [prev_id, state, ...] - def chNewState = safeJoin(chInitialOutput, chModifiedFiltered, key_) - // input tuple format: [join_id, id, output, prev_state, ...] - // output tuple format: [join_id, id, new_state, ...] - | map{ tup -> - def new_state = workflowArgs.toState(tup.drop(1).take(3)) - tup.take(2) + [new_state] + tup.drop(4) - } - - if (workflowArgs.auto.publish == "state") { - def chPublish = chNewState - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [join_id, id, new_state] - | map{ tup -> - tup.take(3) - } - - safeJoin(chPublish, chArgsWithDefaults, key_) - // input tuple format: [join_id, id, new_state, orig_state, ...] - // output tuple format: [id, new_state, orig_state] - | map { tup -> - tup.drop(1).take(3) - } - | publishStatesByConfig(key: key_, config: meta.config) - } - - // remove join_id and meta - chReturn = chNewState - | map { tup -> - // input tuple format: [join_id, id, new_state, ...] - // output tuple format: [id, new_state, ...] - tup.drop(1) - } - | _debug(workflowArgs, "output") - | concat(chPassthrough) - - emit: chReturn - } - - def wf = workflowInstance.cloneWithName(key_) - - // add factory function - wf.metaClass.run = { runArgs -> - workflowFactory(runArgs, workflowArgs, meta) - } - // add config to module for later introspection - wf.metaClass.config = meta.config - - return wf -} - -nextflow.enable.dsl=2 - -// START COMPONENT-SPECIFIC CODE - -// create meta object -meta = [ - "resources_dir": moduleDir.toRealPath().normalize(), - "config": processConfig(readJsonBlob('''{ - "name" : "samtools_stats", - "namespace" : "samtools", - "version" : "v0.1.0", - "argument_groups" : [ - { - "name" : "Inputs", - "arguments" : [ - { - "type" : "file", - "name" : "--input", - "description" : "Input file.\n", - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--bai", - "description" : "Index file.\n", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--fasta", - "description" : "Reference file the CRAM was created with.\n", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--coverage", - "alternatives" : [ - "-c" - ], - "description" : "Coverage distribution min,max,step [1,1000,1].\n", - "required" : false, - "direction" : "input", - "multiple" : true, - "multiple_sep" : "," - }, - { - "type" : "boolean_true", - "name" : "--remove_dups", - "alternatives" : [ - "-d" - ], - "description" : "Exclude from statistics reads marked as duplicates.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--customized_index_file", - "alternatives" : [ - "-X" - ], - "description" : "Use a customized index file.\n", - "direction" : "input" - }, - { - "type" : "string", - "name" : "--required_flag", - "alternatives" : [ - "-f" - ], - "description" : "Required flag, 0 for unset. See also `samtools flags`.\n", - "default" : [ - "0" - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "string", - "name" : "--filtering_flag", - "alternatives" : [ - "-F" - ], - "description" : "Filtering flag, 0 for unset. See also `samtools flags`.\n", - "default" : [ - "0" - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "double", - "name" : "--GC_depth", - "description" : "The size of GC-depth bins (decreasing bin size increases memory requirement).\n", - "default" : [ - 20000.0 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--insert_size", - "alternatives" : [ - "-i" - ], - "description" : "Maximum insert size.\n", - "default" : [ - 8000 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "string", - "name" : "--id", - "alternatives" : [ - "-I" - ], - "description" : "Include only listed read group or sample name.\n", - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--read_length", - "alternatives" : [ - "-l" - ], - "description" : "Include in the statistics only reads with the given read length.\n", - "default" : [ - -1 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "double", - "name" : "--most_inserts", - "alternatives" : [ - "-m" - ], - "description" : "Report only the main part of inserts.\n", - "default" : [ - 0.99 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "string", - "name" : "--split_prefix", - "alternatives" : [ - "-P" - ], - "description" : "Path or string prefix for filepaths output by --split (default is input filename).\n", - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "integer", - "name" : "--trim_quality", - "alternatives" : [ - "-q" - ], - "description" : "The BWA trimming parameter.\n", - "default" : [ - 0 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--ref_seq", - "alternatives" : [ - "-r" - ], - "description" : "Reference sequence (required for GC-depth and mismatches-per-cycle calculation).\n", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "string", - "name" : "--split", - "alternatives" : [ - "-S" - ], - "description" : "Also write statistics to separate files split by tagged field.\n", - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--target_regions", - "alternatives" : [ - "-t" - ], - "description" : "Do stats in these regions only. Tab-delimited file chr,from,to, 1-based, inclusive.\n", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "boolean_true", - "name" : "--sparse", - "alternatives" : [ - "-x" - ], - "description" : "Suppress outputting IS rows where there are no insertions.\n", - "direction" : "input" - }, - { - "type" : "boolean_true", - "name" : "--remove_overlaps", - "alternatives" : [ - "-p" - ], - "description" : "Remove overlaps of paired-end reads from coverage and base count computations.\n", - "direction" : "input" - }, - { - "type" : "integer", - "name" : "--cov_threshold", - "alternatives" : [ - "-g" - ], - "description" : "Only bases with coverage above this value will be included in the target percentage computation.\n", - "default" : [ - 0 - ], - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "string", - "name" : "--input_fmt_option", - "description" : "Specify a single input file format option in the form of OPTION or OPTION=VALUE.\n", - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - }, - { - "type" : "file", - "name" : "--reference", - "description" : "Reference sequence FASTA FILE.\n", - "must_exist" : true, - "create_parent" : true, - "required" : false, - "direction" : "input", - "multiple" : false, - "multiple_sep" : ";" - } - ] - }, - { - "name" : "Outputs", - "arguments" : [ - { - "type" : "file", - "name" : "--output", - "alternatives" : [ - "-o" - ], - "description" : "Output file.\n", - "default" : [ - "out.txt" - ], - "must_exist" : true, - "create_parent" : true, - "required" : true, - "direction" : "output", - "multiple" : false, - "multiple_sep" : ";" - } - ] - } - ], - "resources" : [ - { - "type" : "bash_script", - "path" : "script.sh", - "is_executable" : true - } - ], - "description" : "Reports alignment summary statistics for a BAM file.", - "test_resources" : [ - { - "type" : "bash_script", - "path" : "test.sh", - "is_executable" : true - }, - { - "type" : "file", - "path" : "test_data" - } - ], - "status" : "enabled", - "requirements" : { - "commands" : [ - "ps" - ] - }, - "keywords" : [ - "statistics", - "counts", - "bam", - "sam", - "cram" - ], - "license" : "MIT/Expat", - "references" : { - "doi" : [ - "10.1093/bioinformatics/btp352", - "10.1093/gigascience/giab008" - ] - }, - "links" : { - "repository" : "https://github.com/samtools/samtools", - "homepage" : "https://www.htslib.org/", - "documentation" : "https://www.htslib.org/doc/samtools-stats.html" - }, - "runners" : [ - { - "type" : "executable", - "id" : "executable", - "docker_setup_strategy" : "ifneedbepullelsecachedbuild" - }, - { - "type" : "nextflow", - "id" : "nextflow", - "directives" : { - "tag" : "$id" - }, - "auto" : { - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false - }, - "config" : { - "labels" : { - "mem1gb" : "memory = 1000000000.B", - "mem2gb" : "memory = 2000000000.B", - "mem5gb" : "memory = 5000000000.B", - "mem10gb" : "memory = 10000000000.B", - "mem20gb" : "memory = 20000000000.B", - "mem50gb" : "memory = 50000000000.B", - "mem100gb" : "memory = 100000000000.B", - "mem200gb" : "memory = 200000000000.B", - "mem500gb" : "memory = 500000000000.B", - "mem1tb" : "memory = 1000000000000.B", - "mem2tb" : "memory = 2000000000000.B", - "mem5tb" : "memory = 5000000000000.B", - "mem10tb" : "memory = 10000000000000.B", - "mem20tb" : "memory = 20000000000000.B", - "mem50tb" : "memory = 50000000000000.B", - "mem100tb" : "memory = 100000000000000.B", - "mem200tb" : "memory = 200000000000000.B", - "mem500tb" : "memory = 500000000000000.B", - "mem1gib" : "memory = 1073741824.B", - "mem2gib" : "memory = 2147483648.B", - "mem4gib" : "memory = 4294967296.B", - "mem8gib" : "memory = 8589934592.B", - "mem16gib" : "memory = 17179869184.B", - "mem32gib" : "memory = 34359738368.B", - "mem64gib" : "memory = 68719476736.B", - "mem128gib" : "memory = 137438953472.B", - "mem256gib" : "memory = 274877906944.B", - "mem512gib" : "memory = 549755813888.B", - "mem1tib" : "memory = 1099511627776.B", - "mem2tib" : "memory = 2199023255552.B", - "mem4tib" : "memory = 4398046511104.B", - "mem8tib" : "memory = 8796093022208.B", - "mem16tib" : "memory = 17592186044416.B", - "mem32tib" : "memory = 35184372088832.B", - "mem64tib" : "memory = 70368744177664.B", - "mem128tib" : "memory = 140737488355328.B", - "mem256tib" : "memory = 281474976710656.B", - "mem512tib" : "memory = 562949953421312.B", - "cpu1" : "cpus = 1", - "cpu2" : "cpus = 2", - "cpu5" : "cpus = 5", - "cpu10" : "cpus = 10", - "cpu20" : "cpus = 20", - "cpu50" : "cpus = 50", - "cpu100" : "cpus = 100", - "cpu200" : "cpus = 200", - "cpu500" : "cpus = 500", - "cpu1000" : "cpus = 1000" - } - }, - "debug" : false, - "container" : "docker" - } - ], - "engines" : [ - { - "type" : "docker", - "id" : "docker", - "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", - "target_registry" : "images.viash-hub.com", - "target_tag" : "v0.1.0", - "namespace_separator" : "/", - "setup" : [ - { - "type" : "docker", - "run" : [ - "samtools --version 2>&1 | grep -E '^(samtools|Using htslib)' | \\\\\nsed 's#Using ##;s# \\\\([0-9\\\\.]*\\\\)$#: \\\\1#' > /var/software_versions.txt\n" - ] - } - ] - }, - { - "type" : "native", - "id" : "native" - } - ], - "build_info" : { - "config" : "/workdir/root/repo/src/samtools/samtools_stats/config.vsh.yaml", - "runner" : "nextflow", - "engine" : "docker|native", - "output" : "target/nextflow/samtools/samtools_stats", - "viash_version" : "0.9.0-RC6", - "git_commit" : "b84b29747d0635f2ac83ea63b496be9a9edb6724", - "git_remote" : "https://github.com/viash-hub/biobox" - }, - "package_config" : { - "name" : "biobox", - "version" : "v0.1.0", - "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC6", - "source" : "src", - "target" : "target", - "config_mods" : [ - ".requirements.commands := ['ps']\n", - ".engines += { type: \\"native\\" }", - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" - ], - "keywords" : [ - "bioinformatics", - "modules", - "sequencing" - ], - "license" : "MIT", - "organization" : "vsh", - "links" : { - "repository" : "https://github.com/viash-hub/biobox", - "issue_tracker" : "https://github.com/viash-hub/biobox/issues" - } - } -}''')) -] - -// resolve dependencies dependencies (if any) - - -// inner workflow -// inner workflow hook -def innerWorkflowFactory(args) { - def rawScript = '''set -e -tempscript=".viash_script.sh" -cat > "$tempscript" << VIASHMAIN -#!/bin/bash - -## VIASH START -# The following code has been auto-generated by Viash. -$( if [ ! -z ${VIASH_PAR_INPUT+x} ]; then echo "${VIASH_PAR_INPUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_input='&'#" ; else echo "# par_input="; fi ) -$( if [ ! -z ${VIASH_PAR_BAI+x} ]; then echo "${VIASH_PAR_BAI}" | sed "s#'#'\\"'\\"'#g;s#.*#par_bai='&'#" ; else echo "# par_bai="; fi ) -$( if [ ! -z ${VIASH_PAR_FASTA+x} ]; then echo "${VIASH_PAR_FASTA}" | sed "s#'#'\\"'\\"'#g;s#.*#par_fasta='&'#" ; else echo "# par_fasta="; fi ) -$( if [ ! -z ${VIASH_PAR_COVERAGE+x} ]; then echo "${VIASH_PAR_COVERAGE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_coverage='&'#" ; else echo "# par_coverage="; fi ) -$( if [ ! -z ${VIASH_PAR_REMOVE_DUPS+x} ]; then echo "${VIASH_PAR_REMOVE_DUPS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_remove_dups='&'#" ; else echo "# par_remove_dups="; fi ) -$( if [ ! -z ${VIASH_PAR_CUSTOMIZED_INDEX_FILE+x} ]; then echo "${VIASH_PAR_CUSTOMIZED_INDEX_FILE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_customized_index_file='&'#" ; else echo "# par_customized_index_file="; fi ) -$( if [ ! -z ${VIASH_PAR_REQUIRED_FLAG+x} ]; then echo "${VIASH_PAR_REQUIRED_FLAG}" | sed "s#'#'\\"'\\"'#g;s#.*#par_required_flag='&'#" ; else echo "# par_required_flag="; fi ) -$( if [ ! -z ${VIASH_PAR_FILTERING_FLAG+x} ]; then echo "${VIASH_PAR_FILTERING_FLAG}" | sed "s#'#'\\"'\\"'#g;s#.*#par_filtering_flag='&'#" ; else echo "# par_filtering_flag="; fi ) -$( if [ ! -z ${VIASH_PAR_GC_DEPTH+x} ]; then echo "${VIASH_PAR_GC_DEPTH}" | sed "s#'#'\\"'\\"'#g;s#.*#par_GC_depth='&'#" ; else echo "# par_GC_depth="; fi ) -$( if [ ! -z ${VIASH_PAR_INSERT_SIZE+x} ]; then echo "${VIASH_PAR_INSERT_SIZE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_insert_size='&'#" ; else echo "# par_insert_size="; fi ) -$( if [ ! -z ${VIASH_PAR_ID+x} ]; then echo "${VIASH_PAR_ID}" | sed "s#'#'\\"'\\"'#g;s#.*#par_id='&'#" ; else echo "# par_id="; fi ) -$( if [ ! -z ${VIASH_PAR_READ_LENGTH+x} ]; then echo "${VIASH_PAR_READ_LENGTH}" | sed "s#'#'\\"'\\"'#g;s#.*#par_read_length='&'#" ; else echo "# par_read_length="; fi ) -$( if [ ! -z ${VIASH_PAR_MOST_INSERTS+x} ]; then echo "${VIASH_PAR_MOST_INSERTS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_most_inserts='&'#" ; else echo "# par_most_inserts="; fi ) -$( if [ ! -z ${VIASH_PAR_SPLIT_PREFIX+x} ]; then echo "${VIASH_PAR_SPLIT_PREFIX}" | sed "s#'#'\\"'\\"'#g;s#.*#par_split_prefix='&'#" ; else echo "# par_split_prefix="; fi ) -$( if [ ! -z ${VIASH_PAR_TRIM_QUALITY+x} ]; then echo "${VIASH_PAR_TRIM_QUALITY}" | sed "s#'#'\\"'\\"'#g;s#.*#par_trim_quality='&'#" ; else echo "# par_trim_quality="; fi ) -$( if [ ! -z ${VIASH_PAR_REF_SEQ+x} ]; then echo "${VIASH_PAR_REF_SEQ}" | sed "s#'#'\\"'\\"'#g;s#.*#par_ref_seq='&'#" ; else echo "# par_ref_seq="; fi ) -$( if [ ! -z ${VIASH_PAR_SPLIT+x} ]; then echo "${VIASH_PAR_SPLIT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_split='&'#" ; else echo "# par_split="; fi ) -$( if [ ! -z ${VIASH_PAR_TARGET_REGIONS+x} ]; then echo "${VIASH_PAR_TARGET_REGIONS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_target_regions='&'#" ; else echo "# par_target_regions="; fi ) -$( if [ ! -z ${VIASH_PAR_SPARSE+x} ]; then echo "${VIASH_PAR_SPARSE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_sparse='&'#" ; else echo "# par_sparse="; fi ) -$( if [ ! -z ${VIASH_PAR_REMOVE_OVERLAPS+x} ]; then echo "${VIASH_PAR_REMOVE_OVERLAPS}" | sed "s#'#'\\"'\\"'#g;s#.*#par_remove_overlaps='&'#" ; else echo "# par_remove_overlaps="; fi ) -$( if [ ! -z ${VIASH_PAR_COV_THRESHOLD+x} ]; then echo "${VIASH_PAR_COV_THRESHOLD}" | sed "s#'#'\\"'\\"'#g;s#.*#par_cov_threshold='&'#" ; else echo "# par_cov_threshold="; fi ) -$( if [ ! -z ${VIASH_PAR_INPUT_FMT_OPTION+x} ]; then echo "${VIASH_PAR_INPUT_FMT_OPTION}" | sed "s#'#'\\"'\\"'#g;s#.*#par_input_fmt_option='&'#" ; else echo "# par_input_fmt_option="; fi ) -$( if [ ! -z ${VIASH_PAR_REFERENCE+x} ]; then echo "${VIASH_PAR_REFERENCE}" | sed "s#'#'\\"'\\"'#g;s#.*#par_reference='&'#" ; else echo "# par_reference="; fi ) -$( if [ ! -z ${VIASH_PAR_OUTPUT+x} ]; then echo "${VIASH_PAR_OUTPUT}" | sed "s#'#'\\"'\\"'#g;s#.*#par_output='&'#" ; else echo "# par_output="; fi ) -$( if [ ! -z ${VIASH_META_NAME+x} ]; then echo "${VIASH_META_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_name='&'#" ; else echo "# meta_name="; fi ) -$( if [ ! -z ${VIASH_META_FUNCTIONALITY_NAME+x} ]; then echo "${VIASH_META_FUNCTIONALITY_NAME}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_functionality_name='&'#" ; else echo "# meta_functionality_name="; fi ) -$( if [ ! -z ${VIASH_META_RESOURCES_DIR+x} ]; then echo "${VIASH_META_RESOURCES_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_resources_dir='&'#" ; else echo "# meta_resources_dir="; fi ) -$( if [ ! -z ${VIASH_META_EXECUTABLE+x} ]; then echo "${VIASH_META_EXECUTABLE}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_executable='&'#" ; else echo "# meta_executable="; fi ) -$( if [ ! -z ${VIASH_META_CONFIG+x} ]; then echo "${VIASH_META_CONFIG}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_config='&'#" ; else echo "# meta_config="; fi ) -$( if [ ! -z ${VIASH_META_TEMP_DIR+x} ]; then echo "${VIASH_META_TEMP_DIR}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_temp_dir='&'#" ; else echo "# meta_temp_dir="; fi ) -$( if [ ! -z ${VIASH_META_CPUS+x} ]; then echo "${VIASH_META_CPUS}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_cpus='&'#" ; else echo "# meta_cpus="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_B+x} ]; then echo "${VIASH_META_MEMORY_B}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_b='&'#" ; else echo "# meta_memory_b="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KB+x} ]; then echo "${VIASH_META_MEMORY_KB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kb='&'#" ; else echo "# meta_memory_kb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MB+x} ]; then echo "${VIASH_META_MEMORY_MB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mb='&'#" ; else echo "# meta_memory_mb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GB+x} ]; then echo "${VIASH_META_MEMORY_GB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gb='&'#" ; else echo "# meta_memory_gb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TB+x} ]; then echo "${VIASH_META_MEMORY_TB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tb='&'#" ; else echo "# meta_memory_tb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PB+x} ]; then echo "${VIASH_META_MEMORY_PB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pb='&'#" ; else echo "# meta_memory_pb="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_KIB+x} ]; then echo "${VIASH_META_MEMORY_KIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_kib='&'#" ; else echo "# meta_memory_kib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_MIB+x} ]; then echo "${VIASH_META_MEMORY_MIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_mib='&'#" ; else echo "# meta_memory_mib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_GIB+x} ]; then echo "${VIASH_META_MEMORY_GIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_gib='&'#" ; else echo "# meta_memory_gib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_TIB+x} ]; then echo "${VIASH_META_MEMORY_TIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_tib='&'#" ; else echo "# meta_memory_tib="; fi ) -$( if [ ! -z ${VIASH_META_MEMORY_PIB+x} ]; then echo "${VIASH_META_MEMORY_PIB}" | sed "s#'#'\\"'\\"'#g;s#.*#meta_memory_pib='&'#" ; else echo "# meta_memory_pib="; fi ) - -## VIASH END - -set -e - -[[ "\\$par_remove_dups" == "false" ]] && unset par_remove_dups -[[ "\\$par_customized_index_file" == "false" ]] && unset par_customized_index_file -[[ "\\$par_sparse" == "false" ]] && unset par_sparse -[[ "\\$par_remove_overlaps" == "false" ]] && unset par_remove_overlaps - -samtools stats \\\\ - \\${par_coverage:+-c "\\$par_coverage"} \\\\ - \\${par_remove_dups:+-d} \\\\ - \\${par_required_flag:+-f "\\$par_required_flag"} \\\\ - \\${par_filtering_flag:+-F "\\$par_filtering_flag"} \\\\ - \\${par_GC_depth:+--GC-depth "\\$par_GC_depth"} \\\\ - \\${par_insert_size:+-i "\\$par_insert_size"} \\\\ - \\${par_id:+-I "\\$par_id"} \\\\ - \\${par_read_length:+-l "\\$par_read_length"} \\\\ - \\${par_most_inserts:+-m "\\$par_most_inserts"} \\\\ - \\${par_split_prefix:+-P "\\$par_split_prefix"} \\\\ - \\${par_trim_quality:+-q "\\$par_trim_quality"} \\\\ - \\${par_ref_seq:+-r "\\$par_ref_seq"} \\\\ - \\${par_split:+-S "\\$par_split"} \\\\ - \\${par_target_regions:+-t "\\$par_target_regions"} \\\\ - \\${par_sparse:+-x} \\\\ - \\${par_remove_overlaps:+-p} \\\\ - \\${par_cov_threshold:+-g "\\$par_cov_threshold"} \\\\ - \\${par_input_fmt_option:+-O "\\$par_input_fmt_option"} \\\\ - \\${par_reference:+-R "\\$par_reference"} \\\\ - "\\$par_input" \\\\ - > "\\$par_output" - -exit 0 -VIASHMAIN -bash "$tempscript" -''' - - return vdsl3WorkflowFactory(args, meta, rawScript) -} - - - -/** - * Generate a workflow for VDSL3 modules. - * - * This function is called by the workflowFactory() function. - * - * Input channel: [id, input_map] - * Output channel: [id, output_map] - * - * Internally, this workflow will convert the input channel - * to a format which the Nextflow module will be able to handle. - */ -def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { - def key = args["key"] - def processObj = null - - workflow processWf { - take: input_ - main: - - if (processObj == null) { - processObj = _vdsl3ProcessFactory(args, meta, rawScript) - } - - output_ = input_ - | map { tuple -> - def id = tuple[0] - def data_ = tuple[1] - - if (workflow.stubRun) { - // add id if missing - data_ = [id: 'stub'] + data_ - } - - // process input files separately - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { par -> - def val = data_.containsKey(par.plainName) ? data_[par.plainName] : [] - def inputFiles = [] - if (val == null) { - inputFiles = [] - } else if (val instanceof List) { - inputFiles = val - } else if (val instanceof Path) { - inputFiles = [ val ] - } else { - inputFiles = [] - } - if (!workflow.stubRun) { - // throw error when an input file doesn't exist - inputFiles.each{ file -> - assert file.exists() : - "Error in module '${key}' id '${id}' argument '${par.plainName}'.\n" + - " Required input file does not exist.\n" + - " Path: '$file'.\n" + - " Expected input file to exist" - } - } - inputFiles - } - - // remove input files - def argsExclInputFiles = meta.config.allArguments - .findAll { (it.type != "file" || it.direction != "input") && data_.containsKey(it.plainName) } - .collectEntries { par -> - def parName = par.plainName - def val = data_[parName] - if (par.multiple && val instanceof Collection) { - val = val.join(par.multiple_sep) - } - if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) - } - [parName, val] - } - - [ id ] + inputPaths + [ argsExclInputFiles, meta.resources_dir ] - } - | processObj - | map { output -> - def outputFiles = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .indexed() - .collectEntries{ index, par -> - def out = output[index + 1] - // strip dummy '.exitcode' file from output (see nextflow-io/nextflow#2678) - if (!out instanceof List || out.size() <= 1) { - if (par.multiple) { - out = [] - } else { - assert !par.required : - "Error in module '${key}' id '${output[0]}' argument '${par.plainName}'.\n" + - " Required output file is missing" - out = null - } - } else if (out.size() == 2 && !par.multiple) { - out = out[1] - } else { - out = out.drop(1) - } - [ par.plainName, out ] - } - - // drop null outputs - outputFiles.removeAll{it.value == null} - - [ output[0], outputFiles ] - } - emit: output_ - } - - return processWf -} - -// depends on: session? -def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { - // autodetect process key - def wfKey = workflowArgs["key"] - def procKeyPrefix = "${wfKey}_process" - def scriptMeta = nextflow.script.ScriptMeta.current() - def existing = scriptMeta.getProcessNames().findAll{it.startsWith(procKeyPrefix)} - def numbers = existing.collect{it.replace(procKeyPrefix, "0").toInteger()} - def newNumber = (numbers + [-1]).max() + 1 - - def procKey = newNumber == 0 ? procKeyPrefix : "$procKeyPrefix$newNumber" - - if (newNumber > 0) { - log.warn "Key for module '${wfKey}' is duplicated.\n", - "If you run a component multiple times in the same workflow,\n" + - "it's recommended you set a unique key for every call,\n" + - "for example: ${wfKey}.run(key: \"foo\")." - } - - // subset directives and convert to list of tuples - def drctv = workflowArgs.directives - - // TODO: unit test the two commands below - // convert publish array into tags - def valueToStr = { val -> - // ignore closures - if (val instanceof CharSequence) { - if (!val.matches('^[{].*[}]$')) { - '"' + val + '"' - } else { - val - } - } else if (val instanceof List) { - "[" + val.collect{valueToStr(it)}.join(", ") + "]" - } else if (val instanceof Map) { - "[" + val.collect{k, v -> k + ": " + valueToStr(v)}.join(", ") + "]" - } else { - val.inspect() - } - } - - // multiple entries allowed: label, publishdir - def drctvStrs = drctv.collect { key, value -> - if (key in ["label", "publishDir"]) { - value.collect{ val -> - if (val instanceof Map) { - "\n$key " + val.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else if (val == null) { - "" - } else { - "\n$key " + valueToStr(val) - } - }.join() - } else if (value instanceof Map) { - "\n$key " + value.collect{ k, v -> k + ": " + valueToStr(v) }.join(", ") - } else { - "\n$key " + valueToStr(value) - } - }.join() - - def inputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "input" } - .collect { ', path(viash_par_' + it.plainName + ', stageAs: "_viash_par/' + it.plainName + '_?/*")' } - .join() - - def outputPaths = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - // insert dummy into every output (see nextflow-io/nextflow#2678) - if (!par.multiple) { - ', path{[".exitcode", args.' + par.plainName + ']}' - } else { - ', path{[".exitcode"] + args.' + par.plainName + '}' - } - } - .join() - - // TODO: move this functionality somewhere else? - if (workflowArgs.auto.transcript) { - outputPaths = outputPaths + ', path{[".exitcode", ".command*"]}' - } else { - outputPaths = outputPaths + ', path{[".exitcode"]}' - } - - // create dirs for output files (based on BashWrapper.createParentFiles) - def createParentStr = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" && it.create_parent } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // construct inputFileExports - def inputFileExports = meta.config.allArguments - .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } - .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" - } - - // NOTE: if using docker, use /tmp instead of tmpDir! - def tmpDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('VIASH_TMPDIR') ?: - System.getenv('VIASH_TEMPDIR') ?: - System.getenv('VIASH_TMP') ?: - System.getenv('TEMP') ?: - System.getenv('TMPDIR') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMP') ?: - '/tmp' - ).toAbsolutePath() - - // construct stub - def stub = meta.config.allArguments - .findAll { it.type == "file" && it.direction == "output" } - .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"touch2 \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"].replace(\"_*\", \"_0\") : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" - } - .join("\n") - - // escape script - def escapedScript = rawScript.replace('\\', '\\\\').replace('$', '\\$').replace('"""', '\\"\\"\\"') - - // publishdir assert - def assertStr = (workflowArgs.auto.publish == true) || workflowArgs.auto.transcript ? - """\nassert task.publishDir.size() > 0: "if auto.publish is true, params.publish_dir needs to be defined.\\n Example: --publish_dir './output/'" """ : - "" - - // generate process string - def procStr = - """nextflow.enable.dsl=2 - | - |process $procKey {$drctvStrs - |input: - | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") - |output: - | tuple val("\$id")$outputPaths, optional: true - |stub: - |\"\"\" - |touch2() { mkdir -p "\\\$(dirname "\\\$1")" && touch "\\\$1" ; } - |$stub - |\"\"\" - |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } - |def parInject = args - | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} - | .join("\\n") - |\"\"\" - |# meta exports - |export VIASH_META_RESOURCES_DIR="\${resourcesDir}" - |export VIASH_META_TEMP_DIR="${['docker', 'podman', 'charliecloud'].any{ it == workflow.containerEngine } ? '/tmp' : tmpDir}" - |export VIASH_META_NAME="${meta.config.name}" - |# export VIASH_META_EXECUTABLE="\\\$VIASH_META_RESOURCES_DIR/\\\$VIASH_META_NAME" - |export VIASH_META_CONFIG="\\\$VIASH_META_RESOURCES_DIR/.config.vsh.yaml" - |\${task.cpus ? "export VIASH_META_CPUS=\$task.cpus" : "" } - |\${task.memory?.bytes != null ? "export VIASH_META_MEMORY_B=\$task.memory.bytes" : "" } - |if [ ! -z \\\${VIASH_META_MEMORY_B+x} ]; then - | export VIASH_META_MEMORY_KB=\\\$(( (\\\$VIASH_META_MEMORY_B+999) / 1000 )) - | export VIASH_META_MEMORY_MB=\\\$(( (\\\$VIASH_META_MEMORY_KB+999) / 1000 )) - | export VIASH_META_MEMORY_GB=\\\$(( (\\\$VIASH_META_MEMORY_MB+999) / 1000 )) - | export VIASH_META_MEMORY_TB=\\\$(( (\\\$VIASH_META_MEMORY_GB+999) / 1000 )) - | export VIASH_META_MEMORY_PB=\\\$(( (\\\$VIASH_META_MEMORY_TB+999) / 1000 )) - | export VIASH_META_MEMORY_KIB=\\\$(( (\\\$VIASH_META_MEMORY_B+1023) / 1024 )) - | export VIASH_META_MEMORY_MIB=\\\$(( (\\\$VIASH_META_MEMORY_KIB+1023) / 1024 )) - | export VIASH_META_MEMORY_GIB=\\\$(( (\\\$VIASH_META_MEMORY_MIB+1023) / 1024 )) - | export VIASH_META_MEMORY_TIB=\\\$(( (\\\$VIASH_META_MEMORY_GIB+1023) / 1024 )) - | export VIASH_META_MEMORY_PIB=\\\$(( (\\\$VIASH_META_MEMORY_TIB+1023) / 1024 )) - |fi - | - |# meta synonyms - |export VIASH_TEMP="\\\$VIASH_META_TEMP_DIR" - |export TEMP_DIR="\\\$VIASH_META_TEMP_DIR" - | - |# create output dirs if need be - |function mkdir_parent { - | for file in "\\\$@"; do - | mkdir -p "\\\$(dirname "\\\$file")" - | done - |} - |$createParentStr - | - |# argument exports${inputFileExports.join()} - |\$parInject - | - |# process script - |${escapedScript} - |\"\"\" - |} - |""".stripMargin() - - // TODO: print on debug - // if (workflowArgs.debug == true) { - // println("######################\n$procStr\n######################") - // } - - // write process to temp file - def tempFile = java.nio.file.Files.createTempFile("viash-process-${procKey}-", ".nf") - addShutdownHook { java.nio.file.Files.deleteIfExists(tempFile) } - tempFile.text = procStr - - // create process from temp file - def binding = new nextflow.script.ScriptBinding([:]) - def session = nextflow.Nextflow.getSession() - def parser = new nextflow.script.ScriptParser(session) - .setModule(true) - .setBinding(binding) - def moduleScript = parser.runScript(tempFile) - .getScript() - - // register module in meta - def module = new nextflow.script.IncludeDef.Module(name: procKey) - scriptMeta.addModule(moduleScript, module.name, module.alias) - - // retrieve and return process from meta - return scriptMeta.getProcess(procKey) -} - -// defaults -meta["defaults"] = [ - // key to be used to trace the process and determine output names - key: null, - - // fixed arguments to be passed to script - args: [:], - - // default directives - directives: readJsonBlob('''{ - "container" : { - "registry" : "images.viash-hub.com", - "image" : "vsh/biobox/samtools/samtools_stats", - "tag" : "v0.1.0" - }, - "tag" : "$id" -}'''), - - // auto settings - auto: readJsonBlob('''{ - "simplifyInput" : true, - "simplifyOutput" : false, - "transcript" : false, - "publish" : false -}'''), - - // Apply a map over the incoming tuple - // Example: `{ tup -> [ tup[0], [input: tup[1].output] ] + tup.drop(2) }` - map: null, - - // Apply a map over the ID element of a tuple (i.e. the first element) - // Example: `{ id -> id + "_foo" }` - mapId: null, - - // Apply a map over the data element of a tuple (i.e. the second element) - // Example: `{ data -> [ input: data.output ] }` - mapData: null, - - // Apply a map over the passthrough elements of a tuple (i.e. the tuple excl. the first two elements) - // Example: `{ pt -> pt.drop(1) }` - mapPassthrough: null, - - // Filter the channel - // Example: `{ tup -> tup[0] == "foo" }` - filter: null, - - // Choose whether or not to run the component on the tuple if the condition is true. - // Otherwise, the tuple will be passed through. - // Example: `{ tup -> tup[0] != "skip_this" }` - runIf: null, - - // Rename keys in the data field of the tuple (i.e. the second element) - // Will likely be deprecated in favour of `fromState`. - // Example: `[ "new_key": "old_key" ]` - renameKeys: null, - - // Fetch data from the state and pass it to the module without altering the current state. - // - // `fromState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be passed to the module as is. - // - If it is a `List[String]`, the data will be the values of the state at the given keys. - // - If it is a `Map[String, String]`, the data will be the values of the state at the given keys, with the keys renamed according to the map. - // - If it is a function, the tuple (`[id, state]`) in the channel will be passed to the function, and the result will be used as the data. - // - // Example: `{ id, state -> [input: state.fastq_file] }` - // Default: `null` - fromState: null, - - // Determine how the state should be updated after the module has been run. - // - // `toState` should be `null`, `List[String]`, `Map[String, String]` or a function. - // - // - If it is `null`, the state will be replaced with the output of the module. - // - If it is a `List[String]`, the state will be updated with the values of the data at the given keys. - // - If it is a `Map[String, String]`, the state will be updated with the values of the data at the given keys, with the keys renamed according to the map. - // - If it is a function, a tuple (`[id, output, state]`) will be passed to the function, and the result will be used as the new state. - // - // Example: `{ id, output, state -> state + [counts: state.output] }` - // Default: `{ id, output, state -> output }` - toState: null, - - // Whether or not to print debug messages - // Default: `false` - debug: false -] - -// initialise default workflow -meta["workflow"] = workflowFactory([key: meta.config.name], meta.defaults, meta) - -// add workflow to environment -nextflow.script.ScriptMeta.current().addDefinition(meta.workflow) - -// anonymous workflow for running this module as a standalone -workflow { - // add id argument if it's not already in the config - // TODO: deep copy - def newConfig = deepClone(meta.config) - def newParams = deepClone(params) - - def argsContainsId = newConfig.allArguments.any{it.plainName == "id"} - if (!argsContainsId) { - def idArg = [ - 'name': '--id', - 'required': false, - 'type': 'string', - 'description': 'A unique id for every entry.', - 'multiple': false - ] - newConfig.arguments.add(0, idArg) - newConfig = processConfig(newConfig) - } - if (!newParams.containsKey("id")) { - newParams.id = "run" - } - - helpMessage(newConfig) - - channelFromParams(newParams, newConfig) - // make sure id is not in the state if id is not in the args - | map {id, state -> - if (!argsContainsId) { - [id, state.findAll{k, v -> k != "id"}] - } else { - [id, state] - } - } - | meta.workflow.run( - auto: [ publish: "state" ] - ) -} - -// END COMPONENT-SPECIFIC CODE diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/nextflow.config deleted file mode 100644 index d746263..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/nextflow.config +++ /dev/null @@ -1,125 +0,0 @@ -manifest { - name = 'samtools/samtools_stats' - mainScript = 'main.nf' - nextflowVersion = '!>=20.12.1-edge' - version = 'v0.1.0' - description = 'Reports alignment summary statistics for a BAM file.' -} - -process.container = 'nextflow/bash:latest' - -// detect tempdir -tempDir = java.nio.file.Paths.get( - System.getenv('NXF_TEMP') ?: - System.getenv('VIASH_TEMP') ?: - System.getenv('TEMPDIR') ?: - System.getenv('TMPDIR') ?: - '/tmp' -).toAbsolutePath() - -profiles { - no_publish { - process { - withName: '.*' { - publishDir = [ - enabled: false - ] - } - } - } - mount_temp { - docker.temp = tempDir - podman.temp = tempDir - charliecloud.temp = tempDir - } - docker { - docker.enabled = true - // docker.userEmulation = true - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - singularity { - singularity.enabled = true - singularity.autoMounts = true - docker.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - podman { - podman.enabled = true - docker.enabled = false - singularity.enabled = false - shifter.enabled = false - charliecloud.enabled = false - } - shifter { - shifter.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - charliecloud.enabled = false - } - charliecloud { - charliecloud.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - } -} - -process{ - withLabel: mem1gb { memory = 1000000000.B } - withLabel: mem2gb { memory = 2000000000.B } - withLabel: mem5gb { memory = 5000000000.B } - withLabel: mem10gb { memory = 10000000000.B } - withLabel: mem20gb { memory = 20000000000.B } - withLabel: mem50gb { memory = 50000000000.B } - withLabel: mem100gb { memory = 100000000000.B } - withLabel: mem200gb { memory = 200000000000.B } - withLabel: mem500gb { memory = 500000000000.B } - withLabel: mem1tb { memory = 1000000000000.B } - withLabel: mem2tb { memory = 2000000000000.B } - withLabel: mem5tb { memory = 5000000000000.B } - withLabel: mem10tb { memory = 10000000000000.B } - withLabel: mem20tb { memory = 20000000000000.B } - withLabel: mem50tb { memory = 50000000000000.B } - withLabel: mem100tb { memory = 100000000000000.B } - withLabel: mem200tb { memory = 200000000000000.B } - withLabel: mem500tb { memory = 500000000000000.B } - withLabel: mem1gib { memory = 1073741824.B } - withLabel: mem2gib { memory = 2147483648.B } - withLabel: mem4gib { memory = 4294967296.B } - withLabel: mem8gib { memory = 8589934592.B } - withLabel: mem16gib { memory = 17179869184.B } - withLabel: mem32gib { memory = 34359738368.B } - withLabel: mem64gib { memory = 68719476736.B } - withLabel: mem128gib { memory = 137438953472.B } - withLabel: mem256gib { memory = 274877906944.B } - withLabel: mem512gib { memory = 549755813888.B } - withLabel: mem1tib { memory = 1099511627776.B } - withLabel: mem2tib { memory = 2199023255552.B } - withLabel: mem4tib { memory = 4398046511104.B } - withLabel: mem8tib { memory = 8796093022208.B } - withLabel: mem16tib { memory = 17592186044416.B } - withLabel: mem32tib { memory = 35184372088832.B } - withLabel: mem64tib { memory = 70368744177664.B } - withLabel: mem128tib { memory = 140737488355328.B } - withLabel: mem256tib { memory = 281474976710656.B } - withLabel: mem512tib { memory = 562949953421312.B } - withLabel: cpu1 { cpus = 1 } - withLabel: cpu2 { cpus = 2 } - withLabel: cpu5 { cpus = 5 } - withLabel: cpu10 { cpus = 10 } - withLabel: cpu20 { cpus = 20 } - withLabel: cpu50 { cpus = 50 } - withLabel: cpu100 { cpus = 100 } - withLabel: cpu200 { cpus = 200 } - withLabel: cpu500 { cpus = 500 } - withLabel: cpu1000 { cpus = 1000 } -} - - diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/nextflow_schema.json deleted file mode 100644 index ceb3b49..0000000 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/nextflow_schema.json +++ /dev/null @@ -1,327 +0,0 @@ -{ -"$schema": "http://json-schema.org/draft-07/schema", -"title": "samtools_stats", -"description": "Reports alignment summary statistics for a BAM file.", -"type": "object", -"definitions": { - - - - "inputs" : { - "title": "Inputs", - "type": "object", - "description": "No description", - "properties": { - - - "input": { - "type": - "string", - "description": "Type: `file`, required. Input file", - "help_text": "Type: `file`, required. Input file.\n" - - } - - - , - "bai": { - "type": - "string", - "description": "Type: `file`. Index file", - "help_text": "Type: `file`. Index file.\n" - - } - - - , - "fasta": { - "type": - "string", - "description": "Type: `file`. Reference file the CRAM was created with", - "help_text": "Type: `file`. Reference file the CRAM was created with.\n" - - } - - - , - "coverage": { - "type": - "string", - "description": "Type: List of `integer`, multiple_sep: `\",\"`. Coverage distribution min,max,step [1,1000,1]", - "help_text": "Type: List of `integer`, multiple_sep: `\",\"`. Coverage distribution min,max,step [1,1000,1].\n" - - } - - - , - "remove_dups": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Exclude from statistics reads marked as duplicates", - "help_text": "Type: `boolean_true`, default: `false`. Exclude from statistics reads marked as duplicates.\n" - , - "default": "False" - } - - - , - "customized_index_file": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Use a customized index file", - "help_text": "Type: `boolean_true`, default: `false`. Use a customized index file.\n" - , - "default": "False" - } - - - , - "required_flag": { - "type": - "string", - "description": "Type: `string`, default: `0`. Required flag, 0 for unset", - "help_text": "Type: `string`, default: `0`. Required flag, 0 for unset. See also `samtools flags`.\n" - , - "default": "0" - } - - - , - "filtering_flag": { - "type": - "string", - "description": "Type: `string`, default: `0`. Filtering flag, 0 for unset", - "help_text": "Type: `string`, default: `0`. Filtering flag, 0 for unset. See also `samtools flags`.\n" - , - "default": "0" - } - - - , - "GC_depth": { - "type": - "number", - "description": "Type: `double`, default: `20000.0`. The size of GC-depth bins (decreasing bin size increases memory requirement)", - "help_text": "Type: `double`, default: `20000.0`. The size of GC-depth bins (decreasing bin size increases memory requirement).\n" - , - "default": "20000.0" - } - - - , - "insert_size": { - "type": - "integer", - "description": "Type: `integer`, default: `8000`. Maximum insert size", - "help_text": "Type: `integer`, default: `8000`. Maximum insert size.\n" - , - "default": "8000" - } - - - , - "id": { - "type": - "string", - "description": "Type: `string`. Include only listed read group or sample name", - "help_text": "Type: `string`. Include only listed read group or sample name.\n" - - } - - - , - "read_length": { - "type": - "integer", - "description": "Type: `integer`, default: `-1`. Include in the statistics only reads with the given read length", - "help_text": "Type: `integer`, default: `-1`. Include in the statistics only reads with the given read length.\n" - , - "default": "-1" - } - - - , - "most_inserts": { - "type": - "number", - "description": "Type: `double`, default: `0.99`. Report only the main part of inserts", - "help_text": "Type: `double`, default: `0.99`. Report only the main part of inserts.\n" - , - "default": "0.99" - } - - - , - "split_prefix": { - "type": - "string", - "description": "Type: `string`. Path or string prefix for filepaths output by --split (default is input filename)", - "help_text": "Type: `string`. Path or string prefix for filepaths output by --split (default is input filename).\n" - - } - - - , - "trim_quality": { - "type": - "integer", - "description": "Type: `integer`, default: `0`. The BWA trimming parameter", - "help_text": "Type: `integer`, default: `0`. The BWA trimming parameter.\n" - , - "default": "0" - } - - - , - "ref_seq": { - "type": - "string", - "description": "Type: `file`. Reference sequence (required for GC-depth and mismatches-per-cycle calculation)", - "help_text": "Type: `file`. Reference sequence (required for GC-depth and mismatches-per-cycle calculation).\n" - - } - - - , - "split": { - "type": - "string", - "description": "Type: `string`. Also write statistics to separate files split by tagged field", - "help_text": "Type: `string`. Also write statistics to separate files split by tagged field.\n" - - } - - - , - "target_regions": { - "type": - "string", - "description": "Type: `file`. Do stats in these regions only", - "help_text": "Type: `file`. Do stats in these regions only. Tab-delimited file chr,from,to, 1-based, inclusive.\n" - - } - - - , - "sparse": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Suppress outputting IS rows where there are no insertions", - "help_text": "Type: `boolean_true`, default: `false`. Suppress outputting IS rows where there are no insertions.\n" - , - "default": "False" - } - - - , - "remove_overlaps": { - "type": - "boolean", - "description": "Type: `boolean_true`, default: `false`. Remove overlaps of paired-end reads from coverage and base count computations", - "help_text": "Type: `boolean_true`, default: `false`. Remove overlaps of paired-end reads from coverage and base count computations.\n" - , - "default": "False" - } - - - , - "cov_threshold": { - "type": - "integer", - "description": "Type: `integer`, default: `0`. Only bases with coverage above this value will be included in the target percentage computation", - "help_text": "Type: `integer`, default: `0`. Only bases with coverage above this value will be included in the target percentage computation.\n" - , - "default": "0" - } - - - , - "input_fmt_option": { - "type": - "string", - "description": "Type: `string`. Specify a single input file format option in the form of OPTION or OPTION=VALUE", - "help_text": "Type: `string`. Specify a single input file format option in the form of OPTION or OPTION=VALUE.\n" - - } - - - , - "reference": { - "type": - "string", - "description": "Type: `file`. Reference sequence FASTA FILE", - "help_text": "Type: `file`. Reference sequence FASTA FILE.\n" - - } - - -} -}, - - - "outputs" : { - "title": "Outputs", - "type": "object", - "description": "No description", - "properties": { - - - "output": { - "type": - "string", - "description": "Type: `file`, required, default: `$id.$key.output.txt`. Output file", - "help_text": "Type: `file`, required, default: `$id.$key.output.txt`. Output file.\n" - , - "default": "$id.$key.output.txt" - } - - -} -}, - - - "nextflow input-output arguments" : { - "title": "Nextflow input-output arguments", - "type": "object", - "description": "Input/output parameters for Nextflow itself. Please note that both publishDir and publish_dir are supported but at least one has to be configured.", - "properties": { - - - "publish_dir": { - "type": - "string", - "description": "Type: `string`, required, example: `output/`. Path to an output directory", - "help_text": "Type: `string`, required, example: `output/`. Path to an output directory." - - } - - - , - "param_list": { - "type": - "string", - "description": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel", - "help_text": "Type: `string`, example: `my_params.yaml`. Allows inputting multiple parameter sets to initialise a Nextflow channel. A `param_list` can either be a list of maps, a csv file, a json file, a yaml file, or simply a yaml blob.\n\n* A list of maps (as-is) where the keys of each map corresponds to the arguments of the pipeline. Example: in a `nextflow.config` file: `param_list: [ [\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027], [\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027] ]`.\n* A csv file should have column names which correspond to the different arguments of this pipeline. Example: `--param_list data.csv` with columns `id,input`.\n* A json or a yaml file should be a list of maps, each of which has keys corresponding to the arguments of the pipeline. Example: `--param_list data.json` with contents `[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]`.\n* A yaml blob can also be passed directly as a string. Example: `--param_list \"[ {\u0027id\u0027: \u0027foo\u0027, \u0027input\u0027: \u0027foo.txt\u0027}, {\u0027id\u0027: \u0027bar\u0027, \u0027input\u0027: \u0027bar.txt\u0027} ]\"`.\n\nWhen passing a csv, json or yaml file, relative path names are relativized to the location of the parameter file. No relativation is performed when `param_list` is a list of maps (as-is) or a yaml blob.", - "hidden": true - - } - - -} -} -}, -"allOf": [ - - { - "$ref": "#/definitions/inputs" - }, - - { - "$ref": "#/definitions/outputs" - }, - - { - "$ref": "#/definitions/nextflow input-output arguments" - } -] -} diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/.config.vsh.yaml similarity index 98% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/.config.vsh.yaml index 45b66e4..401926d 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/.config.vsh.yaml @@ -1,5 +1,23 @@ name: "fastp" -version: "v0.1.0" +version: "0.2.0" +authors: +- name: "Robrecht Cannoodt" + roles: + - "author" + - "maintainer" + info: + links: + email: "robrecht@data-intuitive.com" + github: "rcannood" + orcid: "0000-0003-3641-729X" + linkedin: "robrechtcannoodt" + organizations: + - name: "Data Intuitive" + href: "https://www.data-intuitive.com" + role: "Data Science Engineer" + - name: "Open Problems" + href: "https://openproblems.bio" + role: "Core Member" argument_groups: - name: "Inputs" description: "`fastp` supports both single-end (SE) and paired-end (PE) input.\n\ @@ -1048,7 +1066,7 @@ engines: id: "docker" image: "quay.io/biocontainers/fastp:0.23.4--hadf994f_2" target_registry: "images.viash-hub.com" - target_tag: "v0.1.0" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -1064,22 +1082,22 @@ build_info: engine: "docker|native" output: "target/nextflow/fastp" executable: "target/nextflow/fastp/main.nf" - viash_version: "0.9.0-RC6" - git_commit: "b84b29747d0635f2ac83ea63b496be9a9edb6724" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "v0.1.0" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC6" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/main.nf similarity index 97% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/main.nf index b343e1a..571d8b5 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/main.nf @@ -1,13 +1,16 @@ -// fastp v0.1.0 +// fastp 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC6 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such // files, or include a separate license file detailing the licenses of all included // files. +// +// Component authors: +// * Robrecht Cannoodt (author, maintainer) //////////////////////////// // VDSL3 helper functions // @@ -760,8 +763,11 @@ def runEach(Map args) { def fromState_ = args.fromState def toState_ = args.toState def filter_ = args.filter + def runIf_ = args.runIf def id_ = args.id + assert !runIf_ || runIf_ instanceof Closure: "runEach: must pass a Closure to runIf." + workflow runEachWf { take: input_ch main: @@ -783,7 +789,20 @@ def runEach(Map args) { [new_id] + tup.drop(1) } : filter_ch - def data_ch = id_ch | map{tup -> + def chPassthrough = null + def chRun = null + if (runIf_) { + def idRunIfBranch = id_ch.branch{ tup -> + run: runIf_(tup[0], tup[1], comp_) + passthrough: true + } + chPassthrough = idRunIfBranch.passthrough + chRun = idRunIfBranch.run + } else { + chRun = id_ch + chPassthrough = Channel.empty() + } + def data_ch = chRun | map{tup -> def new_data = tup[1] if (fromState_ instanceof Map) { new_data = fromState_.collectEntries{ key0, key1 -> @@ -821,8 +840,11 @@ def runEach(Map args) { [tup[0], new_state] + tup.drop(3) } : out_ch + + def return_ch = post_ch + | concat(chPassthrough) - post_ch + return_ch } // mix all results @@ -1598,8 +1620,8 @@ def findStates(Map params, Map config) { // construct renameMap if (args.rename_keys) { def renameMap = args.rename_keys.collectEntries{renameString -> - def split = renameString.split(";") - assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey,newKey:oldKey'" + def split = renameString.split(":") + assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey', or 'newKey:oldKey;newKey:oldKey' in case of multiple values" split } @@ -1709,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1780,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1822,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2626,30 +2654,31 @@ def workflowFactory(Map args, Map defaultWfArgs, Map meta) { tuple } - def chModifiedFiltered = workflowArgs.filter ? - chModified | filter{workflowArgs.filter(it)} : - chModified def chRun = null def chPassthrough = null if (workflowArgs.runIf) { - def runIfBranch = chModifiedFiltered.branch{ tup -> + def runIfBranch = chModified.branch{ tup -> run: workflowArgs.runIf(tup[0], tup[1]) passthrough: true } chRun = runIfBranch.run chPassthrough = runIfBranch.passthrough } else { - chRun = chModifiedFiltered + chRun = chModified chPassthrough = Channel.empty() } + def chRunFiltered = workflowArgs.filter ? + chRun | filter{workflowArgs.filter(it)} : + chRun + def chArgs = workflowArgs.fromState ? - chRun | map{ + chRunFiltered | map{ def new_data = workflowArgs.fromState(it.take(2)) [it[0], new_data] } : - chRun | map {tup -> tup.take(2)} + chRunFiltered | map {tup -> tup.take(2)} // fill in defaults def chArgsWithDefaults = chArgs @@ -2720,7 +2749,7 @@ def workflowFactory(Map args, Map defaultWfArgs, Map meta) { // | view{"chInitialOutput: ${it.take(3)}"} // join the output [prev_id, new_id, output] with the previous state [prev_id, state, ...] - def chNewState = safeJoin(chInitialOutput, chModifiedFiltered, key_) + def chNewState = safeJoin(chInitialOutput, chRunFiltered, key_) // input tuple format: [join_id, id, output, prev_state, ...] // output tuple format: [join_id, id, new_state, ...] | map{ tup -> @@ -2779,7 +2808,36 @@ meta = [ "resources_dir": moduleDir.toRealPath().normalize(), "config": processConfig(readJsonBlob('''{ "name" : "fastp", - "version" : "v0.1.0", + "version" : "0.2.0", + "authors" : [ + { + "name" : "Robrecht Cannoodt", + "roles" : [ + "author", + "maintainer" + ], + "info" : { + "links" : { + "email" : "robrecht@data-intuitive.com", + "github" : "rcannood", + "orcid" : "0000-0003-3641-729X", + "linkedin" : "robrechtcannoodt" + }, + "organizations" : [ + { + "name" : "Data Intuitive", + "href" : "https://www.data-intuitive.com", + "role" : "Data Science Engineer" + }, + { + "name" : "Open Problems", + "href" : "https://openproblems.bio", + "role" : "Core Member" + } + ] + } + } + ], "argument_groups" : [ { "name" : "Inputs", @@ -3943,7 +4001,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/fastp:0.23.4--hadf994f_2", "target_registry" : "images.viash-hub.com", - "target_tag" : "v0.1.0", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3964,22 +4022,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/fastp", - "viash_version" : "0.9.0-RC6", - "git_commit" : "b84b29747d0635f2ac83ea63b496be9a9edb6724", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "v0.1.0", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC6", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -4107,25 +4165,32 @@ $( if [ ! -z ${VIASH_META_MEMORY_PIB+x} ]; then echo "${VIASH_META_MEMORY_PIB}" ## VIASH END # disable flags -[[ "\\$par_disable_adapter_trimming" == "false" ]] && unset par_disable_adapter_trimming -[[ "\\$par_detect_adapter_for_pe" == "false" ]] && unset par_detect_adapter_for_pe -[[ "\\$par_merge" == "false" ]] && unset par_merge -[[ "\\$par_include_unmerged" == "false" ]] && unset par_include_unmerged -[[ "\\$par_interleaved_in" == "false" ]] && unset par_interleaved_in -[[ "\\$par_fix_mgi_id" == "false" ]] && unset par_fix_mgi_id -[[ "\\$par_phred64" == "false" ]] && unset par_phred64 -[[ "\\$par_dont_overwrite" == "false" ]] && unset par_dont_overwrite -[[ "\\$par_verbose" == "false" ]] && unset par_verbose -[[ "\\$par_dedup" == "false" ]] && unset par_dedup -[[ "\\$par_dont_eval_duplication" == "false" ]] && unset par_dont_eval_duplication -[[ "\\$par_trim_poly_g" == "false" ]] && unset par_trim_poly_g -[[ "\\$par_disable_trim_poly_g" == "false" ]] && unset par_disable_trim_poly_g -[[ "\\$par_trim_poly_x" == "false" ]] && unset par_trim_poly_x -[[ "\\$par_disable_quality_filtering" == "false" ]] && unset par_disable_quality_filtering -[[ "\\$par_disable_length_filtering" == "false" ]] && unset par_disable_length_filtering -[[ "\\$par_low_complexity_filter" == "false" ]] && unset par_low_complexity_filter -[[ "\\$par_umi" == "false" ]] && unset par_umi -[[ "\\$par_overrepresentation_analysis" == "false" ]] && unset par_overrepresentation_analysis +unset_if_false=( + par_disable_adapter_trimming + par_detect_adapter_for_pe + par_merge + par_include_unmerged + par_interleaved_in + par_fix_mgi_id + par_phred64 + par_dont_overwrite + par_verbose + par_dedup + par_dont_eval_duplication + par_trim_poly_g + par_disable_trim_poly_g + par_trim_poly_x + par_disable_quality_filtering + par_disable_length_filtering + par_low_complexity_filter + par_umi + par_overrepresentation_analysis +) + +for par in \\${unset_if_false[@]}; do + test_val="\\${!par}" + [[ "\\$test_val" == "false" ]] && unset \\$par +done # run command fastp \\\\ @@ -4286,7 +4351,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -4417,7 +4486,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -4425,8 +4495,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -4463,6 +4533,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -4474,10 +4545,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -4562,7 +4632,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/fastp", - "tag" : "v0.1.0" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/nextflow.config index 3df0360..3e1cb67 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/nextflow.config @@ -2,8 +2,9 @@ manifest { name = 'fastp' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'v0.1.0' + version = '0.2.0' description = 'An ultra-fast all-in-one FASTQ preprocessor (QC/adapters/trimming/filtering/splitting/merging...).\n\nFeatures:\n\n - comprehensive quality profiling for both before and after filtering data (quality curves, base contents, KMER, Q20/Q30, GC Ratio, duplication, adapter contents...)\n - filter out bad reads (too low quality, too short, or too many N...)\n - cut low quality bases for per read in its 5\' and 3\' by evaluating the mean quality from a sliding window (like Trimmomatic but faster).\n - trim all reads in front and tail\n - cut adapters. Adapter sequences can be automatically detected, which means you don\'t have to input the adapter sequences to trim them.\n - correct mismatched base pairs in overlapped regions of paired end reads, if one base is with high quality while the other is with ultra low quality\n - trim polyG in 3\' ends, which is commonly seen in NovaSeq/NextSeq data. Trim polyX in 3\' ends to remove unwanted polyX tailing (i.e. polyA tailing for mRNA-Seq data)\n - preprocess unique molecular identifier (UMI) enabled data, shift UMI to sequence name.\n - report JSON format result for further interpreting.\n - visualize quality control and filtering results on a single HTML page (like FASTQC but faster and more informative).\n - split the output to multiple files (0001.R1.gz, 0002.R1.gz...) to support parallel processing. Two modes can be used, limiting the total split file number, or limitting the lines of each split file.\n - support long reads (data from PacBio / Nanopore devices).\n - support reading from STDIN and writing to STDOUT\n - support interleaved input\n - support ultra-fast FASTQ-level deduplication\n' + author = 'Robrecht Cannoodt' } process.container = 'nextflow/bash:latest' diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/.config.vsh.yaml similarity index 97% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/.config.vsh.yaml index dfe3778..79e96a8 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/.config.vsh.yaml @@ -1,5 +1,19 @@ name: "featurecounts" -version: "v0.1.0" +version: "0.2.0" +authors: +- name: "Sai Nirmayi Yasa" + roles: + - "author" + - "maintainer" + info: + links: + email: "nirmayi@data-intuitive.com" + github: "sainirmayi" + linkedin: "sai-nirmayi-yasa" + organizations: + - name: "Data Intuitive" + href: "https://www.data-intuitive.com" + role: "Junior Bioinformatics Researcher" argument_groups: - name: "Inputs" arguments: @@ -613,7 +627,7 @@ engines: id: "docker" image: "quay.io/biocontainers/subread:2.0.6--he4a0461_0" target_registry: "images.viash-hub.com" - target_tag: "v0.1.0" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -630,22 +644,22 @@ build_info: engine: "docker|native" output: "target/nextflow/featurecounts" executable: "target/nextflow/featurecounts/main.nf" - viash_version: "0.9.0-RC6" - git_commit: "b84b29747d0635f2ac83ea63b496be9a9edb6724" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "v0.1.0" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC6" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/main.nf similarity index 97% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/main.nf index cb1303c..f39e713 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/main.nf @@ -1,13 +1,16 @@ -// featurecounts v0.1.0 +// featurecounts 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC6 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such // files, or include a separate license file detailing the licenses of all included // files. +// +// Component authors: +// * Sai Nirmayi Yasa (author, maintainer) //////////////////////////// // VDSL3 helper functions // @@ -760,8 +763,11 @@ def runEach(Map args) { def fromState_ = args.fromState def toState_ = args.toState def filter_ = args.filter + def runIf_ = args.runIf def id_ = args.id + assert !runIf_ || runIf_ instanceof Closure: "runEach: must pass a Closure to runIf." + workflow runEachWf { take: input_ch main: @@ -783,7 +789,20 @@ def runEach(Map args) { [new_id] + tup.drop(1) } : filter_ch - def data_ch = id_ch | map{tup -> + def chPassthrough = null + def chRun = null + if (runIf_) { + def idRunIfBranch = id_ch.branch{ tup -> + run: runIf_(tup[0], tup[1], comp_) + passthrough: true + } + chPassthrough = idRunIfBranch.passthrough + chRun = idRunIfBranch.run + } else { + chRun = id_ch + chPassthrough = Channel.empty() + } + def data_ch = chRun | map{tup -> def new_data = tup[1] if (fromState_ instanceof Map) { new_data = fromState_.collectEntries{ key0, key1 -> @@ -821,8 +840,11 @@ def runEach(Map args) { [tup[0], new_state] + tup.drop(3) } : out_ch + + def return_ch = post_ch + | concat(chPassthrough) - post_ch + return_ch } // mix all results @@ -1598,8 +1620,8 @@ def findStates(Map params, Map config) { // construct renameMap if (args.rename_keys) { def renameMap = args.rename_keys.collectEntries{renameString -> - def split = renameString.split(";") - assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey,newKey:oldKey'" + def split = renameString.split(":") + assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey', or 'newKey:oldKey;newKey:oldKey' in case of multiple values" split } @@ -1709,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1780,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1822,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2626,30 +2654,31 @@ def workflowFactory(Map args, Map defaultWfArgs, Map meta) { tuple } - def chModifiedFiltered = workflowArgs.filter ? - chModified | filter{workflowArgs.filter(it)} : - chModified def chRun = null def chPassthrough = null if (workflowArgs.runIf) { - def runIfBranch = chModifiedFiltered.branch{ tup -> + def runIfBranch = chModified.branch{ tup -> run: workflowArgs.runIf(tup[0], tup[1]) passthrough: true } chRun = runIfBranch.run chPassthrough = runIfBranch.passthrough } else { - chRun = chModifiedFiltered + chRun = chModified chPassthrough = Channel.empty() } + def chRunFiltered = workflowArgs.filter ? + chRun | filter{workflowArgs.filter(it)} : + chRun + def chArgs = workflowArgs.fromState ? - chRun | map{ + chRunFiltered | map{ def new_data = workflowArgs.fromState(it.take(2)) [it[0], new_data] } : - chRun | map {tup -> tup.take(2)} + chRunFiltered | map {tup -> tup.take(2)} // fill in defaults def chArgsWithDefaults = chArgs @@ -2720,7 +2749,7 @@ def workflowFactory(Map args, Map defaultWfArgs, Map meta) { // | view{"chInitialOutput: ${it.take(3)}"} // join the output [prev_id, new_id, output] with the previous state [prev_id, state, ...] - def chNewState = safeJoin(chInitialOutput, chModifiedFiltered, key_) + def chNewState = safeJoin(chInitialOutput, chRunFiltered, key_) // input tuple format: [join_id, id, output, prev_state, ...] // output tuple format: [join_id, id, new_state, ...] | map{ tup -> @@ -2779,7 +2808,30 @@ meta = [ "resources_dir": moduleDir.toRealPath().normalize(), "config": processConfig(readJsonBlob('''{ "name" : "featurecounts", - "version" : "v0.1.0", + "version" : "0.2.0", + "authors" : [ + { + "name" : "Sai Nirmayi Yasa", + "roles" : [ + "author", + "maintainer" + ], + "info" : { + "links" : { + "email" : "nirmayi@data-intuitive.com", + "github" : "sainirmayi", + "linkedin" : "sai-nirmayi-yasa" + }, + "organizations" : [ + { + "name" : "Data Intuitive", + "href" : "https://www.data-intuitive.com", + "role" : "Junior Bioinformatics Researcher" + } + ] + } + } + ], "argument_groups" : [ { "name" : "Inputs", @@ -3475,7 +3527,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/subread:2.0.6--he4a0461_0", "target_registry" : "images.viash-hub.com", - "target_tag" : "v0.1.0", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3496,22 +3548,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/featurecounts", - "viash_version" : "0.9.0-RC6", - "git_commit" : "b84b29747d0635f2ac83ea63b496be9a9edb6724", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "v0.1.0", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC6", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3622,24 +3674,31 @@ par_feature_type=\\$(echo \\$par_feature_type | tr ',' ';') par_extra_attributes=\\$(echo \\$par_extra_attributes | tr ',' ';') # unset flag variables -[[ "\\$par_feature_level" == "false" ]] && unset par_feature_level -[[ "\\$par_overlapping" == "false" ]] && unset par_overlapping -[[ "\\$par_largest_overlap" == "false" ]] && unset par_largest_overlap -[[ "\\$par_multi_mapping" == "false" ]] && unset par_multi_mapping -[[ "\\$par_fraction" == "false" ]] && unset par_fraction -[[ "\\$par_split_only" == "false" ]] && unset par_split_only -[[ "\\$par_non_split_only" == "false" ]] && unset par_non_split_only -[[ "\\$par_primary" == "false" ]] && unset par_primary -[[ "\\$par_ignore_dup" == "false" ]] && unset par_ignore_dup -[[ "\\$par_paired" == "false" ]] && unset par_paired -[[ "\\$par_count_read_pairs" == "false" ]] && unset par_count_read_pairs -[[ "\\$par_both_aligned" == "false" ]] && unset par_both_aligned -[[ "\\$par_check_pe_dist" == "false" ]] && unset par_check_pe_dist -[[ "\\$par_same_strand" == "false" ]] && unset par_same_strand -[[ "\\$par_donotsort" == "false" ]] && unset par_donotsort -[[ "\\$par_by_read_group" == "false" ]] && unset par_by_read_group -[[ "\\$par_long_reads" == "false" ]] && unset par_long_reads -[[ "\\$par_verbose" == "false" ]] && unset par_verbose +unset_if_false=( + par_feature_level + par_overlapping + par_largest_overlap + par_multi_mapping + par_fraction + par_split_only + par_non_split_only + par_primary + par_ignore_dup + par_paired + par_count_read_pairs + par_both_aligned + par_check_pe_dist + par_same_strand + par_donotsort + par_by_read_group + par_long_reads + par_verbose +) + +for par in \\${unset_if_false[@]}; do + test_val="\\${!par}" + [[ "\\$test_val" == "false" ]] && unset \\$par +done IFS=";" read -ra input <<< \\$par_input @@ -3775,7 +3834,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3906,7 +3969,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3914,8 +3978,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3952,6 +4016,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3963,10 +4028,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -4051,7 +4115,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/featurecounts", - "tag" : "v0.1.0" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/nextflow.config similarity index 98% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/nextflow.config index e241602..346054a 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/nextflow.config @@ -2,8 +2,9 @@ manifest { name = 'featurecounts' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'v0.1.0' + version = '0.2.0' description = 'featureCounts is a read summarization program for counting reads generated from either RNA or genomic DNA sequencing experiments by implementing highly efficient chromosome hashing and feature blocking techniques. It works with either single or paired-end reads and provides a wide range of options appropriate for different sequencing applications.\n' + author = 'Sai Nirmayi Yasa' } process.container = 'nextflow/bash:latest' diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/nextflow_schema.json similarity index 95% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/nextflow_schema.json index 564393b..d55c22d 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/nextflow_schema.json +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/nextflow_schema.json @@ -27,8 +27,8 @@ "input": { "type": "string", - "description": "Type: List of `file`, required, example: `input_file1.bam`, multiple_sep: `\":\"`. A list of SAM or BAM format files separated by semi-colon (;)", - "help_text": "Type: List of `file`, required, example: `input_file1.bam`, multiple_sep: `\":\"`. A list of SAM or BAM format files separated by semi-colon (;). They can be either name or location sorted. Location-sorted paired-end reads are automatically sorted by read names.\n" + "description": "Type: List of `file`, required, example: `input_file1.bam`, multiple_sep: `\";\"`. A list of SAM or BAM format files separated by semi-colon (;)", + "help_text": "Type: List of `file`, required, example: `input_file1.bam`, multiple_sep: `\";\"`. A list of SAM or BAM format files separated by semi-colon (;). They can be either name or location sorted. Location-sorted paired-end reads are automatically sorted by read names.\n" } @@ -102,8 +102,8 @@ "feature_type": { "type": "string", - "description": "Type: List of `string`, example: `exon`, multiple_sep: `\":\"`. Specify feature type(s) in a GTF annotation", - "help_text": "Type: List of `string`, example: `exon`, multiple_sep: `\":\"`. Specify feature type(s) in a GTF annotation. If multiple types are provided, they should be separated by \u0027;\u0027 with no space in between. \u0027exon\u0027 by default. Rows in the annotation with a matched feature will be extracted and used for read mapping.\n" + "description": "Type: List of `string`, example: `exon`, multiple_sep: `\";\"`. Specify feature type(s) in a GTF annotation", + "help_text": "Type: List of `string`, example: `exon`, multiple_sep: `\";\"`. Specify feature type(s) in a GTF annotation. If multiple types are provided, they should be separated by \u0027;\u0027 with no space in between. \u0027exon\u0027 by default. Rows in the annotation with a matched feature will be extracted and used for read mapping.\n" } @@ -122,8 +122,8 @@ "extra_attributes": { "type": "string", - "description": "Type: List of `string`, multiple_sep: `\":\"`. Extract extra attribute types from the provided GTF annotation and include them in the counting output", - "help_text": "Type: List of `string`, multiple_sep: `\":\"`. Extract extra attribute types from the provided GTF annotation and include them in the counting output. These attribute types will not be used to group features. If more than one attribute type is provided they should be separated by semicolon (;).\n" + "description": "Type: List of `string`, multiple_sep: `\";\"`. Extract extra attribute types from the provided GTF annotation and include them in the counting output", + "help_text": "Type: List of `string`, multiple_sep: `\";\"`. Extract extra attribute types from the provided GTF annotation and include them in the counting output. These attribute types will not be used to group features. If more than one attribute type is provided they should be separated by semicolon (;).\n" } @@ -194,8 +194,8 @@ "frac_overlap": { "type": "number", - "description": "Type: `double`, example: `0`. Minimum fraction of overlapping bases in a read that is required for read assignment", - "help_text": "Type: `double`, example: `0`. Minimum fraction of overlapping bases in a read that is required for read assignment. Value should be within range [0,1]. 0 by default. Number of overlapping bases is counted from both reads if paired end. Both this option and \u0027--min_overlap\u0027 option need to be satisfied for read assignment.\n" + "description": "Type: `double`, example: `0.0`. Minimum fraction of overlapping bases in a read that is required for read assignment", + "help_text": "Type: `double`, example: `0.0`. Minimum fraction of overlapping bases in a read that is required for read assignment. Value should be within range [0,1]. 0 by default. Number of overlapping bases is counted from both reads if paired end. Both this option and \u0027--min_overlap\u0027 option need to be satisfied for read assignment.\n" } @@ -204,8 +204,8 @@ "frac_overlap_feature": { "type": "number", - "description": "Type: `double`, example: `0`. Minimum fraction of overlapping bases in a feature that is required for read assignment", - "help_text": "Type: `double`, example: `0`. Minimum fraction of overlapping bases in a feature that is required for read assignment. Value should be within range [0,1]. 0 by default.\n" + "description": "Type: `double`, example: `0.0`. Minimum fraction of overlapping bases in a feature that is required for read assignment", + "help_text": "Type: `double`, example: `0.0`. Minimum fraction of overlapping bases in a feature that is required for read assignment. Value should be within range [0,1]. 0 by default.\n" } @@ -573,8 +573,8 @@ "detailed_results": { "type": "string", - "description": "Type: `file`, default: `$id.$key.detailed_results.detailed_results`, example: `detailed_results/`. Directory to save the detailed assignment results", - "help_text": "Type: `file`, default: `$id.$key.detailed_results.detailed_results`, example: `detailed_results/`. Directory to save the detailed assignment results. Use `--detailed_results_format` to determine the format of the detailed results.\n" + "description": "Type: `file`, default: `$id.$key.detailed_results.detailed_results`, example: `detailed_results`. Directory to save the detailed assignment results", + "help_text": "Type: `file`, default: `$id.$key.detailed_results.detailed_results`, example: `detailed_results`. Directory to save the detailed assignment results. Use `--detailed_results_format` to determine the format of the detailed results.\n" , "default": "$id.$key.detailed_results.detailed_results" } diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/.config.vsh.yaml similarity index 98% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/.config.vsh.yaml index 6064c5b..8fdae94 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/.config.vsh.yaml @@ -1,5 +1,5 @@ name: "gffread" -version: "main" +version: "0.2.0" authors: - name: "Emma Rousseau" roles: @@ -668,7 +668,7 @@ engines: id: "docker" image: "quay.io/biocontainers/gffread:0.12.7--hdcf5f25_3" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -684,22 +684,22 @@ build_info: engine: "docker|native" output: "target/nextflow/gffread" executable: "target/nextflow/gffread/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/main.nf similarity index 99% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/main.nf index dea2d52..4fa0e80 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/main.nf @@ -1,8 +1,8 @@ -// gffread main +// gffread 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2802,7 +2808,7 @@ meta = [ "resources_dir": moduleDir.toRealPath().normalize(), "config": processConfig(readJsonBlob('''{ "name" : "gffread", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Emma Rousseau", @@ -3578,7 +3584,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/gffread:0.12.7--hdcf5f25_3", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3599,22 +3605,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/gffread", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3931,7 +3937,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -4062,7 +4072,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -4070,8 +4081,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -4108,6 +4119,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -4119,10 +4131,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -4207,7 +4218,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/gffread", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/nextflow.config index a32d649..1860658 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'gffread' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Validate, filter, convert and perform various other operations on GFF files.' author = 'Emma Rousseau' } diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/gffread/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/.config.vsh.yaml similarity index 94% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/.config.vsh.yaml index fcf4762..245ef5c 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/.config.vsh.yaml @@ -1,5 +1,19 @@ name: "multiqc" -version: "v0.1.0" +version: "0.2.0" +authors: +- name: "Dorien Roosen" + roles: + - "author" + - "maintainer" + info: + links: + email: "dorien@data-intuitive.com" + github: "dorien-er" + linkedin: "dorien-roosen" + organizations: + - name: "Data Intuitive" + href: "https://www.data-intuitive.com" + role: "Data Scientist" argument_groups: - name: "Input" arguments: @@ -63,39 +77,43 @@ argument_groups: description: "Use only these module" info: null example: - - "fastqc,cutadapt" + - "fastqc" + - "cutadapt" required: false direction: "input" multiple: true - multiple_sep: "," + multiple_sep: ";" - type: "string" name: "--exclude_modules" description: "Do not use only these modules" info: null example: - - "fastqc,cutadapt" + - "fastqc" + - "cutadapt" required: false direction: "input" multiple: true - multiple_sep: "," + multiple_sep: ";" - type: "string" name: "--ignore_analysis" info: null example: - - "run_one/*,run_two/*" + - "run_one/*" + - "run_two/*" required: false direction: "input" multiple: true - multiple_sep: "," + multiple_sep: ";" - type: "string" name: "--ignore_samples" info: null example: - - "sample_1*,sample_3*" + - "sample_1*" + - "sample_3*" required: false direction: "input" multiple: true - multiple_sep: "," + multiple_sep: ";" - type: "boolean_true" name: "--ignore_symlinks" description: "Ignore symlinked directories and files" @@ -415,7 +433,7 @@ engines: id: "docker" image: "quay.io/biocontainers/multiqc:1.21--pyhdfd78af_0" target_registry: "images.viash-hub.com" - target_tag: "v0.1.0" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -437,22 +455,22 @@ build_info: engine: "docker|native" output: "target/nextflow/multiqc" executable: "target/nextflow/multiqc/main.nf" - viash_version: "0.9.0-RC6" - git_commit: "b84b29747d0635f2ac83ea63b496be9a9edb6724" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "v0.1.0" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC6" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/main.nf similarity index 97% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/main.nf index d7f771d..7e0282b 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/main.nf @@ -1,13 +1,16 @@ -// multiqc v0.1.0 +// multiqc 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC6 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such // files, or include a separate license file detailing the licenses of all included // files. +// +// Component authors: +// * Dorien Roosen (author, maintainer) //////////////////////////// // VDSL3 helper functions // @@ -760,8 +763,11 @@ def runEach(Map args) { def fromState_ = args.fromState def toState_ = args.toState def filter_ = args.filter + def runIf_ = args.runIf def id_ = args.id + assert !runIf_ || runIf_ instanceof Closure: "runEach: must pass a Closure to runIf." + workflow runEachWf { take: input_ch main: @@ -783,7 +789,20 @@ def runEach(Map args) { [new_id] + tup.drop(1) } : filter_ch - def data_ch = id_ch | map{tup -> + def chPassthrough = null + def chRun = null + if (runIf_) { + def idRunIfBranch = id_ch.branch{ tup -> + run: runIf_(tup[0], tup[1], comp_) + passthrough: true + } + chPassthrough = idRunIfBranch.passthrough + chRun = idRunIfBranch.run + } else { + chRun = id_ch + chPassthrough = Channel.empty() + } + def data_ch = chRun | map{tup -> def new_data = tup[1] if (fromState_ instanceof Map) { new_data = fromState_.collectEntries{ key0, key1 -> @@ -821,8 +840,11 @@ def runEach(Map args) { [tup[0], new_state] + tup.drop(3) } : out_ch + + def return_ch = post_ch + | concat(chPassthrough) - post_ch + return_ch } // mix all results @@ -1598,8 +1620,8 @@ def findStates(Map params, Map config) { // construct renameMap if (args.rename_keys) { def renameMap = args.rename_keys.collectEntries{renameString -> - def split = renameString.split(";") - assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey,newKey:oldKey'" + def split = renameString.split(":") + assert split.size() == 2: "Argument 'rename_keys' should be of the form 'newKey:oldKey', or 'newKey:oldKey;newKey:oldKey' in case of multiple values" split } @@ -1709,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1780,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1822,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2626,30 +2654,31 @@ def workflowFactory(Map args, Map defaultWfArgs, Map meta) { tuple } - def chModifiedFiltered = workflowArgs.filter ? - chModified | filter{workflowArgs.filter(it)} : - chModified def chRun = null def chPassthrough = null if (workflowArgs.runIf) { - def runIfBranch = chModifiedFiltered.branch{ tup -> + def runIfBranch = chModified.branch{ tup -> run: workflowArgs.runIf(tup[0], tup[1]) passthrough: true } chRun = runIfBranch.run chPassthrough = runIfBranch.passthrough } else { - chRun = chModifiedFiltered + chRun = chModified chPassthrough = Channel.empty() } + def chRunFiltered = workflowArgs.filter ? + chRun | filter{workflowArgs.filter(it)} : + chRun + def chArgs = workflowArgs.fromState ? - chRun | map{ + chRunFiltered | map{ def new_data = workflowArgs.fromState(it.take(2)) [it[0], new_data] } : - chRun | map {tup -> tup.take(2)} + chRunFiltered | map {tup -> tup.take(2)} // fill in defaults def chArgsWithDefaults = chArgs @@ -2720,7 +2749,7 @@ def workflowFactory(Map args, Map defaultWfArgs, Map meta) { // | view{"chInitialOutput: ${it.take(3)}"} // join the output [prev_id, new_id, output] with the previous state [prev_id, state, ...] - def chNewState = safeJoin(chInitialOutput, chModifiedFiltered, key_) + def chNewState = safeJoin(chInitialOutput, chRunFiltered, key_) // input tuple format: [join_id, id, output, prev_state, ...] // output tuple format: [join_id, id, new_state, ...] | map{ tup -> @@ -2779,7 +2808,30 @@ meta = [ "resources_dir": moduleDir.toRealPath().normalize(), "config": processConfig(readJsonBlob('''{ "name" : "multiqc", - "version" : "v0.1.0", + "version" : "0.2.0", + "authors" : [ + { + "name" : "Dorien Roosen", + "roles" : [ + "author", + "maintainer" + ], + "info" : { + "links" : { + "email" : "dorien@data-intuitive.com", + "github" : "dorien-er", + "linkedin" : "dorien-roosen" + }, + "organizations" : [ + { + "name" : "Data Intuitive", + "href" : "https://www.data-intuitive.com", + "role" : "Data Scientist" + } + ] + } + } + ], "argument_groups" : [ { "name" : "Input", @@ -2855,46 +2907,50 @@ meta = [ "name" : "--include_modules", "description" : "Use only these module", "example" : [ - "fastqc,cutadapt" + "fastqc", + "cutadapt" ], "required" : false, "direction" : "input", "multiple" : true, - "multiple_sep" : "," + "multiple_sep" : ";" }, { "type" : "string", "name" : "--exclude_modules", "description" : "Do not use only these modules", "example" : [ - "fastqc,cutadapt" + "fastqc", + "cutadapt" ], "required" : false, "direction" : "input", "multiple" : true, - "multiple_sep" : "," + "multiple_sep" : ";" }, { "type" : "string", "name" : "--ignore_analysis", "example" : [ - "run_one/*,run_two/*" + "run_one/*", + "run_two/*" ], "required" : false, "direction" : "input", "multiple" : true, - "multiple_sep" : "," + "multiple_sep" : ";" }, { "type" : "string", "name" : "--ignore_samples", "example" : [ - "sample_1*,sample_3*" + "sample_1*", + "sample_3*" ], "required" : false, "direction" : "input", "multiple" : true, - "multiple_sep" : "," + "multiple_sep" : ";" }, { "type" : "boolean_true", @@ -3279,7 +3335,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/multiqc:1.21--pyhdfd78af_0", "target_registry" : "images.viash-hub.com", - "target_tag" : "v0.1.0", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3309,22 +3365,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/multiqc", - "viash_version" : "0.9.0-RC6", - "git_commit" : "b84b29747d0635f2ac83ea63b496be9a9edb6724", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "v0.1.0", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC6", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3411,26 +3467,32 @@ $( if [ ! -z ${VIASH_META_MEMORY_PIB+x} ]; then echo "${VIASH_META_MEMORY_PIB}" #!/bin/bash # disable flags -[[ "\\$par_ignore_symlinks" == "false" ]] && unset par_ignore_symlinks -[[ "\\$par_dirs" == "false" ]] && unset par_dirs -[[ "\\$par_full_names" == "false" ]] && unset par_full_names -[[ "\\$par_fn_as_s_name" == "false" ]] && unset par_fn_as_s_name -[[ "\\$par_profile_runtime" == "false" ]] && unset par_profile_runtime -[[ "\\$par_verbose" == "false" ]] && unset par_verbose -[[ "\\$par_quiet" == "false" ]] && unset par_quiet -[[ "\\$par_strict" == "false" ]] && unset par_strict -[[ "\\$par_development" == "false" ]] && unset par_development -[[ "\\$par_require_logs" == "false" ]] && unset par_require_logs -[[ "\\$par_no_megaqc_upload" == "false" ]] && unset par_no_megaqc_upload -[[ "\\$par_no_ansi" == "false" ]] && unset par_no_ansi -[[ "\\$par_flat" == "false" ]] && unset par_flat -[[ "\\$par_interactive" == "false" ]] && unset par_interactive -[[ "\\$par_static_plot_export" == "false" ]] && unset par_static_plot_export -[[ "\\$par_data_dir" == "false" ]] && unset par_data_dir -[[ "\\$par_no_data_dir" == "false" ]] && unset par_no_data_dir -[[ "\\$par_zip_data_dir" == "false" ]] && unset par_zip_data_dir -[[ "\\$par_pdf" == "false" ]] && unset par_pdf +unset_if_false=( + par_ignore_symlinks + par_dirs + par_full_names + par_fn_as_s_name + par_profile_runtime + par_verbose + par_quiet + par_strict + par_development + par_require_logs + par_no_megaqc_upload + par_no_ansi + par_flat + par_interactive + par_static_plot_export + par_data_dir + par_no_data_dir + par_zip_data_dir + par_pdf +) +for par in \\${unset_if_false[@]}; do + test_val="\\${!par}" + [[ "\\$test_val" == "false" ]] && unset \\$par +done # handle inputs out_dir=\\$(dirname "\\$par_output_report") @@ -3448,7 +3510,7 @@ IFS=";" read -ra inputs <<< \\$par_input if [[ -n "\\$par_include_modules" ]]; then include_modules="" - IFS="," read -ra incl_modules <<< \\$par_include_modules + IFS=";" read -ra incl_modules <<< \\$par_include_modules for i in "\\${incl_modules[@]}"; do include_modules+="--include \\$i " done @@ -3457,7 +3519,7 @@ fi if [[ -n "\\$par_exclude_modules" ]]; then exclude_modules="" - IFS="," read -ra excl_modules <<< \\$par_exclude_modules + IFS=";" read -ra excl_modules <<< \\$par_exclude_modules for i in "\\${excl_modules[@]}"; do exclude_modules+="--exclude \\$i" done @@ -3466,7 +3528,7 @@ fi if [[ -n "\\$par_ignore_analysis" ]]; then ignore="" - IFS="," read -ra ignore_analysis <<< \\$par_ignore_analysis + IFS=";" read -ra ignore_analysis <<< \\$par_ignore_analysis for i in "\\${ignore_analysis[@]}"; do ignore+="--ignore \\$i " done @@ -3475,7 +3537,7 @@ fi if [[ -n "\\$par_ignore_samples" ]]; then ignore_samples="" - IFS="," read -ra ign_samples <<< \\$par_ignore_samples + IFS=";" read -ra ign_samples <<< \\$par_ignore_samples for i in "\\${ign_samples[@]}"; do ignore_samples+="--ignore-samples \\$i" done @@ -3618,7 +3680,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3749,7 +3815,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3757,8 +3824,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3795,6 +3862,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3806,10 +3874,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -3894,7 +3961,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/multiqc", - "tag" : "v0.1.0" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/nextflow.config similarity index 98% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/nextflow.config index 2443ee9..2fe3a6a 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/nextflow.config @@ -2,8 +2,9 @@ manifest { name = 'multiqc' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'v0.1.0' + version = '0.2.0' description = 'MultiQC aggregates results from bioinformatics analyses across many samples into a single report.\nIt searches a given directory for analysis logs and compiles a HTML report. It\'s a general use tool, perfect for summarising the output from numerous bioinformatics tools.\n' + author = 'Dorien Roosen' } process.container = 'nextflow/bash:latest' diff --git a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/nextflow_schema.json similarity index 96% rename from target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/nextflow_schema.json index daab1d2..5f3f25e 100644 --- a/target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/nextflow_schema.json +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/nextflow_schema.json @@ -17,8 +17,8 @@ "input": { "type": "string", - "description": "Type: List of `file`, required, example: `data/results/`, multiple_sep: `\":\"`. File paths to be searched for analysis results to be included in the report", - "help_text": "Type: List of `file`, required, example: `data/results/`, multiple_sep: `\":\"`. File paths to be searched for analysis results to be included in the report.\n" + "description": "Type: List of `file`, required, example: `data/results`, multiple_sep: `\";\"`. File paths to be searched for analysis results to be included in the report", + "help_text": "Type: List of `file`, required, example: `data/results`, multiple_sep: `\";\"`. File paths to be searched for analysis results to be included in the report.\n" } @@ -80,8 +80,8 @@ "include_modules": { "type": "string", - "description": "Type: List of `string`, example: `fastqc,cutadapt`, multiple_sep: `\",\"`. Use only these module", - "help_text": "Type: List of `string`, example: `fastqc,cutadapt`, multiple_sep: `\",\"`. Use only these module" + "description": "Type: List of `string`, example: `fastqc;cutadapt`, multiple_sep: `\";\"`. Use only these module", + "help_text": "Type: List of `string`, example: `fastqc;cutadapt`, multiple_sep: `\";\"`. Use only these module" } @@ -90,8 +90,8 @@ "exclude_modules": { "type": "string", - "description": "Type: List of `string`, example: `fastqc,cutadapt`, multiple_sep: `\",\"`. Do not use only these modules", - "help_text": "Type: List of `string`, example: `fastqc,cutadapt`, multiple_sep: `\",\"`. Do not use only these modules" + "description": "Type: List of `string`, example: `fastqc;cutadapt`, multiple_sep: `\";\"`. Do not use only these modules", + "help_text": "Type: List of `string`, example: `fastqc;cutadapt`, multiple_sep: `\";\"`. Do not use only these modules" } @@ -100,8 +100,8 @@ "ignore_analysis": { "type": "string", - "description": "Type: List of `string`, example: `run_one/*,run_two/*`, multiple_sep: `\",\"`. ", - "help_text": "Type: List of `string`, example: `run_one/*,run_two/*`, multiple_sep: `\",\"`. " + "description": "Type: List of `string`, example: `run_one/*;run_two/*`, multiple_sep: `\";\"`. ", + "help_text": "Type: List of `string`, example: `run_one/*;run_two/*`, multiple_sep: `\";\"`. " } @@ -110,8 +110,8 @@ "ignore_samples": { "type": "string", - "description": "Type: List of `string`, example: `sample_1*,sample_3*`, multiple_sep: `\",\"`. ", - "help_text": "Type: List of `string`, example: `sample_1*,sample_3*`, multiple_sep: `\",\"`. " + "description": "Type: List of `string`, example: `sample_1*;sample_3*`, multiple_sep: `\";\"`. ", + "help_text": "Type: List of `string`, example: `sample_1*;sample_3*`, multiple_sep: `\";\"`. " } diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/.config.vsh.yaml similarity index 98% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/.config.vsh.yaml index f4f7298..76883ee 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "rsem_prepare_reference" namespace: "rsem" -version: "main" +version: "0.2.0" authors: - name: "Sai Nirmayi Yasa" roles: @@ -352,7 +352,7 @@ engines: id: "docker" image: "ubuntu:22.04" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "apt" @@ -415,22 +415,22 @@ build_info: engine: "docker|native" output: "target/nextflow/rsem/rsem_prepare_reference" executable: "target/nextflow/rsem/rsem_prepare_reference/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/main.nf similarity index 98% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/main.nf index d669258..3fd602e 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/main.nf @@ -1,8 +1,8 @@ -// rsem_prepare_reference main +// rsem_prepare_reference 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2803,7 +2809,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "rsem_prepare_reference", "namespace" : "rsem", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Sai Nirmayi Yasa", @@ -3179,7 +3185,7 @@ meta = [ "id" : "docker", "image" : "ubuntu:22.04", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3238,22 +3244,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/rsem/rsem_prepare_reference", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3444,7 +3450,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3575,7 +3585,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3583,8 +3594,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3621,6 +3632,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3632,10 +3644,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -3720,7 +3731,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/rsem/rsem_prepare_reference", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/nextflow.config index 35bb747..0214611 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'rsem/rsem_prepare_reference' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'RSEM is a software package for estimating gene and isoform expression levels from RNA-Seq data. This component prepares transcript references for RSEM.\n' author = 'Sai Nirmayi Yasa' } diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/.config.vsh.yaml similarity index 97% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/.config.vsh.yaml index 60b94ef..f4b3e35 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "salmon_index" namespace: "salmon" -version: "main" +version: "0.2.0" authors: - name: "Sai Nirmayi Yasa" roles: @@ -260,7 +260,7 @@ engines: id: "docker" image: "quay.io/biocontainers/salmon:1.10.2--hecfa306_0" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -276,22 +276,22 @@ build_info: engine: "docker|native" output: "target/nextflow/salmon/salmon_index" executable: "target/nextflow/salmon/salmon_index/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/main.nf similarity index 98% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/main.nf index 867edaf..6633d73 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/main.nf @@ -1,8 +1,8 @@ -// salmon_index main +// salmon_index 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2803,7 +2809,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "salmon_index", "namespace" : "salmon", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Sai Nirmayi Yasa", @@ -3101,7 +3107,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/salmon:1.10.2--hecfa306_0", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3122,22 +3128,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/salmon/salmon_index", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3332,7 +3338,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3463,7 +3473,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3471,8 +3482,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3509,6 +3520,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3520,10 +3532,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -3608,7 +3619,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/salmon/salmon_index", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/nextflow.config index 8367d96..d036a17 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'salmon/salmon_index' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Salmon is a tool for wicked-fast transcript quantification from RNA-seq data. It can either make use of pre-computed alignments (in the form of a SAM/BAM file) to the transcripts rather than the raw reads, or can be run in the mapping-based mode. This component creates a salmon index for the transcriptome to use Salmon in the mapping-based mode. It is generally recommend that you build a decoy-aware transcriptome file. This is done using the entire genome of the organism as the decoy sequence by concatenating the genome to the end of the transcriptome to be indexed and populating the decoys.txt file with the chromosome names.\n' author = 'Sai Nirmayi Yasa' } diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/.config.vsh.yaml similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/.config.vsh.yaml index af05d4d..2e84d6c 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "salmon_quant" namespace: "salmon" -version: "main" +version: "0.2.0" authors: - name: "Sai Nirmayi Yasa" roles: @@ -1156,7 +1156,7 @@ engines: id: "docker" image: "quay.io/biocontainers/salmon:1.10.2--hecfa306_0" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -1172,22 +1172,22 @@ build_info: engine: "docker|native" output: "target/nextflow/salmon/salmon_quant" executable: "target/nextflow/salmon/salmon_quant/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/main.nf similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/main.nf index b7bb2d7..4c41526 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/main.nf @@ -1,8 +1,8 @@ -// salmon_quant main +// salmon_quant 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2803,7 +2809,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "salmon_quant", "namespace" : "salmon", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Sai Nirmayi Yasa", @@ -3936,7 +3942,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/salmon:1.10.2--hecfa306_0", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3957,22 +3963,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/salmon/salmon_quant", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -4347,7 +4353,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -4478,7 +4488,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -4486,8 +4497,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -4524,6 +4535,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -4535,10 +4547,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -4623,7 +4634,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/salmon/salmon_quant", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/nextflow.config index d33d7b4..3425279 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'salmon/salmon_quant' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Salmon is a tool for wicked-fast transcript quantification from RNA-seq data. It can either make use of pre-computed alignments (in the form of a SAM/BAM file) to the transcripts rather than the raw reads, or can be run in the mapping-based mode. \n' author = 'Sai Nirmayi Yasa' } diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/.config.vsh.yaml similarity index 95% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/.config.vsh.yaml index d4c6bd5..85c50ea 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "samtools_flagstat" namespace: "samtools" -version: "main" +version: "0.2.0" authors: - name: "Emma Rousseau" roles: @@ -155,7 +155,7 @@ engines: id: "docker" image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -172,22 +172,22 @@ build_info: engine: "docker|native" output: "target/nextflow/samtools/samtools_flagstat" executable: "target/nextflow/samtools/samtools_flagstat/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/main.nf similarity index 98% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/main.nf index 3061bbb..4e8d8e9 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/main.nf @@ -1,8 +1,8 @@ -// samtools_flagstat main +// samtools_flagstat 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2803,7 +2809,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "samtools_flagstat", "namespace" : "samtools", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Emma Rousseau", @@ -3000,7 +3006,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3021,22 +3027,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/samtools/samtools_flagstat", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3176,7 +3182,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3307,7 +3317,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3315,8 +3326,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3353,6 +3364,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3364,10 +3376,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -3452,7 +3463,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/samtools/samtools_flagstat", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/nextflow.config index f027ef2..17007f7 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'samtools/samtools_flagstat' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Counts the number of alignments in SAM/BAM/CRAM files for each FLAG type.' author = 'Emma Rousseau' } diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/.config.vsh.yaml similarity index 96% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/.config.vsh.yaml index 0e7547c..4874329 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "samtools_idxstats" namespace: "samtools" -version: "main" +version: "0.2.0" authors: - name: "Emma Rousseau" roles: @@ -165,7 +165,7 @@ engines: id: "docker" image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -182,22 +182,22 @@ build_info: engine: "docker|native" output: "target/nextflow/samtools/samtools_idxstats" executable: "target/nextflow/samtools/samtools_idxstats/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/main.nf similarity index 98% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/main.nf index 4a851db..15ce949 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/main.nf @@ -1,8 +1,8 @@ -// samtools_idxstats main +// samtools_idxstats 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2803,7 +2809,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "samtools_idxstats", "namespace" : "samtools", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Emma Rousseau", @@ -3012,7 +3018,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3033,22 +3039,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/samtools/samtools_idxstats", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3186,7 +3192,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3317,7 +3327,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3325,8 +3336,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3363,6 +3374,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3374,10 +3386,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -3462,7 +3473,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/samtools/samtools_idxstats", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/nextflow.config index 0300443..c53aaa5 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'samtools/samtools_idxstats' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Reports alignment summary statistics for a BAM file.' author = 'Emma Rousseau' } diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/.config.vsh.yaml similarity index 96% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/.config.vsh.yaml index cb9eef1..36e112f 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "samtools_index" namespace: "samtools" -version: "main" +version: "0.2.0" authors: - name: "Emma Rousseau" roles: @@ -171,7 +171,7 @@ engines: id: "docker" image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -188,22 +188,22 @@ build_info: engine: "docker|native" output: "target/nextflow/samtools/samtools_index" executable: "target/nextflow/samtools/samtools_index/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/main.nf similarity index 98% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/main.nf index 19d2c42..d8b6b24 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/main.nf @@ -1,8 +1,8 @@ -// samtools_index main +// samtools_index 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2803,7 +2809,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "samtools_index", "namespace" : "samtools", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Emma Rousseau", @@ -3025,7 +3031,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3046,22 +3052,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/samtools/samtools_index", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3210,7 +3216,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3341,7 +3351,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3349,8 +3360,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3387,6 +3398,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3398,10 +3410,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -3486,7 +3497,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/samtools/samtools_index", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/nextflow.config index 285e5af..0ce06ea 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'samtools/samtools_index' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Index SAM/BAM/CRAM files.' author = 'Emma Rousseau' } diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/.config.vsh.yaml similarity index 97% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/.config.vsh.yaml index 150af0d..a37efeb 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "samtools_sort" namespace: "samtools" -version: "main" +version: "0.2.0" authors: - name: "Emma Rousseau" roles: @@ -314,7 +314,7 @@ engines: id: "docker" image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -331,22 +331,22 @@ build_info: engine: "docker|native" output: "target/nextflow/samtools/samtools_sort" executable: "target/nextflow/samtools/samtools_sort/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/main.nf similarity index 98% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/main.nf index 8cf7081..7525e02 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/main.nf @@ -1,8 +1,8 @@ -// samtools_sort main +// samtools_sort 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2803,7 +2809,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "samtools_sort", "namespace" : "samtools", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Emma Rousseau", @@ -3197,7 +3203,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3218,22 +3224,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/samtools/samtools_sort", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3430,7 +3436,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3561,7 +3571,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3569,8 +3580,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3607,6 +3618,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3618,10 +3630,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -3706,7 +3717,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/samtools/samtools_sort", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/nextflow.config index 7a38662..ea64c8c 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'samtools/samtools_sort' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Sort SAM/BAM/CRAM file.' author = 'Emma Rousseau' } diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/.config.vsh.yaml similarity index 97% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/.config.vsh.yaml index 9fae13b..ee7dd48 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "samtools_stats" namespace: "samtools" -version: "main" +version: "0.2.0" authors: - name: "Emma Rousseau" roles: @@ -383,7 +383,7 @@ engines: id: "docker" image: "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -400,22 +400,22 @@ build_info: engine: "docker|native" output: "target/nextflow/samtools/samtools_stats" executable: "target/nextflow/samtools/samtools_stats/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/main.nf similarity index 98% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/main.nf index 090d03d..1f8595f 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/main.nf @@ -1,8 +1,8 @@ -// samtools_stats main +// samtools_stats 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2803,7 +2809,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "samtools_stats", "namespace" : "samtools", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Emma Rousseau", @@ -3267,7 +3273,7 @@ meta = [ "id" : "docker", "image" : "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_1", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3288,22 +3294,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/samtools/samtools_stats", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3492,7 +3498,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3623,7 +3633,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3631,8 +3642,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3669,6 +3680,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3680,10 +3692,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -3768,7 +3779,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/samtools/samtools_stats", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/nextflow.config index 733a57c..8b99052 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'samtools/samtools_stats' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Reports alignment summary statistics for a BAM file.' author = 'Emma Rousseau' } diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/.config.vsh.yaml similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/.config.vsh.yaml index 59bddff..caf1001 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "star_align_reads" namespace: "star" -version: "main" +version: "0.2.0" authors: - name: "Angela Oliveira Pisco" roles: @@ -2624,7 +2624,7 @@ engines: id: "docker" image: "python:3.12-slim" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "apt" @@ -2662,22 +2662,22 @@ build_info: engine: "docker|native" output: "target/nextflow/star/star_align_reads" executable: "target/nextflow/star/star_align_reads/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/main.nf similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/main.nf index ca3ade9..a205d8a 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/main.nf @@ -1,8 +1,8 @@ -// star_align_reads main +// star_align_reads 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1732,7 +1732,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1803,7 +1805,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1845,7 +1849,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2804,7 +2810,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "star_align_reads", "namespace" : "star", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Angela Oliveira Pisco", @@ -4564,7 +4570,7 @@ meta = [ { "type" : "integer", "name" : "--seed_split_min", - "description" : "min length of the seed sequen''' + '''ces split by Ns or mate gap", + "description" : "min length of the seed seque''' + '''nces split by Ns or mate gap", "info" : { "orig_name" : "--seedSplitMin" }, @@ -5888,7 +5894,7 @@ meta = [ "id" : "docker", "image" : "python:3.12-slim", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -5936,22 +5942,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/star/star_align_reads", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -6384,7 +6390,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -6515,7 +6525,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -6523,8 +6534,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -6561,6 +6572,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -6572,10 +6584,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -6660,7 +6671,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/star/star_align_reads", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/nextflow.config index aaf983d..9406e86 100644 --- a/target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'star/star_align_reads' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Aligns reads to a reference genome using STAR.\n' author = 'Angela Oliveira Pisco, Robrecht Cannoodt' } diff --git a/target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/.config.vsh.yaml b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/.config.vsh.yaml similarity index 97% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/.config.vsh.yaml rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/.config.vsh.yaml index ef682f4..0280082 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/.config.vsh.yaml @@ -1,6 +1,6 @@ name: "star_genome_generate" namespace: "star" -version: "main" +version: "0.2.0" authors: - name: "Sai Nirmayi Yasa" roles: @@ -305,7 +305,7 @@ engines: id: "docker" image: "ubuntu:22.04" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "0.2.0" namespace_separator: "/" setup: - type: "docker" @@ -332,22 +332,22 @@ build_info: engine: "docker|native" output: "target/nextflow/star/star_genome_generate" executable: "target/nextflow/star/star_genome_generate/main.nf" - viash_version: "0.9.0-RC7" - git_commit: "bd8ca889d13784c5a7502bb977c6659fe420d973" + viash_version: "0.9.0" + git_commit: "5526b3e939030daea80595fa98387b469329bbfa" git_remote: "https://github.com/viash-hub/biobox" package_config: name: "biobox" - version: "main" + version: "0.2.0" description: "A collection of bioinformatics tools for working with sequence data.\n" info: null - viash_version: "0.9.0-RC7" + viash_version: "0.9.0" source: "src" target: "target" config_mods: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := '0.2.0'" keywords: - "bioinformatics" - "modules" diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/main.nf b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/main.nf similarity index 98% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/main.nf rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/main.nf index ae22459..6861801 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/main.nf +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/main.nf @@ -1,8 +1,8 @@ -// star_genome_generate main +// star_genome_generate 0.2.0 // -// This wrapper script is auto-generated by viash 0.9.0-RC7 and is thus a -// derivative work thereof. This software comes with ABSOLUTELY NO WARRANTY from -// Data Intuitive. +// This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative +// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data +// Intuitive. // // The component may contain files which fall under a different license. The // authors of this component should specify the license in the header of such @@ -1731,7 +1731,9 @@ def publishStates(Map args) { def yamlFilename = yamlTemplate_ .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) // TODO: do the pathnames in state_ match up with the outputFilenames_? @@ -1802,7 +1804,9 @@ def publishStatesByConfig(Map args) { def yamlTemplate = params.containsKey("output_state") ? params.output_state : '$id.$key.state.yaml' def yamlFilename = yamlTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) def yamlDir = java.nio.file.Paths.get(yamlFilename).getParent() // the processed state is a list of [key, value, inputPath, outputFilename] tuples, where @@ -1844,7 +1848,9 @@ def publishStatesByConfig(Map args) { // instantiate the template def filename = filenameTemplate .replaceAll('\\$id', id_) + .replaceAll('\\$\\{id\\}', id_) .replaceAll('\\$key', key_) + .replaceAll('\\$\\{key\\}', key_) if (par.multiple) { // if the parameter is multiple: true, the filename // should contain a wildcard '*' that is replaced with @@ -2803,7 +2809,7 @@ meta = [ "config": processConfig(readJsonBlob('''{ "name" : "star_genome_generate", "namespace" : "star", - "version" : "main", + "version" : "0.2.0", "authors" : [ { "name" : "Sai Nirmayi Yasa", @@ -3157,7 +3163,7 @@ meta = [ "id" : "docker", "image" : "ubuntu:22.04", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "0.2.0", "namespace_separator" : "/", "setup" : [ { @@ -3188,22 +3194,22 @@ meta = [ "runner" : "nextflow", "engine" : "docker|native", "output" : "target/nextflow/star/star_genome_generate", - "viash_version" : "0.9.0-RC7", - "git_commit" : "bd8ca889d13784c5a7502bb977c6659fe420d973", + "viash_version" : "0.9.0", + "git_commit" : "5526b3e939030daea80595fa98387b469329bbfa", "git_remote" : "https://github.com/viash-hub/biobox" }, "package_config" : { "name" : "biobox", - "version" : "main", + "version" : "0.2.0", "description" : "A collection of bioinformatics tools for working with sequence data.\n", - "viash_version" : "0.9.0-RC7", + "viash_version" : "0.9.0", "source" : "src", "target" : "target", "config_mods" : [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := '0.2.0'" ], "keywords" : [ "bioinformatics", @@ -3375,7 +3381,11 @@ def vdsl3WorkflowFactory(Map args, Map meta, String rawScript) { val = val.join(par.multiple_sep) } if (par.direction == "output" && par.type == "file") { - val = val.replaceAll('\\$id', id).replaceAll('\\$key', key) + val = val + .replaceAll('\\$id', id) + .replaceAll('\\$\\{id\\}', id) + .replaceAll('\\$key', key) + .replaceAll('\\$\\{key\\}', key) } [parName, val] } @@ -3506,7 +3516,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def createParentStr = meta.config.allArguments .findAll { it.type == "file" && it.direction == "output" && it.create_parent } .collect { par -> - "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent \\\"\" + (args[\"${par.plainName}\"] instanceof String ? args[\"${par.plainName}\"] : args[\"${par.plainName}\"].join('\" \"')) + \"\\\"\" : \"\" }" + def contents = "args[\"${par.plainName}\"] instanceof List ? args[\"${par.plainName}\"].join('\" \"') : args[\"${par.plainName}\"]" + "\${ args.containsKey(\"${par.plainName}\") ? \"mkdir_parent '\" + escapeText(${contents}) + \"'\" : \"\" }" } .join("\n") @@ -3514,8 +3525,8 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def inputFileExports = meta.config.allArguments .findAll { it.type == "file" && it.direction.toLowerCase() == "input" } .collect { par -> - def viash_par_contents = "(viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName})" - "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}=\\\"\" + ${viash_par_contents} + \"\\\"\"}" + def contents = "viash_par_${par.plainName} instanceof List ? viash_par_${par.plainName}.join(\"${par.multiple_sep}\") : viash_par_${par.plainName}" + "\n\${viash_par_${par.plainName}.empty ? \"\" : \"export VIASH_PAR_${par.plainName.toUpperCase()}='\" + escapeText(${contents}) + \"'\"}" } // NOTE: if using docker, use /tmp instead of tmpDir! @@ -3552,6 +3563,7 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { def procStr = """nextflow.enable.dsl=2 | + |def escapeText = { s -> s.toString().replaceAll("'", "'\\\"'\\\"'") } |process $procKey {$drctvStrs |input: | tuple val(id)$inputPaths, val(args), path(resourcesDir, stageAs: ".viash_meta_resources") @@ -3563,10 +3575,9 @@ def _vdsl3ProcessFactory(Map workflowArgs, Map meta, String rawScript) { |$stub |\"\"\" |script:$assertStr - |def escapeText = { s -> s.toString().replaceAll('([`"])', '\\\\\\\\\$1') } |def parInject = args | .findAll{key, value -> value != null} - | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}=\\\"\${escapeText(value)}\\\""} + | .collect{key, value -> "export VIASH_PAR_\${key.toUpperCase()}='\${escapeText(value)}'"} | .join("\\n") |\"\"\" |# meta exports @@ -3651,7 +3662,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/biobox/star/star_genome_generate", - "tag" : "main" + "tag" : "0.2.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/nextflow.config b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/nextflow.config rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/nextflow.config index e3ae601..19e916a 100644 --- a/target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/nextflow.config +++ b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'star/star_genome_generate' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = '0.2.0' description = 'Create index for STAR\n' author = 'Sai Nirmayi Yasa' } diff --git a/target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/nextflow_schema.json b/target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/nextflow_schema.json rename to target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/nextflow_schema.json diff --git a/target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/.config.vsh.yaml b/target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/.config.vsh.yaml similarity index 96% rename from target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/.config.vsh.yaml rename to target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/.config.vsh.yaml index 1ba3cbf..9c48fed 100644 --- a/target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/.config.vsh.yaml +++ b/target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/.config.vsh.yaml @@ -1,5 +1,5 @@ name: "untar" -version: "main" +version: "v0.1.0" argument_groups: - name: "Input arguments" arguments: @@ -129,7 +129,7 @@ engines: id: "docker" image: "debian:stable-slim" target_registry: "images.viash-hub.com" - target_tag: "main" + target_tag: "v0.1.0" namespace_separator: "/" setup: - type: "apt" @@ -147,11 +147,11 @@ build_info: output: "target/nextflow/untar" executable: "target/nextflow/untar/main.nf" viash_version: "0.9.0" - git_commit: "3fecd6a214295592c65d5ef03b8b7115867f8752" + git_commit: "3143dd6e4c2c3107f79639fe8602d92f3141ad82" git_remote: "https://github.com/viash-hub/craftbox" package_config: name: "craftbox" - version: "main" + version: "v0.1.0" description: "A collection of custom-tailored scripts and applied tools.\n" info: null viash_version: "0.9.0" @@ -161,7 +161,7 @@ package_config: - ".requirements.commands := ['ps']\n" - ".engines += { type: \"native\" }" - ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'" - - ".engines[.type == 'docker'].target_tag := 'main'" + - ".engines[.type == 'docker'].target_tag := 'v0.1.0'" keywords: - "scripts" - "custom" diff --git a/target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/main.nf b/target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/main.nf similarity index 99% rename from target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/main.nf rename to target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/main.nf index 9d6caf7..48fe97b 100644 --- a/target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/main.nf +++ b/target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/main.nf @@ -1,4 +1,4 @@ -// untar main +// untar v0.1.0 // // This wrapper script is auto-generated by viash 0.9.0 and is thus a derivative // work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data @@ -2805,7 +2805,7 @@ meta = [ "resources_dir": moduleDir.toRealPath().normalize(), "config": processConfig(readJsonBlob('''{ "name" : "untar", - "version" : "main", + "version" : "v0.1.0", "argument_groups" : [ { "name" : "Input arguments", @@ -2965,7 +2965,7 @@ meta = [ "id" : "docker", "image" : "debian:stable-slim", "target_registry" : "images.viash-hub.com", - "target_tag" : "main", + "target_tag" : "v0.1.0", "namespace_separator" : "/", "setup" : [ { @@ -2988,12 +2988,12 @@ meta = [ "engine" : "docker|native", "output" : "target/nextflow/untar", "viash_version" : "0.9.0", - "git_commit" : "3fecd6a214295592c65d5ef03b8b7115867f8752", + "git_commit" : "3143dd6e4c2c3107f79639fe8602d92f3141ad82", "git_remote" : "https://github.com/viash-hub/craftbox" }, "package_config" : { "name" : "craftbox", - "version" : "main", + "version" : "v0.1.0", "description" : "A collection of custom-tailored scripts and applied tools.\n", "viash_version" : "0.9.0", "source" : "src", @@ -3002,7 +3002,7 @@ meta = [ ".requirements.commands := ['ps']\n", ".engines += { type: \\"native\\" }", ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'", - ".engines[.type == 'docker'].target_tag := 'main'" + ".engines[.type == 'docker'].target_tag := 'v0.1.0'" ], "keywords" : [ "scripts", @@ -3454,7 +3454,7 @@ meta["defaults"] = [ "container" : { "registry" : "images.viash-hub.com", "image" : "vsh/craftbox/untar", - "tag" : "main" + "tag" : "v0.1.0" }, "tag" : "$id" }'''), diff --git a/target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/nextflow.config b/target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/nextflow.config similarity index 99% rename from target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/nextflow.config rename to target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/nextflow.config index 51d7ab4..b023cf6 100644 --- a/target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/nextflow.config +++ b/target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/nextflow.config @@ -2,7 +2,7 @@ manifest { name = 'untar' mainScript = 'main.nf' nextflowVersion = '!>=20.12.1-edge' - version = 'main' + version = 'v0.1.0' description = 'Unpack a .tar file. When the contents of the .tar file is just a single directory,\nput the contents of the directory into the output folder instead of that directory.\n' } diff --git a/target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/nextflow_schema.json b/target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/nextflow_schema.json similarity index 100% rename from target/dependencies/vsh/vsh/craftbox/main/nextflow/untar/nextflow_schema.json rename to target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/nextflow_schema.json diff --git a/target/executable/bbmap_bbsplit/.config.vsh.yaml b/target/executable/bbmap_bbsplit/.config.vsh.yaml index eecbda0..3fae3fe 100644 --- a/target/executable/bbmap_bbsplit/.config.vsh.yaml +++ b/target/executable/bbmap_bbsplit/.config.vsh.yaml @@ -229,7 +229,7 @@ build_info: output: "target/executable/bbmap_bbsplit" executable: "target/executable/bbmap_bbsplit/bbmap_bbsplit" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/bbmap_bbsplit/bbmap_bbsplit b/target/executable/bbmap_bbsplit/bbmap_bbsplit index 91f102f..031080b 100755 --- a/target/executable/bbmap_bbsplit/bbmap_bbsplit +++ b/target/executable/bbmap_bbsplit/bbmap_bbsplit @@ -506,9 +506,9 @@ tar xzf BBMap_39.01.tar.gz && \ cp -r bbmap/* /usr/local/bin LABEL org.opencontainers.image.description="Companion container for running component bbmap_bbsplit" -LABEL org.opencontainers.image.created="2024-09-13T06:49:49Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:10Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/bedtools_genomecov/.config.vsh.yaml b/target/executable/bedtools_genomecov/.config.vsh.yaml index bb3ca54..9f59ebe 100644 --- a/target/executable/bedtools_genomecov/.config.vsh.yaml +++ b/target/executable/bedtools_genomecov/.config.vsh.yaml @@ -169,7 +169,7 @@ build_info: output: "target/executable/bedtools_genomecov" executable: "target/executable/bedtools_genomecov/bedtools_genomecov" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/bedtools_genomecov/bedtools_genomecov b/target/executable/bedtools_genomecov/bedtools_genomecov index 0bd32bc..3f50d69 100755 --- a/target/executable/bedtools_genomecov/bedtools_genomecov +++ b/target/executable/bedtools_genomecov/bedtools_genomecov @@ -481,9 +481,9 @@ mv bedtools.static /usr/local/bin/bedtools && \ chmod a+x /usr/local/bin/bedtools LABEL org.opencontainers.image.description="Companion container for running component bedtools_genomecov" -LABEL org.opencontainers.image.created="2024-09-13T06:49:49Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:11Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/cat_additional_fasta/.config.vsh.yaml b/target/executable/cat_additional_fasta/.config.vsh.yaml index a5ea420..3bd1930 100644 --- a/target/executable/cat_additional_fasta/.config.vsh.yaml +++ b/target/executable/cat_additional_fasta/.config.vsh.yaml @@ -173,7 +173,7 @@ build_info: output: "target/executable/cat_additional_fasta" executable: "target/executable/cat_additional_fasta/cat_additional_fasta" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/cat_additional_fasta/cat_additional_fasta b/target/executable/cat_additional_fasta/cat_additional_fasta index 1b05115..c822cb2 100755 --- a/target/executable/cat_additional_fasta/cat_additional_fasta +++ b/target/executable/cat_additional_fasta/cat_additional_fasta @@ -480,9 +480,9 @@ function ViashDockerfile { FROM python:latest ENTRYPOINT [] LABEL org.opencontainers.image.description="Companion container for running component cat_additional_fasta" -LABEL org.opencontainers.image.created="2024-09-13T06:49:57Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:17Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/cat_fastq/.config.vsh.yaml b/target/executable/cat_fastq/.config.vsh.yaml index 26d5464..601beec 100644 --- a/target/executable/cat_fastq/.config.vsh.yaml +++ b/target/executable/cat_fastq/.config.vsh.yaml @@ -160,7 +160,7 @@ build_info: output: "target/executable/cat_fastq" executable: "target/executable/cat_fastq/cat_fastq" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/cat_fastq/cat_fastq b/target/executable/cat_fastq/cat_fastq index efabf0c..2a56225 100755 --- a/target/executable/cat_fastq/cat_fastq +++ b/target/executable/cat_fastq/cat_fastq @@ -472,9 +472,9 @@ function ViashDockerfile { FROM ubuntu:22.04 ENTRYPOINT [] LABEL org.opencontainers.image.description="Companion container for running component cat_fastq" -LABEL org.opencontainers.image.created="2024-09-13T06:49:57Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:18Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/deseq2_qc/.config.vsh.yaml b/target/executable/deseq2_qc/.config.vsh.yaml index 7962560..4321520 100644 --- a/target/executable/deseq2_qc/.config.vsh.yaml +++ b/target/executable/deseq2_qc/.config.vsh.yaml @@ -228,7 +228,7 @@ build_info: output: "target/executable/deseq2_qc" executable: "target/executable/deseq2_qc/deseq2_qc" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/deseq2_qc/deseq2_qc b/target/executable/deseq2_qc/deseq2_qc index 5d0f6ca..832e0f3 100755 --- a/target/executable/deseq2_qc/deseq2_qc +++ b/target/executable/deseq2_qc/deseq2_qc @@ -502,9 +502,9 @@ RUN Rscript -e 'if (!requireNamespace("remotes", quietly = TRUE)) install.packag Rscript -e 'remotes::install_url(c("https://cran.r-project.org/src/contrib/Archive/matrixStats/matrixStats_1.1.0.tar.gz"), repos = "https://cran.rstudio.com")' LABEL org.opencontainers.image.description="Companion container for running component deseq2_qc" -LABEL org.opencontainers.image.created="2024-09-13T06:50:07Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:30Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/dupradar/.config.vsh.yaml b/target/executable/dupradar/.config.vsh.yaml index 400bcd1..a8b8891 100644 --- a/target/executable/dupradar/.config.vsh.yaml +++ b/target/executable/dupradar/.config.vsh.yaml @@ -257,7 +257,7 @@ build_info: output: "target/executable/dupradar" executable: "target/executable/dupradar/dupradar" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/dupradar/dupradar b/target/executable/dupradar/dupradar index 940706d..a918549 100755 --- a/target/executable/dupradar/dupradar +++ b/target/executable/dupradar/dupradar @@ -520,9 +520,9 @@ RUN Rscript -e 'if (!requireNamespace("BiocManager", quietly = TRUE)) install.pa Rscript -e 'if (!requireNamespace("dupRadar", quietly = TRUE)) BiocManager::install("dupRadar")' LABEL org.opencontainers.image.description="Companion container for running component dupradar" -LABEL org.opencontainers.image.created="2024-09-13T06:49:58Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:19Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/fastqc/.config.vsh.yaml b/target/executable/fastqc/.config.vsh.yaml index 191d7a9..03a38f3 100644 --- a/target/executable/fastqc/.config.vsh.yaml +++ b/target/executable/fastqc/.config.vsh.yaml @@ -189,7 +189,7 @@ build_info: output: "target/executable/fastqc" executable: "target/executable/fastqc/fastqc" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/fastqc/fastqc b/target/executable/fastqc/fastqc index ea51514..b49ba34 100755 --- a/target/executable/fastqc/fastqc +++ b/target/executable/fastqc/fastqc @@ -490,9 +490,9 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* LABEL org.opencontainers.image.description="Companion container for running component fastqc" -LABEL org.opencontainers.image.created="2024-09-13T06:49:50Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:12Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/fq_subsample/.config.vsh.yaml b/target/executable/fq_subsample/.config.vsh.yaml index 8ad2083..efd46c8 100644 --- a/target/executable/fq_subsample/.config.vsh.yaml +++ b/target/executable/fq_subsample/.config.vsh.yaml @@ -168,7 +168,7 @@ build_info: output: "target/executable/fq_subsample" executable: "target/executable/fq_subsample/fq_subsample" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/fq_subsample/fq_subsample b/target/executable/fq_subsample/fq_subsample index 6d32b96..20a34c5 100755 --- a/target/executable/fq_subsample/fq_subsample +++ b/target/executable/fq_subsample/fq_subsample @@ -485,9 +485,9 @@ cargo install --locked --path . && \ mv /usr/local/fq/target/release/fq /usr/local/bin/ LABEL org.opencontainers.image.description="Companion container for running component fq_subsample" -LABEL org.opencontainers.image.created="2024-09-13T06:49:50Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:11Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/getchromsizes/.config.vsh.yaml b/target/executable/getchromsizes/.config.vsh.yaml index 92ce767..4e7500c 100644 --- a/target/executable/getchromsizes/.config.vsh.yaml +++ b/target/executable/getchromsizes/.config.vsh.yaml @@ -158,7 +158,7 @@ build_info: output: "target/executable/getchromsizes" executable: "target/executable/getchromsizes/getchromsizes" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/getchromsizes/getchromsizes b/target/executable/getchromsizes/getchromsizes index e189ec5..8eb748c 100755 --- a/target/executable/getchromsizes/getchromsizes +++ b/target/executable/getchromsizes/getchromsizes @@ -480,9 +480,9 @@ make && \ make install LABEL org.opencontainers.image.description="Companion container for running component getchromsizes" -LABEL org.opencontainers.image.created="2024-09-13T06:49:51Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:12Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/gtf2bed/.config.vsh.yaml b/target/executable/gtf2bed/.config.vsh.yaml index 131fe32..7bda08c 100644 --- a/target/executable/gtf2bed/.config.vsh.yaml +++ b/target/executable/gtf2bed/.config.vsh.yaml @@ -136,7 +136,7 @@ build_info: output: "target/executable/gtf2bed" executable: "target/executable/gtf2bed/gtf2bed" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/gtf2bed/gtf2bed b/target/executable/gtf2bed/gtf2bed index 8d7b1ed..ac61544 100755 --- a/target/executable/gtf2bed/gtf2bed +++ b/target/executable/gtf2bed/gtf2bed @@ -466,9 +466,9 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* LABEL org.opencontainers.image.description="Companion container for running component gtf2bed" -LABEL org.opencontainers.image.created="2024-09-13T06:50:02Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:25Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/gtf_filter/.config.vsh.yaml b/target/executable/gtf_filter/.config.vsh.yaml index 94fa482..3af4651 100644 --- a/target/executable/gtf_filter/.config.vsh.yaml +++ b/target/executable/gtf_filter/.config.vsh.yaml @@ -146,7 +146,7 @@ build_info: output: "target/executable/gtf_filter" executable: "target/executable/gtf_filter/gtf_filter" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/gtf_filter/gtf_filter b/target/executable/gtf_filter/gtf_filter index 3c9a20b..6b1aba6 100755 --- a/target/executable/gtf_filter/gtf_filter +++ b/target/executable/gtf_filter/gtf_filter @@ -470,9 +470,9 @@ function ViashDockerfile { FROM python:latest ENTRYPOINT [] LABEL org.opencontainers.image.description="Companion container for running component gtf_filter" -LABEL org.opencontainers.image.created="2024-09-13T06:50:05Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:28Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/gunzip/.config.vsh.yaml b/target/executable/gunzip/.config.vsh.yaml index 3245b59..36ed156 100644 --- a/target/executable/gunzip/.config.vsh.yaml +++ b/target/executable/gunzip/.config.vsh.yaml @@ -135,7 +135,7 @@ build_info: output: "target/executable/gunzip" executable: "target/executable/gunzip/gunzip" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/gunzip/gunzip b/target/executable/gunzip/gunzip index 162172c..a86c9ac 100755 --- a/target/executable/gunzip/gunzip +++ b/target/executable/gunzip/gunzip @@ -466,9 +466,9 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* LABEL org.opencontainers.image.description="Companion container for running component gunzip" -LABEL org.opencontainers.image.created="2024-09-13T06:49:51Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:12Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/kallisto/kallisto_index/.config.vsh.yaml b/target/executable/kallisto/kallisto_index/.config.vsh.yaml index ca23907..3f1c9ac 100644 --- a/target/executable/kallisto/kallisto_index/.config.vsh.yaml +++ b/target/executable/kallisto/kallisto_index/.config.vsh.yaml @@ -146,7 +146,7 @@ build_info: output: "target/executable/kallisto/kallisto_index" executable: "target/executable/kallisto/kallisto_index/kallisto_index" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/kallisto/kallisto_index/kallisto_index b/target/executable/kallisto/kallisto_index/kallisto_index index d711f00..0ba7108 100755 --- a/target/executable/kallisto/kallisto_index/kallisto_index +++ b/target/executable/kallisto/kallisto_index/kallisto_index @@ -471,9 +471,9 @@ tar -xzf kallisto_linux-v0.50.1.tar.gz && \ mv kallisto/kallisto /usr/local/bin/ LABEL org.opencontainers.image.description="Companion container for running component kallisto kallisto_index" -LABEL org.opencontainers.image.created="2024-09-13T06:50:04Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:27Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/kallisto/kallisto_quant/.config.vsh.yaml b/target/executable/kallisto/kallisto_quant/.config.vsh.yaml index 6cf75f8..bea6c21 100644 --- a/target/executable/kallisto/kallisto_quant/.config.vsh.yaml +++ b/target/executable/kallisto/kallisto_quant/.config.vsh.yaml @@ -244,7 +244,7 @@ build_info: output: "target/executable/kallisto/kallisto_quant" executable: "target/executable/kallisto/kallisto_quant/kallisto_quant" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/kallisto/kallisto_quant/kallisto_quant b/target/executable/kallisto/kallisto_quant/kallisto_quant index c8d6573..c7b17ed 100755 --- a/target/executable/kallisto/kallisto_quant/kallisto_quant +++ b/target/executable/kallisto/kallisto_quant/kallisto_quant @@ -515,9 +515,9 @@ tar -xzf kallisto_linux-v0.50.1.tar.gz && \ mv kallisto/kallisto /usr/local/bin/ LABEL org.opencontainers.image.description="Companion container for running component kallisto kallisto_quant" -LABEL org.opencontainers.image.created="2024-09-13T06:50:03Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:26Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/multiqc_custom_biotype/.config.vsh.yaml b/target/executable/multiqc_custom_biotype/.config.vsh.yaml index ac2a28b..efb6502 100644 --- a/target/executable/multiqc_custom_biotype/.config.vsh.yaml +++ b/target/executable/multiqc_custom_biotype/.config.vsh.yaml @@ -161,7 +161,7 @@ build_info: output: "target/executable/multiqc_custom_biotype" executable: "target/executable/multiqc_custom_biotype/multiqc_custom_biotype" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/multiqc_custom_biotype/multiqc_custom_biotype b/target/executable/multiqc_custom_biotype/multiqc_custom_biotype index d64a0e5..1037e37 100755 --- a/target/executable/multiqc_custom_biotype/multiqc_custom_biotype +++ b/target/executable/multiqc_custom_biotype/multiqc_custom_biotype @@ -481,9 +481,9 @@ RUN apt-get update && \ RUN pip install --upgrade pip LABEL org.opencontainers.image.description="Companion container for running component multiqc_custom_biotype" -LABEL org.opencontainers.image.created="2024-09-13T06:49:58Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:20Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/picard_markduplicates/.config.vsh.yaml b/target/executable/picard_markduplicates/.config.vsh.yaml index 99e75c7..3dbcbf3 100644 --- a/target/executable/picard_markduplicates/.config.vsh.yaml +++ b/target/executable/picard_markduplicates/.config.vsh.yaml @@ -198,7 +198,7 @@ build_info: output: "target/executable/picard_markduplicates" executable: "target/executable/picard_markduplicates/picard_markduplicates" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/picard_markduplicates/picard_markduplicates b/target/executable/picard_markduplicates/picard_markduplicates index 000b9a8..bc1e96f 100755 --- a/target/executable/picard_markduplicates/picard_markduplicates +++ b/target/executable/picard_markduplicates/picard_markduplicates @@ -494,9 +494,9 @@ wget --no-check-certificate https://github.com/broadinstitute/picard/releases/do mv picard.jar /usr/local/bin LABEL org.opencontainers.image.description="Companion container for running component picard_markduplicates" -LABEL org.opencontainers.image.created="2024-09-13T06:50:06Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:29Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/prepare_multiqc_input/.config.vsh.yaml b/target/executable/prepare_multiqc_input/.config.vsh.yaml index 24bb763..cf39721 100644 --- a/target/executable/prepare_multiqc_input/.config.vsh.yaml +++ b/target/executable/prepare_multiqc_input/.config.vsh.yaml @@ -400,7 +400,7 @@ build_info: output: "target/executable/prepare_multiqc_input" executable: "target/executable/prepare_multiqc_input/prepare_multiqc_input" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/prepare_multiqc_input/prepare_multiqc_input b/target/executable/prepare_multiqc_input/prepare_multiqc_input index d1204a6..9bfff9f 100755 --- a/target/executable/prepare_multiqc_input/prepare_multiqc_input +++ b/target/executable/prepare_multiqc_input/prepare_multiqc_input @@ -557,9 +557,9 @@ function ViashDockerfile { FROM ubuntu:22.04 ENTRYPOINT [] LABEL org.opencontainers.image.description="Companion container for running component prepare_multiqc_input" -LABEL org.opencontainers.image.created="2024-09-13T06:50:01Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:24Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/preprocess_transcripts_fasta/.config.vsh.yaml b/target/executable/preprocess_transcripts_fasta/.config.vsh.yaml index d451ca9..ef6a1af 100644 --- a/target/executable/preprocess_transcripts_fasta/.config.vsh.yaml +++ b/target/executable/preprocess_transcripts_fasta/.config.vsh.yaml @@ -129,7 +129,7 @@ build_info: output: "target/executable/preprocess_transcripts_fasta" executable: "target/executable/preprocess_transcripts_fasta/preprocess_transcripts_fasta" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/preprocess_transcripts_fasta/preprocess_transcripts_fasta b/target/executable/preprocess_transcripts_fasta/preprocess_transcripts_fasta index f673dae..7509d8b 100755 --- a/target/executable/preprocess_transcripts_fasta/preprocess_transcripts_fasta +++ b/target/executable/preprocess_transcripts_fasta/preprocess_transcripts_fasta @@ -462,9 +462,9 @@ function ViashDockerfile { FROM ubuntu:22.04 ENTRYPOINT [] LABEL org.opencontainers.image.description="Companion container for running component preprocess_transcripts_fasta" -LABEL org.opencontainers.image.created="2024-09-13T06:50:01Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:23Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/preseq_lcextrap/.config.vsh.yaml b/target/executable/preseq_lcextrap/.config.vsh.yaml index 22ee3e7..de7d3a3 100644 --- a/target/executable/preseq_lcextrap/.config.vsh.yaml +++ b/target/executable/preseq_lcextrap/.config.vsh.yaml @@ -182,7 +182,7 @@ build_info: output: "target/executable/preseq_lcextrap" executable: "target/executable/preseq_lcextrap/preseq_lcextrap" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/preseq_lcextrap/preseq_lcextrap b/target/executable/preseq_lcextrap/preseq_lcextrap index a480f2a..27068d1 100755 --- a/target/executable/preseq_lcextrap/preseq_lcextrap +++ b/target/executable/preseq_lcextrap/preseq_lcextrap @@ -495,9 +495,9 @@ mkdir build && cd build && \ make && make install && make HAVE_HTSLIB=1 all LABEL org.opencontainers.image.description="Companion container for running component preseq_lcextrap" -LABEL org.opencontainers.image.created="2024-09-13T06:49:52Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:12Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/qualimap/.config.vsh.yaml b/target/executable/qualimap/.config.vsh.yaml index c034d5d..092f429 100644 --- a/target/executable/qualimap/.config.vsh.yaml +++ b/target/executable/qualimap/.config.vsh.yaml @@ -262,7 +262,7 @@ build_info: output: "target/executable/qualimap" executable: "target/executable/qualimap/qualimap" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/qualimap/qualimap b/target/executable/qualimap/qualimap index 218879e..c057e77 100755 --- a/target/executable/qualimap/qualimap +++ b/target/executable/qualimap/qualimap @@ -537,9 +537,9 @@ RUN Rscript -e 'if (!requireNamespace("remotes", quietly = TRUE)) install.packag Rscript -e 'remotes::install_cran(c("optparse"), repos = "https://cran.rstudio.com")' LABEL org.opencontainers.image.description="Companion container for running component qualimap" -LABEL org.opencontainers.image.created="2024-09-13T06:49:50Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:11Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rsem/rsem_calculate_expression/.config.vsh.yaml b/target/executable/rsem/rsem_calculate_expression/.config.vsh.yaml index ac5b5e2..a910e0e 100644 --- a/target/executable/rsem/rsem_calculate_expression/.config.vsh.yaml +++ b/target/executable/rsem/rsem_calculate_expression/.config.vsh.yaml @@ -299,7 +299,7 @@ build_info: output: "target/executable/rsem/rsem_calculate_expression" executable: "target/executable/rsem/rsem_calculate_expression/rsem_calculate_expression" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rsem/rsem_calculate_expression/rsem_calculate_expression b/target/executable/rsem/rsem_calculate_expression/rsem_calculate_expression index 1923fa5..caa65a5 100755 --- a/target/executable/rsem/rsem_calculate_expression/rsem_calculate_expression +++ b/target/executable/rsem/rsem_calculate_expression/rsem_calculate_expression @@ -545,9 +545,9 @@ echo 'export PATH=$PATH:/usr/local/bin' >> ~/.bashrc && \ /bin/bash -c "source /etc/profile && source ~/.bashrc && echo $PATH && which STAR" LABEL org.opencontainers.image.description="Companion container for running component rsem rsem_calculate_expression" -LABEL org.opencontainers.image.created="2024-09-13T06:50:03Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:26Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rsem/rsem_merge_counts/.config.vsh.yaml b/target/executable/rsem/rsem_merge_counts/.config.vsh.yaml index 4040ad5..8950881 100644 --- a/target/executable/rsem/rsem_merge_counts/.config.vsh.yaml +++ b/target/executable/rsem/rsem_merge_counts/.config.vsh.yaml @@ -193,7 +193,7 @@ build_info: output: "target/executable/rsem/rsem_merge_counts" executable: "target/executable/rsem/rsem_merge_counts/rsem_merge_counts" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rsem/rsem_merge_counts/rsem_merge_counts b/target/executable/rsem/rsem_merge_counts/rsem_merge_counts index 6b78715..fd8ad5f 100755 --- a/target/executable/rsem/rsem_merge_counts/rsem_merge_counts +++ b/target/executable/rsem/rsem_merge_counts/rsem_merge_counts @@ -490,9 +490,9 @@ function ViashDockerfile { FROM ubuntu:22.04 ENTRYPOINT [] LABEL org.opencontainers.image.description="Companion container for running component rsem rsem_merge_counts" -LABEL org.opencontainers.image.created="2024-09-13T06:50:03Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:26Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rseqc/rseqc_bamstat/.config.vsh.yaml b/target/executable/rseqc/rseqc_bamstat/.config.vsh.yaml index 0083b6f..28b499b 100644 --- a/target/executable/rseqc/rseqc_bamstat/.config.vsh.yaml +++ b/target/executable/rseqc/rseqc_bamstat/.config.vsh.yaml @@ -154,7 +154,7 @@ build_info: output: "target/executable/rseqc/rseqc_bamstat" executable: "target/executable/rseqc/rseqc_bamstat/rseqc_bamstat" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rseqc/rseqc_bamstat/rseqc_bamstat b/target/executable/rseqc/rseqc_bamstat/rseqc_bamstat index e624c4f..62c24b1 100755 --- a/target/executable/rseqc/rseqc_bamstat/rseqc_bamstat +++ b/target/executable/rseqc/rseqc_bamstat/rseqc_bamstat @@ -477,9 +477,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "RSeQC" LABEL org.opencontainers.image.description="Companion container for running component rseqc rseqc_bamstat" -LABEL org.opencontainers.image.created="2024-09-13T06:50:01Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:23Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rseqc/rseqc_inferexperiment/.config.vsh.yaml b/target/executable/rseqc/rseqc_inferexperiment/.config.vsh.yaml index 5a17e2c..0a0011d 100644 --- a/target/executable/rseqc/rseqc_inferexperiment/.config.vsh.yaml +++ b/target/executable/rseqc/rseqc_inferexperiment/.config.vsh.yaml @@ -177,7 +177,7 @@ build_info: output: "target/executable/rseqc/rseqc_inferexperiment" executable: "target/executable/rseqc/rseqc_inferexperiment/rseqc_inferexperiment" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rseqc/rseqc_inferexperiment/rseqc_inferexperiment b/target/executable/rseqc/rseqc_inferexperiment/rseqc_inferexperiment index cc48c47..8168042 100755 --- a/target/executable/rseqc/rseqc_inferexperiment/rseqc_inferexperiment +++ b/target/executable/rseqc/rseqc_inferexperiment/rseqc_inferexperiment @@ -487,9 +487,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "RSeQC" LABEL org.opencontainers.image.description="Companion container for running component rseqc rseqc_inferexperiment" -LABEL org.opencontainers.image.created="2024-09-13T06:49:59Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:20Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rseqc/rseqc_innerdistance/.config.vsh.yaml b/target/executable/rseqc/rseqc_innerdistance/.config.vsh.yaml index 7389a98..a9b70a3 100644 --- a/target/executable/rseqc/rseqc_innerdistance/.config.vsh.yaml +++ b/target/executable/rseqc/rseqc_innerdistance/.config.vsh.yaml @@ -263,7 +263,7 @@ build_info: output: "target/executable/rseqc/rseqc_innerdistance" executable: "target/executable/rseqc/rseqc_innerdistance/rseqc_innerdistance" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rseqc/rseqc_innerdistance/rseqc_innerdistance b/target/executable/rseqc/rseqc_innerdistance/rseqc_innerdistance index d418cdc..58cb253 100755 --- a/target/executable/rseqc/rseqc_innerdistance/rseqc_innerdistance +++ b/target/executable/rseqc/rseqc_innerdistance/rseqc_innerdistance @@ -529,9 +529,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "RSeQC" LABEL org.opencontainers.image.description="Companion container for running component rseqc rseqc_innerdistance" -LABEL org.opencontainers.image.created="2024-09-13T06:50:00Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:22Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rseqc/rseqc_junctionannotation/.config.vsh.yaml b/target/executable/rseqc/rseqc_junctionannotation/.config.vsh.yaml index e5b781e..ec7c9ea 100644 --- a/target/executable/rseqc/rseqc_junctionannotation/.config.vsh.yaml +++ b/target/executable/rseqc/rseqc_junctionannotation/.config.vsh.yaml @@ -251,7 +251,7 @@ build_info: output: "target/executable/rseqc/rseqc_junctionannotation" executable: "target/executable/rseqc/rseqc_junctionannotation/rseqc_junctionannotation" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rseqc/rseqc_junctionannotation/rseqc_junctionannotation b/target/executable/rseqc/rseqc_junctionannotation/rseqc_junctionannotation index 233a243..0694b61 100755 --- a/target/executable/rseqc/rseqc_junctionannotation/rseqc_junctionannotation +++ b/target/executable/rseqc/rseqc_junctionannotation/rseqc_junctionannotation @@ -519,9 +519,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "RSeQC" LABEL org.opencontainers.image.description="Companion container for running component rseqc rseqc_junctionannotation" -LABEL org.opencontainers.image.created="2024-09-13T06:50:00Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:22Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rseqc/rseqc_junctionsaturation/.config.vsh.yaml b/target/executable/rseqc/rseqc_junctionsaturation/.config.vsh.yaml index 2b7a908..b3cd479 100644 --- a/target/executable/rseqc/rseqc_junctionsaturation/.config.vsh.yaml +++ b/target/executable/rseqc/rseqc_junctionsaturation/.config.vsh.yaml @@ -240,7 +240,7 @@ build_info: output: "target/executable/rseqc/rseqc_junctionsaturation" executable: "target/executable/rseqc/rseqc_junctionsaturation/rseqc_junctionsaturation" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rseqc/rseqc_junctionsaturation/rseqc_junctionsaturation b/target/executable/rseqc/rseqc_junctionsaturation/rseqc_junctionsaturation index 4dc077b..a1742be 100755 --- a/target/executable/rseqc/rseqc_junctionsaturation/rseqc_junctionsaturation +++ b/target/executable/rseqc/rseqc_junctionsaturation/rseqc_junctionsaturation @@ -522,9 +522,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "RSeQC" LABEL org.opencontainers.image.description="Companion container for running component rseqc rseqc_junctionsaturation" -LABEL org.opencontainers.image.created="2024-09-13T06:50:00Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:21Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rseqc/rseqc_readdistribution/.config.vsh.yaml b/target/executable/rseqc/rseqc_readdistribution/.config.vsh.yaml index 87f6238..0c7498a 100644 --- a/target/executable/rseqc/rseqc_readdistribution/.config.vsh.yaml +++ b/target/executable/rseqc/rseqc_readdistribution/.config.vsh.yaml @@ -153,7 +153,7 @@ build_info: output: "target/executable/rseqc/rseqc_readdistribution" executable: "target/executable/rseqc/rseqc_readdistribution/rseqc_readdistribution" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rseqc/rseqc_readdistribution/rseqc_readdistribution b/target/executable/rseqc/rseqc_readdistribution/rseqc_readdistribution index 77df78c..c7c55eb 100755 --- a/target/executable/rseqc/rseqc_readdistribution/rseqc_readdistribution +++ b/target/executable/rseqc/rseqc_readdistribution/rseqc_readdistribution @@ -474,9 +474,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "RSeQC" LABEL org.opencontainers.image.description="Companion container for running component rseqc rseqc_readdistribution" -LABEL org.opencontainers.image.created="2024-09-13T06:50:01Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:23Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rseqc/rseqc_readduplication/.config.vsh.yaml b/target/executable/rseqc/rseqc_readduplication/.config.vsh.yaml index 3ff5703..e3c513d 100644 --- a/target/executable/rseqc/rseqc_readduplication/.config.vsh.yaml +++ b/target/executable/rseqc/rseqc_readduplication/.config.vsh.yaml @@ -202,7 +202,7 @@ build_info: output: "target/executable/rseqc/rseqc_readduplication" executable: "target/executable/rseqc/rseqc_readduplication/rseqc_readduplication" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rseqc/rseqc_readduplication/rseqc_readduplication b/target/executable/rseqc/rseqc_readduplication/rseqc_readduplication index cfae04e..6edeaaa 100755 --- a/target/executable/rseqc/rseqc_readduplication/rseqc_readduplication +++ b/target/executable/rseqc/rseqc_readduplication/rseqc_readduplication @@ -499,9 +499,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "RSeQC" LABEL org.opencontainers.image.description="Companion container for running component rseqc rseqc_readduplication" -LABEL org.opencontainers.image.created="2024-09-13T06:49:59Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:20Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/rseqc/rseqc_tin/.config.vsh.yaml b/target/executable/rseqc/rseqc_tin/.config.vsh.yaml index 25b21a2..26d3e5b 100644 --- a/target/executable/rseqc/rseqc_tin/.config.vsh.yaml +++ b/target/executable/rseqc/rseqc_tin/.config.vsh.yaml @@ -205,7 +205,7 @@ build_info: output: "target/executable/rseqc/rseqc_tin" executable: "target/executable/rseqc/rseqc_tin/rseqc_tin" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/rseqc/rseqc_tin/rseqc_tin b/target/executable/rseqc/rseqc_tin/rseqc_tin index 0df4528..844666e 100755 --- a/target/executable/rseqc/rseqc_tin/rseqc_tin +++ b/target/executable/rseqc/rseqc_tin/rseqc_tin @@ -501,9 +501,9 @@ RUN apt-get update && \ RUN pip3 install RSeQC LABEL org.opencontainers.image.description="Companion container for running component rseqc rseqc_tin" -LABEL org.opencontainers.image.created="2024-09-13T06:49:59Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:21Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/sortmerna/.config.vsh.yaml b/target/executable/sortmerna/.config.vsh.yaml index 39deffd..9385587 100644 --- a/target/executable/sortmerna/.config.vsh.yaml +++ b/target/executable/sortmerna/.config.vsh.yaml @@ -189,7 +189,7 @@ build_info: output: "target/executable/sortmerna" executable: "target/executable/sortmerna/sortmerna" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/sortmerna/sortmerna b/target/executable/sortmerna/sortmerna index 020b0af..a6f50cf 100755 --- a/target/executable/sortmerna/sortmerna +++ b/target/executable/sortmerna/sortmerna @@ -492,9 +492,9 @@ wget --no-check-certificate https://github.com/sortmerna/sortmerna/releases/down bash sortmerna-4.3.6-Linux.sh --skip-license LABEL org.opencontainers.image.description="Companion container for running component sortmerna" -LABEL org.opencontainers.image.created="2024-09-13T06:50:05Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:28Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/stringtie/.config.vsh.yaml b/target/executable/stringtie/.config.vsh.yaml index 927489b..36ec788 100644 --- a/target/executable/stringtie/.config.vsh.yaml +++ b/target/executable/stringtie/.config.vsh.yaml @@ -207,7 +207,7 @@ build_info: output: "target/executable/stringtie" executable: "target/executable/stringtie/stringtie" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/stringtie/stringtie b/target/executable/stringtie/stringtie index 44930fc..88d13dc 100755 --- a/target/executable/stringtie/stringtie +++ b/target/executable/stringtie/stringtie @@ -496,9 +496,9 @@ tar -xzf stringtie-2.2.1.Linux_x86_64.tar.gz && \ cp stringtie-2.2.1.Linux_x86_64/stringtie /usr/local/bin/ LABEL org.opencontainers.image.description="Companion container for running component stringtie" -LABEL org.opencontainers.image.created="2024-09-13T06:50:02Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:25Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/summarizedexperiment/.config.vsh.yaml b/target/executable/summarizedexperiment/.config.vsh.yaml index 58e00bd..f11cd7f 100644 --- a/target/executable/summarizedexperiment/.config.vsh.yaml +++ b/target/executable/summarizedexperiment/.config.vsh.yaml @@ -190,7 +190,7 @@ build_info: output: "target/executable/summarizedexperiment" executable: "target/executable/summarizedexperiment/summarizedexperiment" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/summarizedexperiment/summarizedexperiment b/target/executable/summarizedexperiment/summarizedexperiment index 7e11923..a4ee416 100755 --- a/target/executable/summarizedexperiment/summarizedexperiment +++ b/target/executable/summarizedexperiment/summarizedexperiment @@ -487,9 +487,9 @@ RUN Rscript -e 'if (!requireNamespace("BiocManager", quietly = TRUE)) install.pa Rscript -e 'if (!requireNamespace("tximeta", quietly = TRUE)) BiocManager::install("tximeta")' LABEL org.opencontainers.image.description="Companion container for running component summarizedexperiment" -LABEL org.opencontainers.image.created="2024-09-13T06:50:06Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:29Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/trimgalore/.config.vsh.yaml b/target/executable/trimgalore/.config.vsh.yaml index a2a42e1..f49b024 100644 --- a/target/executable/trimgalore/.config.vsh.yaml +++ b/target/executable/trimgalore/.config.vsh.yaml @@ -779,7 +779,7 @@ build_info: output: "target/executable/trimgalore" executable: "target/executable/trimgalore/trimgalore" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/trimgalore/trimgalore b/target/executable/trimgalore/trimgalore index d86e525..4ba0640 100755 --- a/target/executable/trimgalore/trimgalore +++ b/target/executable/trimgalore/trimgalore @@ -858,9 +858,9 @@ ENTRYPOINT [] RUN echo "TrimGalore: `trim_galore --version | sed -n 's/.*version\s\+\([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p'`" > /var/software_versions.txt LABEL org.opencontainers.image.description="Companion container for running component trimgalore" -LABEL org.opencontainers.image.created="2024-09-13T06:50:05Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:28Z" LABEL org.opencontainers.image.source="https://github.com/FelixKrueger/TrimGalore" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/tx2gene/.config.vsh.yaml b/target/executable/tx2gene/.config.vsh.yaml index c8d7f03..9c29f8f 100644 --- a/target/executable/tx2gene/.config.vsh.yaml +++ b/target/executable/tx2gene/.config.vsh.yaml @@ -183,7 +183,7 @@ build_info: output: "target/executable/tx2gene" executable: "target/executable/tx2gene/tx2gene" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/tx2gene/tx2gene b/target/executable/tx2gene/tx2gene index 3d1e0a5..17fc024 100755 --- a/target/executable/tx2gene/tx2gene +++ b/target/executable/tx2gene/tx2gene @@ -487,9 +487,9 @@ RUN apt-get update && \ RUN pip install --upgrade pip LABEL org.opencontainers.image.description="Companion container for running component tx2gene" -LABEL org.opencontainers.image.created="2024-09-13T06:50:02Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:24Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/tximport/.config.vsh.yaml b/target/executable/tximport/.config.vsh.yaml index a83bce7..b5a0420 100644 --- a/target/executable/tximport/.config.vsh.yaml +++ b/target/executable/tximport/.config.vsh.yaml @@ -238,7 +238,7 @@ build_info: output: "target/executable/tximport" executable: "target/executable/tximport/tximport" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/tximport/tximport b/target/executable/tximport/tximport index 180d28f..2a23bfd 100755 --- a/target/executable/tximport/tximport +++ b/target/executable/tximport/tximport @@ -508,9 +508,9 @@ RUN Rscript -e 'if (!requireNamespace("remotes", quietly = TRUE)) install.packag Rscript -e 'remotes::install_cran(c("jsonlite"), repos = "https://cran.rstudio.com")' LABEL org.opencontainers.image.description="Companion container for running component tximport" -LABEL org.opencontainers.image.created="2024-09-13T06:49:57Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:17Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/ucsc/bedclip/.config.vsh.yaml b/target/executable/ucsc/bedclip/.config.vsh.yaml index 111b190..dae5f3c 100644 --- a/target/executable/ucsc/bedclip/.config.vsh.yaml +++ b/target/executable/ucsc/bedclip/.config.vsh.yaml @@ -155,7 +155,7 @@ build_info: output: "target/executable/ucsc/bedclip" executable: "target/executable/ucsc/bedclip/bedclip" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/ucsc/bedclip/bedclip b/target/executable/ucsc/bedclip/bedclip index cb5ba79..d66243b 100755 --- a/target/executable/ucsc/bedclip/bedclip +++ b/target/executable/ucsc/bedclip/bedclip @@ -473,9 +473,9 @@ RUN apt-get update && \ RUN rsync -aP rsync://hgdownload.soe.ucsc.edu/genome/admin/exe/linux.x86_64/bedClip /usr/local/bin/ LABEL org.opencontainers.image.description="Companion container for running component ucsc bedclip" -LABEL org.opencontainers.image.created="2024-09-13T06:49:57Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:18Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/ucsc/bedgraphtobigwig/.config.vsh.yaml b/target/executable/ucsc/bedgraphtobigwig/.config.vsh.yaml index 77ecb32..255ada5 100644 --- a/target/executable/ucsc/bedgraphtobigwig/.config.vsh.yaml +++ b/target/executable/ucsc/bedgraphtobigwig/.config.vsh.yaml @@ -155,7 +155,7 @@ build_info: output: "target/executable/ucsc/bedgraphtobigwig" executable: "target/executable/ucsc/bedgraphtobigwig/bedgraphtobigwig" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/ucsc/bedgraphtobigwig/bedgraphtobigwig b/target/executable/ucsc/bedgraphtobigwig/bedgraphtobigwig index eec7c4a..ba2f940 100755 --- a/target/executable/ucsc/bedgraphtobigwig/bedgraphtobigwig +++ b/target/executable/ucsc/bedgraphtobigwig/bedgraphtobigwig @@ -473,9 +473,9 @@ RUN apt-get update && \ RUN rsync -aP rsync://hgdownload.soe.ucsc.edu/genome/admin/exe/linux.x86_64/bedGraphToBigWig /usr/local/bin/ LABEL org.opencontainers.image.description="Companion container for running component ucsc bedgraphtobigwig" -LABEL org.opencontainers.image.created="2024-09-13T06:49:58Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:18Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/umitools/umitools_dedup/.config.vsh.yaml b/target/executable/umitools/umitools_dedup/.config.vsh.yaml index b09b630..25edc91 100644 --- a/target/executable/umitools/umitools_dedup/.config.vsh.yaml +++ b/target/executable/umitools/umitools_dedup/.config.vsh.yaml @@ -186,7 +186,7 @@ build_info: output: "target/executable/umitools/umitools_dedup" executable: "target/executable/umitools/umitools_dedup/umitools_dedup" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/umitools/umitools_dedup/umitools_dedup b/target/executable/umitools/umitools_dedup/umitools_dedup index e407953..cfd1758 100755 --- a/target/executable/umitools/umitools_dedup/umitools_dedup +++ b/target/executable/umitools/umitools_dedup/umitools_dedup @@ -489,9 +489,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "umi_tools" LABEL org.opencontainers.image.description="Companion container for running component umitools umitools_dedup" -LABEL org.opencontainers.image.created="2024-09-13T06:50:04Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:27Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/umitools/umitools_extract/.config.vsh.yaml b/target/executable/umitools/umitools_extract/.config.vsh.yaml index 3c6c74e..909dedc 100644 --- a/target/executable/umitools/umitools_extract/.config.vsh.yaml +++ b/target/executable/umitools/umitools_extract/.config.vsh.yaml @@ -244,7 +244,7 @@ build_info: output: "target/executable/umitools/umitools_extract" executable: "target/executable/umitools/umitools_extract/umitools_extract" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/umitools/umitools_extract/umitools_extract b/target/executable/umitools/umitools_extract/umitools_extract index ccd112d..b4c1699 100755 --- a/target/executable/umitools/umitools_extract/umitools_extract +++ b/target/executable/umitools/umitools_extract/umitools_extract @@ -521,9 +521,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "umi_tools" LABEL org.opencontainers.image.description="Companion container for running component umitools umitools_extract" -LABEL org.opencontainers.image.created="2024-09-13T06:50:04Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:27Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/umitools_prepareforquant/.config.vsh.yaml b/target/executable/umitools_prepareforquant/.config.vsh.yaml index c5ee919..5ee07e8 100644 --- a/target/executable/umitools_prepareforquant/.config.vsh.yaml +++ b/target/executable/umitools_prepareforquant/.config.vsh.yaml @@ -147,7 +147,7 @@ build_info: output: "target/executable/umitools_prepareforquant" executable: "target/executable/umitools_prepareforquant/umitools_prepareforquant" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/executable/umitools_prepareforquant/umitools_prepareforquant b/target/executable/umitools_prepareforquant/umitools_prepareforquant index 0c210be..7cf0e3e 100755 --- a/target/executable/umitools_prepareforquant/umitools_prepareforquant +++ b/target/executable/umitools_prepareforquant/umitools_prepareforquant @@ -473,9 +473,9 @@ RUN pip install --upgrade pip && \ pip install --upgrade --no-cache-dir "umi_tools" "pysam" LABEL org.opencontainers.image.description="Companion container for running component umitools_prepareforquant" -LABEL org.opencontainers.image.created="2024-09-13T06:50:06Z" +LABEL org.opencontainers.image.created="2024-09-13T10:19:29Z" LABEL org.opencontainers.image.source="https://github.com/viash-hub/rnaseq" -LABEL org.opencontainers.image.revision="1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" +LABEL org.opencontainers.image.revision="cb9b32883494c48f394213551a82e9103f2e620c" LABEL org.opencontainers.image.version="main" VIASHDOCKER diff --git a/target/executable/workflows/genome_alignment_and_quant/.config.vsh.yaml b/target/executable/workflows/genome_alignment_and_quant/.config.vsh.yaml index cd88763..18ba3d5 100644 --- a/target/executable/workflows/genome_alignment_and_quant/.config.vsh.yaml +++ b/target/executable/workflows/genome_alignment_and_quant/.config.vsh.yaml @@ -398,26 +398,32 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_sort" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_index" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_stats" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_flagstat" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_idxstats" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "umitools/umitools_dedup" repository: type: "local" @@ -428,6 +434,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "rsem/rsem_calculate_expression" repository: type: "local" @@ -435,6 +442,7 @@ repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -510,18 +518,18 @@ build_info: output: "target/executable/workflows/genome_alignment_and_quant" executable: "target/executable/workflows/genome_alignment_and_quant/genome_alignment_and_quant" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - - "target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats" - "target/nextflow/umitools/umitools_dedup" - "target/nextflow/umitools_prepareforquant" - - "target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant" - "target/nextflow/rsem/rsem_calculate_expression" package_config: version: "main" diff --git a/target/executable/workflows/genome_alignment_and_quant/genome_alignment_and_quant b/target/executable/workflows/genome_alignment_and_quant/genome_alignment_and_quant index 37c1908..2a744f0 100755 --- a/target/executable/workflows/genome_alignment_and_quant/genome_alignment_and_quant +++ b/target/executable/workflows/genome_alignment_and_quant/genome_alignment_and_quant @@ -1169,13 +1169,13 @@ fi VIASH_DEP_UMITOOLS_UMITOOLS_DEDUP="$VIASH_META_RESOURCES_DIR/../../../nextflow/umitools/umitools_dedup/main.nf" VIASH_DEP_UMITOOLS_PREPAREFORQUANT="$VIASH_META_RESOURCES_DIR/../../../nextflow/umitools_prepareforquant/main.nf" VIASH_DEP_RSEM_RSEM_CALCULATE_EXPRESSION="$VIASH_META_RESOURCES_DIR/../../../nextflow/rsem/rsem_calculate_expression/main.nf" -VIASH_DEP_STAR_STAR_ALIGN_READS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_SORT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_INDEX="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_STATS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_FLAGSTAT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_IDXSTATS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/main.nf" -VIASH_DEP_SALMON_SALMON_QUANT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/main.nf" +VIASH_DEP_STAR_STAR_ALIGN_READS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_SORT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_INDEX="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_STATS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_FLAGSTAT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_IDXSTATS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/main.nf" +VIASH_DEP_SALMON_SALMON_QUANT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/main.nf" ViashDebug "Running command: $(echo $VIASH_CMD)" cat << VIASHEOF | eval $VIASH_CMD diff --git a/target/executable/workflows/merge_quant_results/.config.vsh.yaml b/target/executable/workflows/merge_quant_results/.config.vsh.yaml index 9996ed3..03a7d31 100644 --- a/target/executable/workflows/merge_quant_results/.config.vsh.yaml +++ b/target/executable/workflows/merge_quant_results/.config.vsh.yaml @@ -269,7 +269,7 @@ build_info: output: "target/executable/workflows/merge_quant_results" executable: "target/executable/workflows/merge_quant_results/merge_quant_results" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/tx2gene" diff --git a/target/executable/workflows/post_processing/.config.vsh.yaml b/target/executable/workflows/post_processing/.config.vsh.yaml index 82764c0..291477f 100644 --- a/target/executable/workflows/post_processing/.config.vsh.yaml +++ b/target/executable/workflows/post_processing/.config.vsh.yaml @@ -369,27 +369,27 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "samtools/samtools_index" repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "samtools/samtools_stats" repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "samtools/samtools_flagstat" repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "samtools/samtools_idxstats" repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "stringtie" repository: type: "local" @@ -406,7 +406,7 @@ repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -482,15 +482,15 @@ build_info: output: "target/executable/workflows/post_processing" executable: "target/executable/workflows/post_processing/post_processing" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/picard_markduplicates" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats" - "target/nextflow/stringtie" - "target/nextflow/bedtools_genomecov" - "target/nextflow/ucsc/bedclip" diff --git a/target/executable/workflows/post_processing/post_processing b/target/executable/workflows/post_processing/post_processing index 82b6bce..4037274 100755 --- a/target/executable/workflows/post_processing/post_processing +++ b/target/executable/workflows/post_processing/post_processing @@ -1143,11 +1143,11 @@ VIASH_DEP_STRINGTIE="$VIASH_META_RESOURCES_DIR/../../../nextflow/stringtie/main. VIASH_DEP_BEDTOOLS_GENOMECOV="$VIASH_META_RESOURCES_DIR/../../../nextflow/bedtools_genomecov/main.nf" VIASH_DEP_UCSC_BEDCLIP="$VIASH_META_RESOURCES_DIR/../../../nextflow/ucsc/bedclip/main.nf" VIASH_DEP_UCSC_BEDGRAPHTOBIGWIG="$VIASH_META_RESOURCES_DIR/../../../nextflow/ucsc/bedgraphtobigwig/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_SORT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_INDEX="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_STATS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_FLAGSTAT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/main.nf" -VIASH_DEP_SAMTOOLS_SAMTOOLS_IDXSTATS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_SORT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_INDEX="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_STATS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_FLAGSTAT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/main.nf" +VIASH_DEP_SAMTOOLS_SAMTOOLS_IDXSTATS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/main.nf" ViashDebug "Running command: $(echo $VIASH_CMD)" cat << VIASHEOF | eval $VIASH_CMD diff --git a/target/executable/workflows/pre_processing/.config.vsh.yaml b/target/executable/workflows/pre_processing/.config.vsh.yaml index 00610c3..11420c9 100644 --- a/target/executable/workflows/pre_processing/.config.vsh.yaml +++ b/target/executable/workflows/pre_processing/.config.vsh.yaml @@ -551,7 +551,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "fq_subsample" repository: type: "local" @@ -559,12 +559,12 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -640,7 +640,7 @@ build_info: output: "target/executable/workflows/pre_processing" executable: "target/executable/workflows/pre_processing/pre_processing" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/fastqc" @@ -648,9 +648,9 @@ build_info: - "target/nextflow/trimgalore" - "target/nextflow/bbmap_bbsplit" - "target/nextflow/sortmerna" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp" - "target/nextflow/fq_subsample" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant" package_config: version: "main" info: diff --git a/target/executable/workflows/pre_processing/pre_processing b/target/executable/workflows/pre_processing/pre_processing index f7f301f..0096c24 100755 --- a/target/executable/workflows/pre_processing/pre_processing +++ b/target/executable/workflows/pre_processing/pre_processing @@ -1462,8 +1462,8 @@ VIASH_DEP_TRIMGALORE="$VIASH_META_RESOURCES_DIR/../../../nextflow/trimgalore/mai VIASH_DEP_BBMAP_BBSPLIT="$VIASH_META_RESOURCES_DIR/../../../nextflow/bbmap_bbsplit/main.nf" VIASH_DEP_SORTMERNA="$VIASH_META_RESOURCES_DIR/../../../nextflow/sortmerna/main.nf" VIASH_DEP_FQ_SUBSAMPLE="$VIASH_META_RESOURCES_DIR/../../../nextflow/fq_subsample/main.nf" -VIASH_DEP_FASTP="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/main.nf" -VIASH_DEP_SALMON_SALMON_QUANT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/main.nf" +VIASH_DEP_FASTP="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/main.nf" +VIASH_DEP_SALMON_SALMON_QUANT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/main.nf" ViashDebug "Running command: $(echo $VIASH_CMD)" cat << VIASHEOF | eval $VIASH_CMD diff --git a/target/executable/workflows/prepare_genome/.config.vsh.yaml b/target/executable/workflows/prepare_genome/.config.vsh.yaml index 346814b..fe5953f 100644 --- a/target/executable/workflows/prepare_genome/.config.vsh.yaml +++ b/target/executable/workflows/prepare_genome/.config.vsh.yaml @@ -370,7 +370,7 @@ dependencies: repository: type: "vsh" repo: "biobox" - tag: "main" + tag: "v0.2.0" - name: "cat_additional_fasta" repository: type: "local" @@ -387,7 +387,7 @@ dependencies: repository: type: "vsh" repo: "biobox" - tag: "main" + tag: "v0.2.0" - name: "getchromsizes" repository: type: "local" @@ -395,12 +395,12 @@ dependencies: repository: type: "vsh" repo: "craftbox" - tag: "main" + tag: "v0.1.0" - name: "star/star_genome_generate" repository: type: "vsh" repo: "biobox" - tag: "main" + tag: "v0.2.0" - name: "bbmap_bbsplit" repository: type: "local" @@ -408,7 +408,7 @@ dependencies: repository: type: "vsh" repo: "biobox" - tag: "main" + tag: "v0.2.0" - name: "kallisto/kallisto_index" repository: type: "local" @@ -416,11 +416,11 @@ repositories: - type: "vsh" name: "biobox" repo: "biobox" - tag: "main" + tag: "v0.2.0" - type: "vsh" name: "craftbox" repo: "craftbox" - tag: "main" + tag: "v0.1.0" runners: - type: "executable" id: "executable" @@ -496,21 +496,21 @@ build_info: output: "target/executable/workflows/prepare_genome" executable: "target/executable/workflows/prepare_genome/prepare_genome" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/gunzip" - - "target/dependencies/vsh/vsh/biobox/main/nextflow/gffread" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread" - "target/nextflow/cat_additional_fasta" - "target/nextflow/gtf2bed" - "target/nextflow/preprocess_transcripts_fasta" - "target/nextflow/gtf_filter" - - "target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference" - "target/nextflow/getchromsizes" - - "target/dependencies/vsh/vsh/craftbox/main/nextflow/untar" - - "target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate" + - "target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate" - "target/nextflow/bbmap_bbsplit" - - "target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index" - "target/nextflow/kallisto/kallisto_index" package_config: version: "main" diff --git a/target/executable/workflows/prepare_genome/prepare_genome b/target/executable/workflows/prepare_genome/prepare_genome index 679007a..6a3aa84 100755 --- a/target/executable/workflows/prepare_genome/prepare_genome +++ b/target/executable/workflows/prepare_genome/prepare_genome @@ -1111,11 +1111,11 @@ VIASH_DEP_GTF_FILTER="$VIASH_META_RESOURCES_DIR/../../../nextflow/gtf_filter/mai VIASH_DEP_GETCHROMSIZES="$VIASH_META_RESOURCES_DIR/../../../nextflow/getchromsizes/main.nf" VIASH_DEP_BBMAP_BBSPLIT="$VIASH_META_RESOURCES_DIR/../../../nextflow/bbmap_bbsplit/main.nf" VIASH_DEP_KALLISTO_KALLISTO_INDEX="$VIASH_META_RESOURCES_DIR/../../../nextflow/kallisto/kallisto_index/main.nf" -VIASH_DEP_GFFREAD="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/main/nextflow/gffread/main.nf" -VIASH_DEP_RSEM_RSEM_PREPARE_REFERENCE="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/main.nf" -VIASH_DEP_UNTAR="$VIASH_TARGET_DIR/dependencies/vsh/vsh/craftbox/main/nextflow/untar/main.nf" -VIASH_DEP_STAR_STAR_GENOME_GENERATE="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/main.nf" -VIASH_DEP_SALMON_SALMON_INDEX="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/main.nf" +VIASH_DEP_GFFREAD="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/main.nf" +VIASH_DEP_RSEM_RSEM_PREPARE_REFERENCE="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/main.nf" +VIASH_DEP_UNTAR="$VIASH_TARGET_DIR/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/main.nf" +VIASH_DEP_STAR_STAR_GENOME_GENERATE="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/main.nf" +VIASH_DEP_SALMON_SALMON_INDEX="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/main.nf" ViashDebug "Running command: $(echo $VIASH_CMD)" cat << VIASHEOF | eval $VIASH_CMD diff --git a/target/executable/workflows/pseudo_alignment_and_quant/.config.vsh.yaml b/target/executable/workflows/pseudo_alignment_and_quant/.config.vsh.yaml index e6f498e..a5785a2 100644 --- a/target/executable/workflows/pseudo_alignment_and_quant/.config.vsh.yaml +++ b/target/executable/workflows/pseudo_alignment_and_quant/.config.vsh.yaml @@ -197,7 +197,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "kallisto/kallisto_quant" repository: type: "local" @@ -205,7 +205,7 @@ repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -281,10 +281,10 @@ build_info: output: "target/executable/workflows/pseudo_alignment_and_quant" executable: "target/executable/workflows/pseudo_alignment_and_quant/pseudo_alignment_and_quant" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant" - "target/nextflow/kallisto/kallisto_quant" package_config: version: "main" diff --git a/target/executable/workflows/pseudo_alignment_and_quant/pseudo_alignment_and_quant b/target/executable/workflows/pseudo_alignment_and_quant/pseudo_alignment_and_quant index 5e9b086..b432a0d 100755 --- a/target/executable/workflows/pseudo_alignment_and_quant/pseudo_alignment_and_quant +++ b/target/executable/workflows/pseudo_alignment_and_quant/pseudo_alignment_and_quant @@ -784,7 +784,7 @@ fi # set dependency paths VIASH_DEP_KALLISTO_KALLISTO_QUANT="$VIASH_META_RESOURCES_DIR/../../../nextflow/kallisto/kallisto_quant/main.nf" -VIASH_DEP_SALMON_SALMON_QUANT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/main.nf" +VIASH_DEP_SALMON_SALMON_QUANT="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/main.nf" ViashDebug "Running command: $(echo $VIASH_CMD)" cat << VIASHEOF | eval $VIASH_CMD diff --git a/target/executable/workflows/quality_control/.config.vsh.yaml b/target/executable/workflows/quality_control/.config.vsh.yaml index dcfe18a..05f4c9c 100644 --- a/target/executable/workflows/quality_control/.config.vsh.yaml +++ b/target/executable/workflows/quality_control/.config.vsh.yaml @@ -1490,7 +1490,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "multiqc_custom_biotype" repository: type: "local" @@ -1504,7 +1504,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "workflows/merge_quant_results" repository: type: "local" @@ -1512,7 +1512,7 @@ repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -1588,7 +1588,7 @@ build_info: output: "target/executable/workflows/quality_control" executable: "target/executable/workflows/quality_control/quality_control" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/rseqc/rseqc_bamstat" @@ -1602,11 +1602,11 @@ build_info: - "target/nextflow/dupradar" - "target/nextflow/qualimap" - "target/nextflow/preseq_lcextrap" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts" - "target/nextflow/multiqc_custom_biotype" - "target/nextflow/deseq2_qc" - "target/nextflow/prepare_multiqc_input" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc" - "target/nextflow/workflows/merge_quant_results" package_config: version: "main" diff --git a/target/executable/workflows/quality_control/quality_control b/target/executable/workflows/quality_control/quality_control index b8813d0..6f5143a 100755 --- a/target/executable/workflows/quality_control/quality_control +++ b/target/executable/workflows/quality_control/quality_control @@ -3343,8 +3343,8 @@ VIASH_DEP_MULTIQC_CUSTOM_BIOTYPE="$VIASH_META_RESOURCES_DIR/../../../nextflow/mu VIASH_DEP_DESEQ2_QC="$VIASH_META_RESOURCES_DIR/../../../nextflow/deseq2_qc/main.nf" VIASH_DEP_PREPARE_MULTIQC_INPUT="$VIASH_META_RESOURCES_DIR/../../../nextflow/prepare_multiqc_input/main.nf" VIASH_DEP_WORKFLOWS_MERGE_QUANT_RESULTS="$VIASH_META_RESOURCES_DIR/../../../nextflow/workflows/merge_quant_results/main.nf" -VIASH_DEP_FEATURECOUNTS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/main.nf" -VIASH_DEP_MULTIQC="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/main.nf" +VIASH_DEP_FEATURECOUNTS="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/main.nf" +VIASH_DEP_MULTIQC="$VIASH_TARGET_DIR/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/main.nf" ViashDebug "Running command: $(echo $VIASH_CMD)" cat << VIASHEOF | eval $VIASH_CMD diff --git a/target/executable/workflows/rnaseq/.config.vsh.yaml b/target/executable/workflows/rnaseq/.config.vsh.yaml index 378e2be..9657d82 100644 --- a/target/executable/workflows/rnaseq/.config.vsh.yaml +++ b/target/executable/workflows/rnaseq/.config.vsh.yaml @@ -1956,7 +1956,7 @@ build_info: output: "target/executable/workflows/rnaseq" executable: "target/executable/workflows/rnaseq/rnaseq" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/workflows/prepare_genome" diff --git a/target/nextflow/bbmap_bbsplit/.config.vsh.yaml b/target/nextflow/bbmap_bbsplit/.config.vsh.yaml index b87b41a..616aeda 100644 --- a/target/nextflow/bbmap_bbsplit/.config.vsh.yaml +++ b/target/nextflow/bbmap_bbsplit/.config.vsh.yaml @@ -229,7 +229,7 @@ build_info: output: "target/nextflow/bbmap_bbsplit" executable: "target/nextflow/bbmap_bbsplit/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/bbmap_bbsplit/main.nf b/target/nextflow/bbmap_bbsplit/main.nf index 2c7eb89..384f02f 100644 --- a/target/nextflow/bbmap_bbsplit/main.nf +++ b/target/nextflow/bbmap_bbsplit/main.nf @@ -3090,7 +3090,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/bbmap_bbsplit", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/bedtools_genomecov/.config.vsh.yaml b/target/nextflow/bedtools_genomecov/.config.vsh.yaml index 66a65e6..10ee3ed 100644 --- a/target/nextflow/bedtools_genomecov/.config.vsh.yaml +++ b/target/nextflow/bedtools_genomecov/.config.vsh.yaml @@ -169,7 +169,7 @@ build_info: output: "target/nextflow/bedtools_genomecov" executable: "target/nextflow/bedtools_genomecov/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/bedtools_genomecov/main.nf b/target/nextflow/bedtools_genomecov/main.nf index e949406..20f8c8d 100644 --- a/target/nextflow/bedtools_genomecov/main.nf +++ b/target/nextflow/bedtools_genomecov/main.nf @@ -3017,7 +3017,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/bedtools_genomecov", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/cat_additional_fasta/.config.vsh.yaml b/target/nextflow/cat_additional_fasta/.config.vsh.yaml index 1ab7ac8..5946f6f 100644 --- a/target/nextflow/cat_additional_fasta/.config.vsh.yaml +++ b/target/nextflow/cat_additional_fasta/.config.vsh.yaml @@ -173,7 +173,7 @@ build_info: output: "target/nextflow/cat_additional_fasta" executable: "target/nextflow/cat_additional_fasta/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/cat_additional_fasta/main.nf b/target/nextflow/cat_additional_fasta/main.nf index 532966d..c884808 100644 --- a/target/nextflow/cat_additional_fasta/main.nf +++ b/target/nextflow/cat_additional_fasta/main.nf @@ -3018,7 +3018,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/cat_additional_fasta", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/cat_fastq/.config.vsh.yaml b/target/nextflow/cat_fastq/.config.vsh.yaml index e99cb72..351ac9b 100644 --- a/target/nextflow/cat_fastq/.config.vsh.yaml +++ b/target/nextflow/cat_fastq/.config.vsh.yaml @@ -160,7 +160,7 @@ build_info: output: "target/nextflow/cat_fastq" executable: "target/nextflow/cat_fastq/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/cat_fastq/main.nf b/target/nextflow/cat_fastq/main.nf index 08c307b..ccc6da6 100644 --- a/target/nextflow/cat_fastq/main.nf +++ b/target/nextflow/cat_fastq/main.nf @@ -3009,7 +3009,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/cat_fastq", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/deseq2_qc/.config.vsh.yaml b/target/nextflow/deseq2_qc/.config.vsh.yaml index 1fa6d3c..b09c9ce 100644 --- a/target/nextflow/deseq2_qc/.config.vsh.yaml +++ b/target/nextflow/deseq2_qc/.config.vsh.yaml @@ -228,7 +228,7 @@ build_info: output: "target/nextflow/deseq2_qc" executable: "target/nextflow/deseq2_qc/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/deseq2_qc/main.nf b/target/nextflow/deseq2_qc/main.nf index b90d644..7fddc9b 100644 --- a/target/nextflow/deseq2_qc/main.nf +++ b/target/nextflow/deseq2_qc/main.nf @@ -3096,7 +3096,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/deseq2_qc", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/dupradar/.config.vsh.yaml b/target/nextflow/dupradar/.config.vsh.yaml index ad37777..93f78ff 100644 --- a/target/nextflow/dupradar/.config.vsh.yaml +++ b/target/nextflow/dupradar/.config.vsh.yaml @@ -257,7 +257,7 @@ build_info: output: "target/nextflow/dupradar" executable: "target/nextflow/dupradar/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/dupradar/main.nf b/target/nextflow/dupradar/main.nf index ba18558..3ee50e9 100644 --- a/target/nextflow/dupradar/main.nf +++ b/target/nextflow/dupradar/main.nf @@ -3122,7 +3122,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/dupradar", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/fastqc/.config.vsh.yaml b/target/nextflow/fastqc/.config.vsh.yaml index 25ae63c..c663236 100644 --- a/target/nextflow/fastqc/.config.vsh.yaml +++ b/target/nextflow/fastqc/.config.vsh.yaml @@ -189,7 +189,7 @@ build_info: output: "target/nextflow/fastqc" executable: "target/nextflow/fastqc/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/fastqc/main.nf b/target/nextflow/fastqc/main.nf index 01f7e5a..15eca1f 100644 --- a/target/nextflow/fastqc/main.nf +++ b/target/nextflow/fastqc/main.nf @@ -3042,7 +3042,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/fastqc", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/fq_subsample/.config.vsh.yaml b/target/nextflow/fq_subsample/.config.vsh.yaml index 306ab61..c90c5e0 100644 --- a/target/nextflow/fq_subsample/.config.vsh.yaml +++ b/target/nextflow/fq_subsample/.config.vsh.yaml @@ -168,7 +168,7 @@ build_info: output: "target/nextflow/fq_subsample" executable: "target/nextflow/fq_subsample/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/fq_subsample/main.nf b/target/nextflow/fq_subsample/main.nf index 8ab2cda..797e2a0 100644 --- a/target/nextflow/fq_subsample/main.nf +++ b/target/nextflow/fq_subsample/main.nf @@ -3013,7 +3013,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/fq_subsample", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/getchromsizes/.config.vsh.yaml b/target/nextflow/getchromsizes/.config.vsh.yaml index 9487b34..0fc2066 100644 --- a/target/nextflow/getchromsizes/.config.vsh.yaml +++ b/target/nextflow/getchromsizes/.config.vsh.yaml @@ -158,7 +158,7 @@ build_info: output: "target/nextflow/getchromsizes" executable: "target/nextflow/getchromsizes/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/getchromsizes/main.nf b/target/nextflow/getchromsizes/main.nf index 20cd675..f22f708 100644 --- a/target/nextflow/getchromsizes/main.nf +++ b/target/nextflow/getchromsizes/main.nf @@ -2999,7 +2999,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/getchromsizes", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/gtf2bed/.config.vsh.yaml b/target/nextflow/gtf2bed/.config.vsh.yaml index 9d90bdb..4c5d521 100644 --- a/target/nextflow/gtf2bed/.config.vsh.yaml +++ b/target/nextflow/gtf2bed/.config.vsh.yaml @@ -136,7 +136,7 @@ build_info: output: "target/nextflow/gtf2bed" executable: "target/nextflow/gtf2bed/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/gtf2bed/main.nf b/target/nextflow/gtf2bed/main.nf index 654ae8f..7ee9152 100644 --- a/target/nextflow/gtf2bed/main.nf +++ b/target/nextflow/gtf2bed/main.nf @@ -2981,7 +2981,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/gtf2bed", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/gtf_filter/.config.vsh.yaml b/target/nextflow/gtf_filter/.config.vsh.yaml index afe6f26..a86123b 100644 --- a/target/nextflow/gtf_filter/.config.vsh.yaml +++ b/target/nextflow/gtf_filter/.config.vsh.yaml @@ -146,7 +146,7 @@ build_info: output: "target/nextflow/gtf_filter" executable: "target/nextflow/gtf_filter/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/gtf_filter/main.nf b/target/nextflow/gtf_filter/main.nf index c519eab..ba2211c 100644 --- a/target/nextflow/gtf_filter/main.nf +++ b/target/nextflow/gtf_filter/main.nf @@ -2989,7 +2989,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/gtf_filter", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/gunzip/.config.vsh.yaml b/target/nextflow/gunzip/.config.vsh.yaml index 03540b2..62205f5 100644 --- a/target/nextflow/gunzip/.config.vsh.yaml +++ b/target/nextflow/gunzip/.config.vsh.yaml @@ -135,7 +135,7 @@ build_info: output: "target/nextflow/gunzip" executable: "target/nextflow/gunzip/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/gunzip/main.nf b/target/nextflow/gunzip/main.nf index 476f005..a12bdb4 100644 --- a/target/nextflow/gunzip/main.nf +++ b/target/nextflow/gunzip/main.nf @@ -2978,7 +2978,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/gunzip", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/kallisto/kallisto_index/.config.vsh.yaml b/target/nextflow/kallisto/kallisto_index/.config.vsh.yaml index 814258e..3f5cd66 100644 --- a/target/nextflow/kallisto/kallisto_index/.config.vsh.yaml +++ b/target/nextflow/kallisto/kallisto_index/.config.vsh.yaml @@ -146,7 +146,7 @@ build_info: output: "target/nextflow/kallisto/kallisto_index" executable: "target/nextflow/kallisto/kallisto_index/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/kallisto/kallisto_index/main.nf b/target/nextflow/kallisto/kallisto_index/main.nf index 1a0f4fe..c91d680 100644 --- a/target/nextflow/kallisto/kallisto_index/main.nf +++ b/target/nextflow/kallisto/kallisto_index/main.nf @@ -2988,7 +2988,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/kallisto/kallisto_index", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/kallisto/kallisto_quant/.config.vsh.yaml b/target/nextflow/kallisto/kallisto_quant/.config.vsh.yaml index ba406e2..e57419c 100644 --- a/target/nextflow/kallisto/kallisto_quant/.config.vsh.yaml +++ b/target/nextflow/kallisto/kallisto_quant/.config.vsh.yaml @@ -244,7 +244,7 @@ build_info: output: "target/nextflow/kallisto/kallisto_quant" executable: "target/nextflow/kallisto/kallisto_quant/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/kallisto/kallisto_quant/main.nf b/target/nextflow/kallisto/kallisto_quant/main.nf index 9a764fe..95343b8 100644 --- a/target/nextflow/kallisto/kallisto_quant/main.nf +++ b/target/nextflow/kallisto/kallisto_quant/main.nf @@ -3100,7 +3100,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/kallisto/kallisto_quant", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/multiqc_custom_biotype/.config.vsh.yaml b/target/nextflow/multiqc_custom_biotype/.config.vsh.yaml index c295806..98da44d 100644 --- a/target/nextflow/multiqc_custom_biotype/.config.vsh.yaml +++ b/target/nextflow/multiqc_custom_biotype/.config.vsh.yaml @@ -161,7 +161,7 @@ build_info: output: "target/nextflow/multiqc_custom_biotype" executable: "target/nextflow/multiqc_custom_biotype/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/multiqc_custom_biotype/main.nf b/target/nextflow/multiqc_custom_biotype/main.nf index 04d08b1..a3dc566 100644 --- a/target/nextflow/multiqc_custom_biotype/main.nf +++ b/target/nextflow/multiqc_custom_biotype/main.nf @@ -3006,7 +3006,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/multiqc_custom_biotype", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/picard_markduplicates/.config.vsh.yaml b/target/nextflow/picard_markduplicates/.config.vsh.yaml index bd89db4..1807801 100644 --- a/target/nextflow/picard_markduplicates/.config.vsh.yaml +++ b/target/nextflow/picard_markduplicates/.config.vsh.yaml @@ -198,7 +198,7 @@ build_info: output: "target/nextflow/picard_markduplicates" executable: "target/nextflow/picard_markduplicates/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/picard_markduplicates/main.nf b/target/nextflow/picard_markduplicates/main.nf index 41badef..473f9e5 100644 --- a/target/nextflow/picard_markduplicates/main.nf +++ b/target/nextflow/picard_markduplicates/main.nf @@ -3049,7 +3049,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/picard_markduplicates", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/prepare_multiqc_input/.config.vsh.yaml b/target/nextflow/prepare_multiqc_input/.config.vsh.yaml index af01c0e..ed3b567 100644 --- a/target/nextflow/prepare_multiqc_input/.config.vsh.yaml +++ b/target/nextflow/prepare_multiqc_input/.config.vsh.yaml @@ -400,7 +400,7 @@ build_info: output: "target/nextflow/prepare_multiqc_input" executable: "target/nextflow/prepare_multiqc_input/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/prepare_multiqc_input/main.nf b/target/nextflow/prepare_multiqc_input/main.nf index 636e882..b2ed4a8 100644 --- a/target/nextflow/prepare_multiqc_input/main.nf +++ b/target/nextflow/prepare_multiqc_input/main.nf @@ -3263,7 +3263,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/prepare_multiqc_input", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/preprocess_transcripts_fasta/.config.vsh.yaml b/target/nextflow/preprocess_transcripts_fasta/.config.vsh.yaml index 7bb73d2..d95a24f 100644 --- a/target/nextflow/preprocess_transcripts_fasta/.config.vsh.yaml +++ b/target/nextflow/preprocess_transcripts_fasta/.config.vsh.yaml @@ -129,7 +129,7 @@ build_info: output: "target/nextflow/preprocess_transcripts_fasta" executable: "target/nextflow/preprocess_transcripts_fasta/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/preprocess_transcripts_fasta/main.nf b/target/nextflow/preprocess_transcripts_fasta/main.nf index fea1a90..ec11355 100644 --- a/target/nextflow/preprocess_transcripts_fasta/main.nf +++ b/target/nextflow/preprocess_transcripts_fasta/main.nf @@ -2968,7 +2968,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/preprocess_transcripts_fasta", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/preseq_lcextrap/.config.vsh.yaml b/target/nextflow/preseq_lcextrap/.config.vsh.yaml index fd05b99..e496a6d 100644 --- a/target/nextflow/preseq_lcextrap/.config.vsh.yaml +++ b/target/nextflow/preseq_lcextrap/.config.vsh.yaml @@ -182,7 +182,7 @@ build_info: output: "target/nextflow/preseq_lcextrap" executable: "target/nextflow/preseq_lcextrap/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/preseq_lcextrap/main.nf b/target/nextflow/preseq_lcextrap/main.nf index d9c0030..8298fdf 100644 --- a/target/nextflow/preseq_lcextrap/main.nf +++ b/target/nextflow/preseq_lcextrap/main.nf @@ -3021,7 +3021,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/preseq_lcextrap", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/qualimap/.config.vsh.yaml b/target/nextflow/qualimap/.config.vsh.yaml index d2c09d0..5216011 100644 --- a/target/nextflow/qualimap/.config.vsh.yaml +++ b/target/nextflow/qualimap/.config.vsh.yaml @@ -262,7 +262,7 @@ build_info: output: "target/nextflow/qualimap" executable: "target/nextflow/qualimap/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/qualimap/main.nf b/target/nextflow/qualimap/main.nf index 8a8561d..e39c337 100644 --- a/target/nextflow/qualimap/main.nf +++ b/target/nextflow/qualimap/main.nf @@ -3130,7 +3130,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/qualimap", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rsem/rsem_calculate_expression/.config.vsh.yaml b/target/nextflow/rsem/rsem_calculate_expression/.config.vsh.yaml index 22576a2..9bca5e1 100644 --- a/target/nextflow/rsem/rsem_calculate_expression/.config.vsh.yaml +++ b/target/nextflow/rsem/rsem_calculate_expression/.config.vsh.yaml @@ -299,7 +299,7 @@ build_info: output: "target/nextflow/rsem/rsem_calculate_expression" executable: "target/nextflow/rsem/rsem_calculate_expression/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rsem/rsem_calculate_expression/main.nf b/target/nextflow/rsem/rsem_calculate_expression/main.nf index b9d6d45..3165b4e 100644 --- a/target/nextflow/rsem/rsem_calculate_expression/main.nf +++ b/target/nextflow/rsem/rsem_calculate_expression/main.nf @@ -3159,7 +3159,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rsem/rsem_calculate_expression", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rsem/rsem_merge_counts/.config.vsh.yaml b/target/nextflow/rsem/rsem_merge_counts/.config.vsh.yaml index 560ce93..0ba87ad 100644 --- a/target/nextflow/rsem/rsem_merge_counts/.config.vsh.yaml +++ b/target/nextflow/rsem/rsem_merge_counts/.config.vsh.yaml @@ -193,7 +193,7 @@ build_info: output: "target/nextflow/rsem/rsem_merge_counts" executable: "target/nextflow/rsem/rsem_merge_counts/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rsem/rsem_merge_counts/main.nf b/target/nextflow/rsem/rsem_merge_counts/main.nf index 599185c..9665aad 100644 --- a/target/nextflow/rsem/rsem_merge_counts/main.nf +++ b/target/nextflow/rsem/rsem_merge_counts/main.nf @@ -3037,7 +3037,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rsem/rsem_merge_counts", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rseqc/rseqc_bamstat/.config.vsh.yaml b/target/nextflow/rseqc/rseqc_bamstat/.config.vsh.yaml index 6ef14a3..1fa8cd0 100644 --- a/target/nextflow/rseqc/rseqc_bamstat/.config.vsh.yaml +++ b/target/nextflow/rseqc/rseqc_bamstat/.config.vsh.yaml @@ -154,7 +154,7 @@ build_info: output: "target/nextflow/rseqc/rseqc_bamstat" executable: "target/nextflow/rseqc/rseqc_bamstat/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rseqc/rseqc_bamstat/main.nf b/target/nextflow/rseqc/rseqc_bamstat/main.nf index bd420b2..a3673a2 100644 --- a/target/nextflow/rseqc/rseqc_bamstat/main.nf +++ b/target/nextflow/rseqc/rseqc_bamstat/main.nf @@ -3002,7 +3002,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rseqc/rseqc_bamstat", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rseqc/rseqc_inferexperiment/.config.vsh.yaml b/target/nextflow/rseqc/rseqc_inferexperiment/.config.vsh.yaml index 5280c81..9e272f3 100644 --- a/target/nextflow/rseqc/rseqc_inferexperiment/.config.vsh.yaml +++ b/target/nextflow/rseqc/rseqc_inferexperiment/.config.vsh.yaml @@ -177,7 +177,7 @@ build_info: output: "target/nextflow/rseqc/rseqc_inferexperiment" executable: "target/nextflow/rseqc/rseqc_inferexperiment/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rseqc/rseqc_inferexperiment/main.nf b/target/nextflow/rseqc/rseqc_inferexperiment/main.nf index a2e1ed6..8d93323 100644 --- a/target/nextflow/rseqc/rseqc_inferexperiment/main.nf +++ b/target/nextflow/rseqc/rseqc_inferexperiment/main.nf @@ -3030,7 +3030,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rseqc/rseqc_inferexperiment", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rseqc/rseqc_innerdistance/.config.vsh.yaml b/target/nextflow/rseqc/rseqc_innerdistance/.config.vsh.yaml index 4e13b6b..87262c5 100644 --- a/target/nextflow/rseqc/rseqc_innerdistance/.config.vsh.yaml +++ b/target/nextflow/rseqc/rseqc_innerdistance/.config.vsh.yaml @@ -263,7 +263,7 @@ build_info: output: "target/nextflow/rseqc/rseqc_innerdistance" executable: "target/nextflow/rseqc/rseqc_innerdistance/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rseqc/rseqc_innerdistance/main.nf b/target/nextflow/rseqc/rseqc_innerdistance/main.nf index b1a93a4..db1b60a 100644 --- a/target/nextflow/rseqc/rseqc_innerdistance/main.nf +++ b/target/nextflow/rseqc/rseqc_innerdistance/main.nf @@ -3123,7 +3123,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rseqc/rseqc_innerdistance", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rseqc/rseqc_junctionannotation/.config.vsh.yaml b/target/nextflow/rseqc/rseqc_junctionannotation/.config.vsh.yaml index bcceb5c..269b9c7 100644 --- a/target/nextflow/rseqc/rseqc_junctionannotation/.config.vsh.yaml +++ b/target/nextflow/rseqc/rseqc_junctionannotation/.config.vsh.yaml @@ -251,7 +251,7 @@ build_info: output: "target/nextflow/rseqc/rseqc_junctionannotation" executable: "target/nextflow/rseqc/rseqc_junctionannotation/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rseqc/rseqc_junctionannotation/main.nf b/target/nextflow/rseqc/rseqc_junctionannotation/main.nf index 18d392b..26e4303 100644 --- a/target/nextflow/rseqc/rseqc_junctionannotation/main.nf +++ b/target/nextflow/rseqc/rseqc_junctionannotation/main.nf @@ -3114,7 +3114,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rseqc/rseqc_junctionannotation", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rseqc/rseqc_junctionsaturation/.config.vsh.yaml b/target/nextflow/rseqc/rseqc_junctionsaturation/.config.vsh.yaml index e6750ea..3cb8eca 100644 --- a/target/nextflow/rseqc/rseqc_junctionsaturation/.config.vsh.yaml +++ b/target/nextflow/rseqc/rseqc_junctionsaturation/.config.vsh.yaml @@ -240,7 +240,7 @@ build_info: output: "target/nextflow/rseqc/rseqc_junctionsaturation" executable: "target/nextflow/rseqc/rseqc_junctionsaturation/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rseqc/rseqc_junctionsaturation/main.nf b/target/nextflow/rseqc/rseqc_junctionsaturation/main.nf index ed3c751..0b94404 100644 --- a/target/nextflow/rseqc/rseqc_junctionsaturation/main.nf +++ b/target/nextflow/rseqc/rseqc_junctionsaturation/main.nf @@ -3099,7 +3099,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rseqc/rseqc_junctionsaturation", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rseqc/rseqc_readdistribution/.config.vsh.yaml b/target/nextflow/rseqc/rseqc_readdistribution/.config.vsh.yaml index 8cb5e3b..de51055 100644 --- a/target/nextflow/rseqc/rseqc_readdistribution/.config.vsh.yaml +++ b/target/nextflow/rseqc/rseqc_readdistribution/.config.vsh.yaml @@ -153,7 +153,7 @@ build_info: output: "target/nextflow/rseqc/rseqc_readdistribution" executable: "target/nextflow/rseqc/rseqc_readdistribution/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rseqc/rseqc_readdistribution/main.nf b/target/nextflow/rseqc/rseqc_readdistribution/main.nf index 651d9fb..9f2f857 100644 --- a/target/nextflow/rseqc/rseqc_readdistribution/main.nf +++ b/target/nextflow/rseqc/rseqc_readdistribution/main.nf @@ -3003,7 +3003,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rseqc/rseqc_readdistribution", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rseqc/rseqc_readduplication/.config.vsh.yaml b/target/nextflow/rseqc/rseqc_readduplication/.config.vsh.yaml index d27ce78..83be962 100644 --- a/target/nextflow/rseqc/rseqc_readduplication/.config.vsh.yaml +++ b/target/nextflow/rseqc/rseqc_readduplication/.config.vsh.yaml @@ -202,7 +202,7 @@ build_info: output: "target/nextflow/rseqc/rseqc_readduplication" executable: "target/nextflow/rseqc/rseqc_readduplication/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rseqc/rseqc_readduplication/main.nf b/target/nextflow/rseqc/rseqc_readduplication/main.nf index 0d82c0b..28359f5 100644 --- a/target/nextflow/rseqc/rseqc_readduplication/main.nf +++ b/target/nextflow/rseqc/rseqc_readduplication/main.nf @@ -3057,7 +3057,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rseqc/rseqc_readduplication", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/rseqc/rseqc_tin/.config.vsh.yaml b/target/nextflow/rseqc/rseqc_tin/.config.vsh.yaml index 0793b53..b41e51e 100644 --- a/target/nextflow/rseqc/rseqc_tin/.config.vsh.yaml +++ b/target/nextflow/rseqc/rseqc_tin/.config.vsh.yaml @@ -205,7 +205,7 @@ build_info: output: "target/nextflow/rseqc/rseqc_tin" executable: "target/nextflow/rseqc/rseqc_tin/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/rseqc/rseqc_tin/main.nf b/target/nextflow/rseqc/rseqc_tin/main.nf index f1bbcf6..aa05bc3 100644 --- a/target/nextflow/rseqc/rseqc_tin/main.nf +++ b/target/nextflow/rseqc/rseqc_tin/main.nf @@ -3062,7 +3062,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/rseqc/rseqc_tin", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/sortmerna/.config.vsh.yaml b/target/nextflow/sortmerna/.config.vsh.yaml index 97e710b..d60daf4 100644 --- a/target/nextflow/sortmerna/.config.vsh.yaml +++ b/target/nextflow/sortmerna/.config.vsh.yaml @@ -189,7 +189,7 @@ build_info: output: "target/nextflow/sortmerna" executable: "target/nextflow/sortmerna/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/sortmerna/main.nf b/target/nextflow/sortmerna/main.nf index 1602d48..22ea85f 100644 --- a/target/nextflow/sortmerna/main.nf +++ b/target/nextflow/sortmerna/main.nf @@ -3036,7 +3036,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/sortmerna", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/stringtie/.config.vsh.yaml b/target/nextflow/stringtie/.config.vsh.yaml index d281d3c..5447c92 100644 --- a/target/nextflow/stringtie/.config.vsh.yaml +++ b/target/nextflow/stringtie/.config.vsh.yaml @@ -207,7 +207,7 @@ build_info: output: "target/nextflow/stringtie" executable: "target/nextflow/stringtie/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/stringtie/main.nf b/target/nextflow/stringtie/main.nf index a4bf78f..4011a29 100644 --- a/target/nextflow/stringtie/main.nf +++ b/target/nextflow/stringtie/main.nf @@ -3059,7 +3059,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/stringtie", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/summarizedexperiment/.config.vsh.yaml b/target/nextflow/summarizedexperiment/.config.vsh.yaml index fdd0555..cf33d20 100644 --- a/target/nextflow/summarizedexperiment/.config.vsh.yaml +++ b/target/nextflow/summarizedexperiment/.config.vsh.yaml @@ -190,7 +190,7 @@ build_info: output: "target/nextflow/summarizedexperiment" executable: "target/nextflow/summarizedexperiment/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/summarizedexperiment/main.nf b/target/nextflow/summarizedexperiment/main.nf index 89a4d22..f7db9e2 100644 --- a/target/nextflow/summarizedexperiment/main.nf +++ b/target/nextflow/summarizedexperiment/main.nf @@ -3040,7 +3040,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/summarizedexperiment", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/trimgalore/.config.vsh.yaml b/target/nextflow/trimgalore/.config.vsh.yaml index 888a979..c100d59 100644 --- a/target/nextflow/trimgalore/.config.vsh.yaml +++ b/target/nextflow/trimgalore/.config.vsh.yaml @@ -779,7 +779,7 @@ build_info: output: "target/nextflow/trimgalore" executable: "target/nextflow/trimgalore/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/trimgalore/main.nf b/target/nextflow/trimgalore/main.nf index 4312bef..80c1c30 100644 --- a/target/nextflow/trimgalore/main.nf +++ b/target/nextflow/trimgalore/main.nf @@ -3562,7 +3562,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/trimgalore", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/tx2gene/.config.vsh.yaml b/target/nextflow/tx2gene/.config.vsh.yaml index cb2e58b..9bf565a 100644 --- a/target/nextflow/tx2gene/.config.vsh.yaml +++ b/target/nextflow/tx2gene/.config.vsh.yaml @@ -183,7 +183,7 @@ build_info: output: "target/nextflow/tx2gene" executable: "target/nextflow/tx2gene/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/tx2gene/main.nf b/target/nextflow/tx2gene/main.nf index 8ed8975..e812cd3 100644 --- a/target/nextflow/tx2gene/main.nf +++ b/target/nextflow/tx2gene/main.nf @@ -3035,7 +3035,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/tx2gene", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/tximport/.config.vsh.yaml b/target/nextflow/tximport/.config.vsh.yaml index b621e1a..5c2a703 100644 --- a/target/nextflow/tximport/.config.vsh.yaml +++ b/target/nextflow/tximport/.config.vsh.yaml @@ -238,7 +238,7 @@ build_info: output: "target/nextflow/tximport" executable: "target/nextflow/tximport/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/tximport/main.nf b/target/nextflow/tximport/main.nf index a5d1a29..3caada6 100644 --- a/target/nextflow/tximport/main.nf +++ b/target/nextflow/tximport/main.nf @@ -3100,7 +3100,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/tximport", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/ucsc/bedclip/.config.vsh.yaml b/target/nextflow/ucsc/bedclip/.config.vsh.yaml index 4cf7969..d351628 100644 --- a/target/nextflow/ucsc/bedclip/.config.vsh.yaml +++ b/target/nextflow/ucsc/bedclip/.config.vsh.yaml @@ -155,7 +155,7 @@ build_info: output: "target/nextflow/ucsc/bedclip" executable: "target/nextflow/ucsc/bedclip/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/ucsc/bedclip/main.nf b/target/nextflow/ucsc/bedclip/main.nf index 9ee950c..86f1601 100644 --- a/target/nextflow/ucsc/bedclip/main.nf +++ b/target/nextflow/ucsc/bedclip/main.nf @@ -3004,7 +3004,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/ucsc/bedclip", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/ucsc/bedgraphtobigwig/.config.vsh.yaml b/target/nextflow/ucsc/bedgraphtobigwig/.config.vsh.yaml index caa0762..4e642b3 100644 --- a/target/nextflow/ucsc/bedgraphtobigwig/.config.vsh.yaml +++ b/target/nextflow/ucsc/bedgraphtobigwig/.config.vsh.yaml @@ -155,7 +155,7 @@ build_info: output: "target/nextflow/ucsc/bedgraphtobigwig" executable: "target/nextflow/ucsc/bedgraphtobigwig/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/ucsc/bedgraphtobigwig/main.nf b/target/nextflow/ucsc/bedgraphtobigwig/main.nf index 3d25fab..a20f80d 100644 --- a/target/nextflow/ucsc/bedgraphtobigwig/main.nf +++ b/target/nextflow/ucsc/bedgraphtobigwig/main.nf @@ -3004,7 +3004,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/ucsc/bedgraphtobigwig", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/umitools/umitools_dedup/.config.vsh.yaml b/target/nextflow/umitools/umitools_dedup/.config.vsh.yaml index 2ea82e1..f7d0992 100644 --- a/target/nextflow/umitools/umitools_dedup/.config.vsh.yaml +++ b/target/nextflow/umitools/umitools_dedup/.config.vsh.yaml @@ -186,7 +186,7 @@ build_info: output: "target/nextflow/umitools/umitools_dedup" executable: "target/nextflow/umitools/umitools_dedup/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/umitools/umitools_dedup/main.nf b/target/nextflow/umitools/umitools_dedup/main.nf index cf6eb0e..ae52e1a 100644 --- a/target/nextflow/umitools/umitools_dedup/main.nf +++ b/target/nextflow/umitools/umitools_dedup/main.nf @@ -3040,7 +3040,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/umitools/umitools_dedup", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/umitools/umitools_extract/.config.vsh.yaml b/target/nextflow/umitools/umitools_extract/.config.vsh.yaml index 7b0d14d..c1937ed 100644 --- a/target/nextflow/umitools/umitools_extract/.config.vsh.yaml +++ b/target/nextflow/umitools/umitools_extract/.config.vsh.yaml @@ -244,7 +244,7 @@ build_info: output: "target/nextflow/umitools/umitools_extract" executable: "target/nextflow/umitools/umitools_extract/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/umitools/umitools_extract/main.nf b/target/nextflow/umitools/umitools_extract/main.nf index 3a50f9e..7ec5ea4 100644 --- a/target/nextflow/umitools/umitools_extract/main.nf +++ b/target/nextflow/umitools/umitools_extract/main.nf @@ -3105,7 +3105,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/umitools/umitools_extract", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/umitools_prepareforquant/.config.vsh.yaml b/target/nextflow/umitools_prepareforquant/.config.vsh.yaml index f62bc3f..9437d39 100644 --- a/target/nextflow/umitools_prepareforquant/.config.vsh.yaml +++ b/target/nextflow/umitools_prepareforquant/.config.vsh.yaml @@ -147,7 +147,7 @@ build_info: output: "target/nextflow/umitools_prepareforquant" executable: "target/nextflow/umitools_prepareforquant/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" package_config: version: "main" diff --git a/target/nextflow/umitools_prepareforquant/main.nf b/target/nextflow/umitools_prepareforquant/main.nf index 3cab63f..9e5c365 100644 --- a/target/nextflow/umitools_prepareforquant/main.nf +++ b/target/nextflow/umitools_prepareforquant/main.nf @@ -2993,7 +2993,7 @@ meta = [ "engine" : "docker|native", "output" : "/workdir/root/repo/target/nextflow/umitools_prepareforquant", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/workflows/genome_alignment_and_quant/.config.vsh.yaml b/target/nextflow/workflows/genome_alignment_and_quant/.config.vsh.yaml index 1e0ab0d..144f973 100644 --- a/target/nextflow/workflows/genome_alignment_and_quant/.config.vsh.yaml +++ b/target/nextflow/workflows/genome_alignment_and_quant/.config.vsh.yaml @@ -398,26 +398,32 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_sort" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_index" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_stats" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_flagstat" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "samtools/samtools_idxstats" repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "umitools/umitools_dedup" repository: type: "local" @@ -428,6 +434,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" + tag: "v0.2.0" - name: "rsem/rsem_calculate_expression" repository: type: "local" @@ -435,6 +442,7 @@ repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -510,18 +518,18 @@ build_info: output: "target/nextflow/workflows/genome_alignment_and_quant" executable: "target/nextflow/workflows/genome_alignment_and_quant/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - - "target/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat" - - "target/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats" - "target/nextflow/umitools/umitools_dedup" - "target/nextflow/umitools_prepareforquant" - - "target/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant" - "target/nextflow/rsem/rsem_calculate_expression" package_config: version: "main" diff --git a/target/nextflow/workflows/genome_alignment_and_quant/main.nf b/target/nextflow/workflows/genome_alignment_and_quant/main.nf index 91d62e9..6e8d097 100644 --- a/target/nextflow/workflows/genome_alignment_and_quant/main.nf +++ b/target/nextflow/workflows/genome_alignment_and_quant/main.nf @@ -3266,42 +3266,48 @@ meta = [ "name" : "star/star_align_reads", "repository" : { "type" : "vsh", - "repo" : "vsh/biobox" + "repo" : "vsh/biobox", + "tag" : "v0.2.0" } }, { "name" : "samtools/samtools_sort", "repository" : { "type" : "vsh", - "repo" : "vsh/biobox" + "repo" : "vsh/biobox", + "tag" : "v0.2.0" } }, { "name" : "samtools/samtools_index", "repository" : { "type" : "vsh", - "repo" : "vsh/biobox" + "repo" : "vsh/biobox", + "tag" : "v0.2.0" } }, { "name" : "samtools/samtools_stats", "repository" : { "type" : "vsh", - "repo" : "vsh/biobox" + "repo" : "vsh/biobox", + "tag" : "v0.2.0" } }, { "name" : "samtools/samtools_flagstat", "repository" : { "type" : "vsh", - "repo" : "vsh/biobox" + "repo" : "vsh/biobox", + "tag" : "v0.2.0" } }, { "name" : "samtools/samtools_idxstats", "repository" : { "type" : "vsh", - "repo" : "vsh/biobox" + "repo" : "vsh/biobox", + "tag" : "v0.2.0" } }, { @@ -3320,7 +3326,8 @@ meta = [ "name" : "salmon/salmon_quant", "repository" : { "type" : "vsh", - "repo" : "vsh/biobox" + "repo" : "vsh/biobox", + "tag" : "v0.2.0" } }, { @@ -3334,7 +3341,8 @@ meta = [ { "type" : "vsh", "name" : "biobox", - "repo" : "vsh/biobox" + "repo" : "vsh/biobox", + "tag" : "v0.2.0" } ], "runners" : [ @@ -3423,7 +3431,7 @@ meta = [ "engine" : "native", "output" : "/workdir/root/repo/target/nextflow/workflows/genome_alignment_and_quant", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { @@ -3452,15 +3460,15 @@ meta = [ // resolve dependencies dependencies (if any) meta["root_dir"] = getRootDir() -include { star_align_reads } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/nextflow/star/star_align_reads/main.nf" -include { samtools_sort } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_sort/main.nf" -include { samtools_index } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_index/main.nf" -include { samtools_stats } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_stats/main.nf" -include { samtools_flagstat } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_flagstat/main.nf" -include { samtools_idxstats } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/nextflow/samtools/samtools_idxstats/main.nf" +include { star_align_reads } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_align_reads/main.nf" +include { samtools_sort } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/main.nf" +include { samtools_index } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/main.nf" +include { samtools_stats } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/main.nf" +include { samtools_flagstat } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/main.nf" +include { samtools_idxstats } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/main.nf" include { umitools_dedup } from "${meta.resources_dir}/../../../nextflow/umitools/umitools_dedup/main.nf" include { umitools_prepareforquant } from "${meta.resources_dir}/../../../nextflow/umitools_prepareforquant/main.nf" -include { salmon_quant } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/nextflow/salmon/salmon_quant/main.nf" +include { salmon_quant } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/main.nf" include { rsem_calculate_expression } from "${meta.resources_dir}/../../../nextflow/rsem/rsem_calculate_expression/main.nf" // inner workflow diff --git a/target/nextflow/workflows/merge_quant_results/.config.vsh.yaml b/target/nextflow/workflows/merge_quant_results/.config.vsh.yaml index 7ae9086..706204f 100644 --- a/target/nextflow/workflows/merge_quant_results/.config.vsh.yaml +++ b/target/nextflow/workflows/merge_quant_results/.config.vsh.yaml @@ -269,7 +269,7 @@ build_info: output: "target/nextflow/workflows/merge_quant_results" executable: "target/nextflow/workflows/merge_quant_results/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/tx2gene" diff --git a/target/nextflow/workflows/merge_quant_results/main.nf b/target/nextflow/workflows/merge_quant_results/main.nf index 11a173d..572b4c0 100644 --- a/target/nextflow/workflows/merge_quant_results/main.nf +++ b/target/nextflow/workflows/merge_quant_results/main.nf @@ -3135,7 +3135,7 @@ meta = [ "engine" : "native", "output" : "/workdir/root/repo/target/nextflow/workflows/merge_quant_results", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { diff --git a/target/nextflow/workflows/post_processing/.config.vsh.yaml b/target/nextflow/workflows/post_processing/.config.vsh.yaml index 6920600..6857119 100644 --- a/target/nextflow/workflows/post_processing/.config.vsh.yaml +++ b/target/nextflow/workflows/post_processing/.config.vsh.yaml @@ -369,27 +369,27 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "samtools/samtools_index" repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "samtools/samtools_stats" repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "samtools/samtools_flagstat" repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "samtools/samtools_idxstats" repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "stringtie" repository: type: "local" @@ -406,7 +406,7 @@ repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -482,15 +482,15 @@ build_info: output: "target/nextflow/workflows/post_processing" executable: "target/nextflow/workflows/post_processing/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/picard_markduplicates" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats" - "target/nextflow/stringtie" - "target/nextflow/bedtools_genomecov" - "target/nextflow/ucsc/bedclip" diff --git a/target/nextflow/workflows/post_processing/main.nf b/target/nextflow/workflows/post_processing/main.nf index 730fa75..b022e4a 100644 --- a/target/nextflow/workflows/post_processing/main.nf +++ b/target/nextflow/workflows/post_processing/main.nf @@ -3237,7 +3237,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } }, { @@ -3245,7 +3245,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } }, { @@ -3253,7 +3253,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } }, { @@ -3261,7 +3261,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } }, { @@ -3269,7 +3269,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } }, { @@ -3302,7 +3302,7 @@ meta = [ "type" : "vsh", "name" : "biobox", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } ], "runners" : [ @@ -3391,7 +3391,7 @@ meta = [ "engine" : "native", "output" : "/workdir/root/repo/target/nextflow/workflows/post_processing", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { @@ -3421,11 +3421,11 @@ meta = [ // resolve dependencies dependencies (if any) meta["root_dir"] = getRootDir() include { picard_markduplicates } from "${meta.resources_dir}/../../../nextflow/picard_markduplicates/main.nf" -include { samtools_sort } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_sort/main.nf" -include { samtools_index } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_index/main.nf" -include { samtools_stats } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_stats/main.nf" -include { samtools_flagstat } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_flagstat/main.nf" -include { samtools_idxstats } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/samtools/samtools_idxstats/main.nf" +include { samtools_sort } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_sort/main.nf" +include { samtools_index } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_index/main.nf" +include { samtools_stats } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_stats/main.nf" +include { samtools_flagstat } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_flagstat/main.nf" +include { samtools_idxstats } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/samtools/samtools_idxstats/main.nf" include { stringtie } from "${meta.resources_dir}/../../../nextflow/stringtie/main.nf" include { bedtools_genomecov } from "${meta.resources_dir}/../../../nextflow/bedtools_genomecov/main.nf" include { bedclip } from "${meta.resources_dir}/../../../nextflow/ucsc/bedclip/main.nf" diff --git a/target/nextflow/workflows/pre_processing/.config.vsh.yaml b/target/nextflow/workflows/pre_processing/.config.vsh.yaml index 19bfaaf..d7d35ec 100644 --- a/target/nextflow/workflows/pre_processing/.config.vsh.yaml +++ b/target/nextflow/workflows/pre_processing/.config.vsh.yaml @@ -551,7 +551,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "fq_subsample" repository: type: "local" @@ -559,12 +559,12 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -640,7 +640,7 @@ build_info: output: "target/nextflow/workflows/pre_processing" executable: "target/nextflow/workflows/pre_processing/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/fastqc" @@ -648,9 +648,9 @@ build_info: - "target/nextflow/trimgalore" - "target/nextflow/bbmap_bbsplit" - "target/nextflow/sortmerna" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp" - "target/nextflow/fq_subsample" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant" package_config: version: "main" info: diff --git a/target/nextflow/workflows/pre_processing/main.nf b/target/nextflow/workflows/pre_processing/main.nf index d37d4e2..17d30b1 100644 --- a/target/nextflow/workflows/pre_processing/main.nf +++ b/target/nextflow/workflows/pre_processing/main.nf @@ -3473,7 +3473,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } }, { @@ -3487,7 +3487,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } } ], @@ -3496,7 +3496,7 @@ meta = [ "type" : "vsh", "name" : "biobox", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } ], "runners" : [ @@ -3585,7 +3585,7 @@ meta = [ "engine" : "native", "output" : "/workdir/root/repo/target/nextflow/workflows/pre_processing", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { @@ -3619,9 +3619,9 @@ include { umitools_extract } from "${meta.resources_dir}/../../../nextflow/umito include { trimgalore } from "${meta.resources_dir}/../../../nextflow/trimgalore/main.nf" include { bbmap_bbsplit } from "${meta.resources_dir}/../../../nextflow/bbmap_bbsplit/main.nf" include { sortmerna } from "${meta.resources_dir}/../../../nextflow/sortmerna/main.nf" -include { fastp } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/fastp/main.nf" +include { fastp } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/fastp/main.nf" include { fq_subsample } from "${meta.resources_dir}/../../../nextflow/fq_subsample/main.nf" -include { salmon_quant } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/main.nf" +include { salmon_quant } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/main.nf" // inner workflow // user-provided Nextflow code diff --git a/target/nextflow/workflows/prepare_genome/.config.vsh.yaml b/target/nextflow/workflows/prepare_genome/.config.vsh.yaml index 9b61672..e1b1cbc 100644 --- a/target/nextflow/workflows/prepare_genome/.config.vsh.yaml +++ b/target/nextflow/workflows/prepare_genome/.config.vsh.yaml @@ -370,7 +370,7 @@ dependencies: repository: type: "vsh" repo: "biobox" - tag: "main" + tag: "v0.2.0" - name: "cat_additional_fasta" repository: type: "local" @@ -387,7 +387,7 @@ dependencies: repository: type: "vsh" repo: "biobox" - tag: "main" + tag: "v0.2.0" - name: "getchromsizes" repository: type: "local" @@ -395,12 +395,12 @@ dependencies: repository: type: "vsh" repo: "craftbox" - tag: "main" + tag: "v0.1.0" - name: "star/star_genome_generate" repository: type: "vsh" repo: "biobox" - tag: "main" + tag: "v0.2.0" - name: "bbmap_bbsplit" repository: type: "local" @@ -408,7 +408,7 @@ dependencies: repository: type: "vsh" repo: "biobox" - tag: "main" + tag: "v0.2.0" - name: "kallisto/kallisto_index" repository: type: "local" @@ -416,11 +416,11 @@ repositories: - type: "vsh" name: "biobox" repo: "biobox" - tag: "main" + tag: "v0.2.0" - type: "vsh" name: "craftbox" repo: "craftbox" - tag: "main" + tag: "v0.1.0" runners: - type: "executable" id: "executable" @@ -496,21 +496,21 @@ build_info: output: "target/nextflow/workflows/prepare_genome" executable: "target/nextflow/workflows/prepare_genome/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/gunzip" - - "target/dependencies/vsh/vsh/biobox/main/nextflow/gffread" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread" - "target/nextflow/cat_additional_fasta" - "target/nextflow/gtf2bed" - "target/nextflow/preprocess_transcripts_fasta" - "target/nextflow/gtf_filter" - - "target/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference" - "target/nextflow/getchromsizes" - - "target/dependencies/vsh/vsh/craftbox/main/nextflow/untar" - - "target/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate" + - "target/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate" - "target/nextflow/bbmap_bbsplit" - - "target/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index" - "target/nextflow/kallisto/kallisto_index" package_config: version: "main" diff --git a/target/nextflow/workflows/prepare_genome/main.nf b/target/nextflow/workflows/prepare_genome/main.nf index a5d54b2..61a9b72 100644 --- a/target/nextflow/workflows/prepare_genome/main.nf +++ b/target/nextflow/workflows/prepare_genome/main.nf @@ -3229,7 +3229,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "biobox", - "tag" : "main" + "tag" : "v0.2.0" } }, { @@ -3261,7 +3261,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "biobox", - "tag" : "main" + "tag" : "v0.2.0" } }, { @@ -3275,7 +3275,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "craftbox", - "tag" : "main" + "tag" : "v0.1.0" } }, { @@ -3283,7 +3283,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "biobox", - "tag" : "main" + "tag" : "v0.2.0" } }, { @@ -3297,7 +3297,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "biobox", - "tag" : "main" + "tag" : "v0.2.0" } }, { @@ -3312,13 +3312,13 @@ meta = [ "type" : "vsh", "name" : "biobox", "repo" : "biobox", - "tag" : "main" + "tag" : "v0.2.0" }, { "type" : "vsh", "name" : "craftbox", "repo" : "craftbox", - "tag" : "main" + "tag" : "v0.1.0" } ], "runners" : [ @@ -3407,7 +3407,7 @@ meta = [ "engine" : "native", "output" : "/workdir/root/repo/target/nextflow/workflows/prepare_genome", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { @@ -3437,17 +3437,17 @@ meta = [ // resolve dependencies dependencies (if any) meta["root_dir"] = getRootDir() include { gunzip } from "${meta.resources_dir}/../../../nextflow/gunzip/main.nf" -include { gffread } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/main/nextflow/gffread/main.nf" +include { gffread } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/gffread/main.nf" include { cat_additional_fasta } from "${meta.resources_dir}/../../../nextflow/cat_additional_fasta/main.nf" include { gtf2bed } from "${meta.resources_dir}/../../../nextflow/gtf2bed/main.nf" include { preprocess_transcripts_fasta } from "${meta.resources_dir}/../../../nextflow/preprocess_transcripts_fasta/main.nf" include { gtf_filter } from "${meta.resources_dir}/../../../nextflow/gtf_filter/main.nf" -include { rsem_prepare_reference } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/main/nextflow/rsem/rsem_prepare_reference/main.nf" +include { rsem_prepare_reference } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/rsem/rsem_prepare_reference/main.nf" include { getchromsizes } from "${meta.resources_dir}/../../../nextflow/getchromsizes/main.nf" -include { untar } from "${meta.root_dir}/dependencies/vsh/vsh/craftbox/main/nextflow/untar/main.nf" -include { star_genome_generate } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/main/nextflow/star/star_genome_generate/main.nf" +include { untar } from "${meta.root_dir}/dependencies/vsh/vsh/craftbox/v0.1.0/nextflow/untar/main.nf" +include { star_genome_generate } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/star/star_genome_generate/main.nf" include { bbmap_bbsplit } from "${meta.resources_dir}/../../../nextflow/bbmap_bbsplit/main.nf" -include { salmon_index } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/main/nextflow/salmon/salmon_index/main.nf" +include { salmon_index } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_index/main.nf" include { kallisto_index } from "${meta.resources_dir}/../../../nextflow/kallisto/kallisto_index/main.nf" // inner workflow diff --git a/target/nextflow/workflows/pseudo_alignment_and_quant/.config.vsh.yaml b/target/nextflow/workflows/pseudo_alignment_and_quant/.config.vsh.yaml index 7e073f5..bf4c943 100644 --- a/target/nextflow/workflows/pseudo_alignment_and_quant/.config.vsh.yaml +++ b/target/nextflow/workflows/pseudo_alignment_and_quant/.config.vsh.yaml @@ -197,7 +197,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "kallisto/kallisto_quant" repository: type: "local" @@ -205,7 +205,7 @@ repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -281,10 +281,10 @@ build_info: output: "target/nextflow/workflows/pseudo_alignment_and_quant" executable: "target/nextflow/workflows/pseudo_alignment_and_quant/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant" - "target/nextflow/kallisto/kallisto_quant" package_config: version: "main" diff --git a/target/nextflow/workflows/pseudo_alignment_and_quant/main.nf b/target/nextflow/workflows/pseudo_alignment_and_quant/main.nf index 55023c6..250b3c9 100644 --- a/target/nextflow/workflows/pseudo_alignment_and_quant/main.nf +++ b/target/nextflow/workflows/pseudo_alignment_and_quant/main.nf @@ -3036,7 +3036,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } }, { @@ -3051,7 +3051,7 @@ meta = [ "type" : "vsh", "name" : "biobox", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } ], "runners" : [ @@ -3140,7 +3140,7 @@ meta = [ "engine" : "native", "output" : "/workdir/root/repo/target/nextflow/workflows/pseudo_alignment_and_quant", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { @@ -3169,7 +3169,7 @@ meta = [ // resolve dependencies dependencies (if any) meta["root_dir"] = getRootDir() -include { salmon_quant } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/salmon/salmon_quant/main.nf" +include { salmon_quant } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/salmon/salmon_quant/main.nf" include { kallisto_quant } from "${meta.resources_dir}/../../../nextflow/kallisto/kallisto_quant/main.nf" // inner workflow diff --git a/target/nextflow/workflows/quality_control/.config.vsh.yaml b/target/nextflow/workflows/quality_control/.config.vsh.yaml index 071952f..5f3e609 100644 --- a/target/nextflow/workflows/quality_control/.config.vsh.yaml +++ b/target/nextflow/workflows/quality_control/.config.vsh.yaml @@ -1490,7 +1490,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "multiqc_custom_biotype" repository: type: "local" @@ -1504,7 +1504,7 @@ dependencies: repository: type: "vsh" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" - name: "workflows/merge_quant_results" repository: type: "local" @@ -1512,7 +1512,7 @@ repositories: - type: "vsh" name: "biobox" repo: "vsh/biobox" - tag: "v0.1" + tag: "v0.2.0" runners: - type: "executable" id: "executable" @@ -1588,7 +1588,7 @@ build_info: output: "target/nextflow/workflows/quality_control" executable: "target/nextflow/workflows/quality_control/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/rseqc/rseqc_bamstat" @@ -1602,11 +1602,11 @@ build_info: - "target/nextflow/dupradar" - "target/nextflow/qualimap" - "target/nextflow/preseq_lcextrap" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts" - "target/nextflow/multiqc_custom_biotype" - "target/nextflow/deseq2_qc" - "target/nextflow/prepare_multiqc_input" - - "target/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc" + - "target/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc" - "target/nextflow/workflows/merge_quant_results" package_config: version: "main" diff --git a/target/nextflow/workflows/quality_control/main.nf b/target/nextflow/workflows/quality_control/main.nf index 06c825e..97392a9 100644 --- a/target/nextflow/workflows/quality_control/main.nf +++ b/target/nextflow/workflows/quality_control/main.nf @@ -4533,7 +4533,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } }, { @@ -4559,7 +4559,7 @@ meta = [ "repository" : { "type" : "vsh", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } }, { @@ -4574,7 +4574,7 @@ meta = [ "type" : "vsh", "name" : "biobox", "repo" : "vsh/biobox", - "tag" : "v0.1" + "tag" : "v0.2.0" } ], "runners" : [ @@ -4663,7 +4663,7 @@ meta = [ "engine" : "native", "output" : "/workdir/root/repo/target/nextflow/workflows/quality_control", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : { @@ -4703,11 +4703,11 @@ include { rseqc_tin } from "${meta.resources_dir}/../../../nextflow/rseqc/rseqc_ include { dupradar } from "${meta.resources_dir}/../../../nextflow/dupradar/main.nf" include { qualimap } from "${meta.resources_dir}/../../../nextflow/qualimap/main.nf" include { preseq_lcextrap } from "${meta.resources_dir}/../../../nextflow/preseq_lcextrap/main.nf" -include { featurecounts } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/featurecounts/main.nf" +include { featurecounts } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/featurecounts/main.nf" include { multiqc_custom_biotype } from "${meta.resources_dir}/../../../nextflow/multiqc_custom_biotype/main.nf" include { deseq2_qc } from "${meta.resources_dir}/../../../nextflow/deseq2_qc/main.nf" include { prepare_multiqc_input } from "${meta.resources_dir}/../../../nextflow/prepare_multiqc_input/main.nf" -include { multiqc } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.1/nextflow/multiqc/main.nf" +include { multiqc } from "${meta.root_dir}/dependencies/vsh/vsh/biobox/v0.2.0/nextflow/multiqc/main.nf" include { merge_quant_results } from "${meta.resources_dir}/../../../nextflow/workflows/merge_quant_results/main.nf" // inner workflow diff --git a/target/nextflow/workflows/rnaseq/.config.vsh.yaml b/target/nextflow/workflows/rnaseq/.config.vsh.yaml index 6f2f886..5a75178 100644 --- a/target/nextflow/workflows/rnaseq/.config.vsh.yaml +++ b/target/nextflow/workflows/rnaseq/.config.vsh.yaml @@ -1956,7 +1956,7 @@ build_info: output: "target/nextflow/workflows/rnaseq" executable: "target/nextflow/workflows/rnaseq/main.nf" viash_version: "0.9.0" - git_commit: "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c" + git_commit: "cb9b32883494c48f394213551a82e9103f2e620c" git_remote: "https://github.com/viash-hub/rnaseq" dependencies: - "target/nextflow/workflows/prepare_genome" diff --git a/target/nextflow/workflows/rnaseq/main.nf b/target/nextflow/workflows/rnaseq/main.nf index d9af87a..533d062 100644 --- a/target/nextflow/workflows/rnaseq/main.nf +++ b/target/nextflow/workflows/rnaseq/main.nf @@ -5089,7 +5089,7 @@ meta = [ "engine" : "native", "output" : "/workdir/root/repo/target/nextflow/workflows/rnaseq", "viash_version" : "0.9.0", - "git_commit" : "1e1ffb315fefec05db2ee0c62e1c98ce4b49929c", + "git_commit" : "cb9b32883494c48f394213551a82e9103f2e620c", "git_remote" : "https://github.com/viash-hub/rnaseq" }, "package_config" : {