### Basic Workflow with Unchained Tasks Source: https://github.com/openwdl/cookbook/blob/main/recipes/01-chain-tasks-together.md Illustrates a WDL workflow with two independent tasks, task_A and task_B, showing the initial setup before chaining. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref File my_input String name } call task_A { input: ref = my_ref, in = my_input, id = name } call task_B { input: ref = my_ref, in = my_input, id = name } } task task_A {...} task task_B {...} ``` -------------------------------- ### Scatter-Gather Parallelism Example Source: https://github.com/openwdl/cookbook/blob/main/recipes/09-scattering-index.md Demonstrates scattering elements from multiple arrays using the `scatter()` function and `range()` for indexing. It also includes a task to validate that input arrays have the same length. ```wdl version 1.0 task checkInputArrays { input { Array[Int] array1 Array[Int] array2 } command { if [ ${length(array1)} -ne ${length(array2)} ]; then echo "Error: Input arrays do not have the same length." exit 1 fi } output { String status } runtime { docker: "ubuntu:latest" } } workflow scatterExample { input { Array[Int] data1 Array[Int] data2 } call checkInputArrays { input: array1 = data1, array2 = data2 } scatter (i in range(length(data1))) { call processElement { input: element1 = data1[i], element2 = data2[i] } } } task processElement { input { Int element1 Int element2 } command { echo "Processing ${element1} and ${element2}" } output { String result } } ``` -------------------------------- ### WDL Workflow with Conditional Task Execution Source: https://github.com/openwdl/cookbook/blob/main/recipes/07-conditional-input-type.md This WDL code demonstrates a workflow that scatters input files and conditionally calls tasks based on file extensions. It uses `basename()` to get the filename and `sub()` within `if()` statements to check for '.fastq' extension, routing files to `task_A` or `task_B` accordingly. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref Array[File] my_input String name } scatter (file in my_input) { # Returns filename of each input file and saves it to the variable `file_extension` String file_extension = basename(file) # If file has extension `fastq`, remove the extension such that the returned string does not match `file_extension`, then run `task_A` if (sub(file_extension, "fastq", "") != file_extension) { call task_A { input: ref = my_ref, in = file, id = name } } # If file does not have extension `fastq`, do not remove the extension such that the returned string matches `file_extension`, then run `task_B` if (sub(file_extension, "fastq", "") == file_extension) { call task_B { input: ref = my_ref, in = file, id = name } } } } task task_A {...} task task_B {...} ``` -------------------------------- ### Optimus Workflow with Branch and Merge Source: https://github.com/openwdl/cookbook/blob/main/recipes/02-multipath-branch-and-merge.md This WDL code defines the Optimus workflow, showcasing how to branch into parallel tasks (CalculateGeneMetrics and CalculateCellMetrics) and then merge their outputs into a subsequent task (OptimusLoomGeneration). It includes inputs for sequencing data and organism references. ```wdl version 1.0 workflow Optimus { input { # Mode for counting either "sc_rna" or "sn_rna" String counting_mode = "sc_rna" # Sequencing data inputs String input_id String? input_name String? input_id_metadata_field String? Input_name_metadata_field # organism reference parameters File annotations_gtf File? Mt_genes } call Metrics.CalculateGeneMetrics as GeneMetrics { input: bam_input = MergeBam.output_bam, mt_genes = mt_genes } call Metrics.CalculateCellMetrics as CellMetrics { input: bam_input = MergeBam.output_bam, mt_genes = mt_genes, original_gtf = annotations_gtf } call LoomUtils.OptimusLoomGeneration { input: input_id = input_id, input_name = input_name, input_id_metadata_field = input_id_metadata_field, input_name_metadata_field = input_name_metadata_field, annotation_file = annotations_gtf, cell_metrics = CellMetrics.cell_metrics, gene_metrics = GeneMetrics.gene_metrics, sparse_count_matrix = MergeStarOutputs.sparse_counts, cell_id = MergeStarOutputs.row_index, gene_id = MergeStarOutputs.col_index, empty_drops_result = RunEmptyDrops.empty_drops_result, counting_mode = counting_mode, pipeline_version = "Optimus_v~{pipeline_version}" } } ``` -------------------------------- ### Initial WDL Workflow Structure (Before Conditionals) Source: https://github.com/openwdl/cookbook/blob/main/recipes/03-multipath-conditionals.md Shows a basic WDL workflow structure where both task_A and task_B are called unconditionally. This serves as a baseline before introducing conditional logic. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref File my_input String name String mode } call task_A { input: ref = my_ref, in = my_input, id = name } call task_B { input: ref = my_ref, in = my_input, id = name } } task task_A {...} task task_B {...} ``` -------------------------------- ### WDL Workflow with Individual File Inputs Source: https://github.com/openwdl/cookbook/blob/main/recipes/11-using-structs.md This WDL code snippet demonstrates a workflow where multiple related files are passed as individual inputs to tasks. It highlights the verbosity that structs aim to reduce. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref_1 File my_ref_2 File my_ref_3 File my_input String name } call task_A { input: ref_1 = my_ref_1, ref_2 = my_ref_2, ref_3 = my_ref_3 } call task_B { input: ref_1 = my_ref_1, ref_2 = my_ref_2, ref_3 = my_ref_3, in = my_input, id = name } } task task_A {...} task task_B {...} ``` -------------------------------- ### WDL Struct Definitions for DNA Sequencing Source: https://github.com/openwdl/cookbook/blob/main/recipes/11-using-structs.md This WDL script defines several structs used for organizing DNA sequencing input parameters. It includes definitions for SampleAndUnmappedBams, DragmapReference, DNASeqSingleSampleReferences, and PapiSettings, specifying the types and structure of each input group. ```wdl version 1.0 struct SampleAndUnmappedBams { String base_file_name String? final_gvcf_base_name Array[File] flowcell_unmapped_bams String sample_name String unmapped_bam_suffix } struct DragmapReference { File reference_bin File hash_table_cfg_bin File hash_table_cmp } struct DNASeqSingleSampleReferences { File contamination_sites_ud File contamination_sites_bed File contamination_sites_mu File calling_interval_list ReferenceFasta reference_fasta Array[File] known_indels_sites_vcfs Array[File] known_indels_sites_indices File dbsnp_vcf File dbsnp_vcf_index File evaluation_interval_list File haplotype_database_file } struct PapiSettings { Int preemptible_tries Int agg_preemptible_tries } ``` -------------------------------- ### Initial WDL Workflow Structure Source: https://github.com/openwdl/cookbook/blob/main/recipes/10-scattering-optional.md This WDL code shows the initial structure of a workflow before implementing optional input scattering. It defines inputs and a scatter block but lacks the logic for handling optional arrays. ```wdl version 1.0 workflow myWorkflowName { input { Array[File]? my_ref Array[File] my_input String name } scatter (idx in range(length(my_input))) { call task_A { input: ref = my_ref, in = my_input[idx], id = name } } } task task_A {...} ``` -------------------------------- ### WDL Workflow with Conditional Task Execution Source: https://github.com/openwdl/cookbook/blob/main/recipes/03-multipath-conditionals.md Demonstrates a WDL workflow where either task_A or task_B is executed based on the 'mode' input. It uses 'if' statements for conditional execution and 'select_first' to merge the outputs for a subsequent task. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref File my_input String name String mode } if (mode == ‘path_A’) { call task_A { input: ref = my_ref, in = my_input, id = name } } if (mode == ‘path_B’) { call task_B { input: ref = my_ref, in = my_input, id = name } } call task_C { input: in = select_first([task_A.output, task_B.output]) } } task task_A {...} task task_B {...} task task_C {...} ``` -------------------------------- ### Basic Scatter on Array Source: https://github.com/openwdl/cookbook/blob/main/recipes/09-scattering-index.md This WDL code snippet demonstrates a basic scatter operation on a single array 'my_input'. It calls 'task_A' for each element in the array. ```wdl version 1.0 workflow myWorkflowName { input { Array[File] my_ref Array[File] my_input String name } scatter (file in my_input) { call task_A { input: ref = my_ref, in = file, id = name } } } task task_A {...} ``` -------------------------------- ### WDL Workflow with Parallel Branching Source: https://github.com/openwdl/cookbook/blob/main/recipes/02-multipath-branch-and-merge.md This WDL code defines a workflow where 'task_A' output is used as input for both 'task_B' and 'task_C', creating two parallel execution paths. It then shows how to merge the outputs of 'task_B' and 'task_C' into 'task_D'. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref File my_input String name String mode } call task_A { input: ref = my_ref, in = my_input, id = name } call task_B { input: ref = my_ref, in = task_A.out_A, id = name } call task_C { input: ref = my_ref, in = task_A.out_A, id = name } call task_D { input: in_B = task_B.out_B, in_C = task_C.out_C } } task task_A {...} task task_B {...} task task_C {...} task task_D {...} ``` -------------------------------- ### WDL Workflow with Optional Input Scattering Source: https://github.com/openwdl/cookbook/blob/main/recipes/10-scattering-optional.md This WDL code demonstrates scattering over a non-optional array (`my_input`) and conditionally scattering an optional array (`my_ref`) using `select_first()` and `defined()`. ```wdl version 1.0 workflow myWorkflowName { input { Array[File]? my_ref Array[File] my_input String name } if (false) { String? none = "None" } scatter (idx in range(length(my_input))) { call task_A { input: ref = if defined(my_ref) then select_first([my_ref])[idx] else none, in = my_input[idx], id = name } } } task task_A {...} ``` -------------------------------- ### Optimus Workflow with Conditional File Processing Source: https://github.com/openwdl/cookbook/blob/main/recipes/05-conditionals-input-size.md This WDL workflow defines the Optimus pipeline, which processes single-cell sequencing data. It includes logic to conditionally split input FASTQ files based on their total size (greater than 30 GiB) and execute tasks accordingly. It utilizes scatter-gather for parallel processing when files are split and calls tasks for STARsolo alignment and BAM merging. ```wdl version 1.0 workflow Optimus { input { # Mode for counting either "sc_rna" or "sn_rna" String counting_mode = "sc_rna" # Sequencing data inputs Array[File] r1_fastq Array[File] r2_fastq Array[File]? i1_fastq String input_id String output_bam_basename = input_id # organism reference parameters File tar_star_reference # 10x parameters File whitelist # tenX_v2, tenX_v3 String chemistry = "tenX_v2" # Set to true to count reads aligned to exonic regions in sn_rna mode Boolean count_exons = false } # Get the size of the input fastq files with `size()` function and round up to the nearest integer with the `ceil()` function Int fastq_input_size = ceil(size(r1_fastq, "Gi") ) + ceil(size(r2_fastq, "Gi")) # Check whether the combined size of the input fastq files is larger than 30 Gi Boolean split_fastqs = if ( fastq_input_size > 30 ) then true else false # Run the following three tasks only if `split_fastqs` is true if ( split_fastqs ) { # Split the input fastq into multiple fastq files call FastqProcessing.FastqProcessing as SplitFastq { input: i1_fastq = i1_fastq, r1_fastq = r1_fastq, r2_fastq = r2_fastq, whitelist = whitelist, chemistry = chemistry, sample_id = input_id } # Scatter the fastq files and call STARsolo in parallel scatter(idx in range(length(SplitFastq.fastq_R1_output_array))) { call StarAlign.STARsoloFastq as STARsoloFastq { input: r1_fastq = [SplitFastq.fastq_R1_output_array[idx]], r2_fastq = [SplitFastq.fastq_R2_output_array[idx]], white_list = whitelist, tar_star_reference = tar_star_reference, chemistry = chemistry, counting_mode = counting_mode, count_exons = count_exons, output_bam_basename = output_bam_basename + "_" + idx } } # Merge the bam files from the previous task call Merge.MergeSortBamFiles as MergeBam { input: bam_inputs = STARsoloFastq.bam_output, output_bam_filename = output_bam_basename + ".bam", sort_order = "coordinate" } } # Run the following task only if `split_fastqs` is false if ( !split_fastqs ) { # Call STARsolo to analyze a single fastq call StarAlign.STARsoloFastq as STARsoloFastqSingle { input: r1_fastq = r1_fastq, r2_fastq = r2_fastq, white_list = whitelist, tar_star_reference = tar_star_reference, chemistry = chemistry, counting_mode = counting_mode, count_exons = count_exons, output_bam_basename = output_bam_basename } } } ``` -------------------------------- ### Optimus Workflow Definition Source: https://github.com/openwdl/cookbook/blob/main/recipes/01-chain-tasks-together.md Defines the Optimus WDL workflow, including inputs, task calls, and outputs. It demonstrates how the output of MergeBam is used as input for GeneMetrics and CellMetrics. ```wdl version 1.0 workflow Optimus { input { # Mode for counting either "sc_rna" or "sn_rna" String counting_mode = "sc_rna" # Sequencing data inputs String input_id String output_bam_basename = input_id String? input_name String? input_id_metadata_field String? input_name_metadata_field # organism reference parameters File annotations_gtf } call Merge.MergeSortBamFiles as MergeBam { input: bam_inputs = STARsoloFastq.bam_output, output_bam_filename = output_bam_basename + ".bam", sort_order = "coordinate" } call Metrics.CalculateGeneMetrics as GeneMetrics { input: bam_input = MergeBam.output_bam } call Metrics.CalculateCellMetrics as CellMetrics { input: bam_input = MergeBam.output_bam, original_gtf = annotations_gtf } call LoomUtils.OptimusLoomGeneration { input: input_id = input_id, input_name = input_name, input_id_metadata_field = input_id_metadata_field, input_name_metadata_field = input_name_metadata_field, annotation_file = annotations_gtf, cell_metrics = CellMetrics.cell_metrics, gene_metrics = GeneMetrics.gene_metrics, sparse_count_matrix = MergeStarOutputs.sparse_counts, cell_id = MergeStarOutputs.row_index, gene_id = MergeStarOutputs.col_index, empty_drops_result = RunEmptyDrops.empty_drops_result, counting_mode = counting_mode, pipeline_version = "Optimus_v~{pipeline_version}" } output { File cell_metrics = CellMetrics.cell_metrics File gene_metrics = GeneMetrics.gene_metrics } } ``` -------------------------------- ### WDL Workflow Using Structs for Grouped Inputs Source: https://github.com/openwdl/cookbook/blob/main/recipes/11-using-structs.md This WDL code snippet shows an improved workflow that utilizes a struct to group related input files. This simplifies the input declarations in the workflow and task calls. ```wdl version 1.0 workflow myWorkflowName { input { ref_files my_refs File my_input String name } call task_A { input: my_refs = my_refs } call task_B { input: my_refs = my_refs, in = my_input, id = name } } task task_A {...} task task_B {...} struct ref_files { File ref_1 File ref_2 File ref_3 } ``` -------------------------------- ### WGS Pipeline Workflow with Struct Inputs Source: https://github.com/openwdl/cookbook/blob/main/recipes/11-using-structs.md This WDL workflow defines inputs using structs like SampleAndUnmappedBams, DNASeqSingleSampleReferences, DragmapReference, and PapiSettings. It demonstrates calling a task 'UnmappedBamToAlignedBam' and accessing struct members using dot notation. ```wdl version 1.0 import "../../../../../../structs/dna_seq/DNASeqStructs.wdl" workflow WholeGenomeGermlineSingleSample { input { SampleAndUnmappedBams sample_and_unmapped_bams DNASeqSingleSampleReferences references DragmapReference? dragmap_reference PapiSettings papi_settings } call ToBam.UnmappedBamToAlignedBam { input: sample_and_unmapped_bams = sample_and_unmapped_bams, references = references, dragmap_reference = dragmap_reference, papi_settings = papi_settings, contamination_sites_ud = references.contamination_sites_ud, contamination_sites_bed = references.contamination_sites_bed, contamination_sites_mu = references.contamination_sites_mu } } ``` -------------------------------- ### OptimusLoomGeneration Task with Conditional Inputs Source: https://github.com/openwdl/cookbook/blob/main/recipes/04-different-parameters.md Defines the 'OptimusLoomGeneration' task, including optional inputs. It demonstrates how to conditionally pass optional inputs to a Python script using WDL's expression syntax, ensuring they are only included if defined. ```wdl version 1.0 task OptimusLoomGeneration { input { #runtime values String docker = "us.gcr.io/broad-gotc-prod/pytools:1.0.0-1661263730" # name of the sample String input_id # user provided id String? input_name String? input_id_metadata_field String? input_name_metadata_field # gene annotation file in GTF format File annotation_file # the file "merged-cell-metrics.csv.gz" that contains the cellwise metrics File cell_metrics # the file "merged-gene-metrics.csv.gz" that contains the genwise metrics File gene_metrics # file (.npz) that contains the count matrix File sparse_count_matrix # file (.npy) that contains the array of cell barcodes File cell_id # file (.npy) that contains the array of gene names File gene_id # emptydrops output metadata File? empty_drops_result String counting_mode = "sc_rna" String pipeline_version Int preemptible = 3 Int disk = 200 Int machine_mem_mb = 18 Int cpu = 4 } command <<< set -euo pipefail if [ "~{counting_mode}" == "sc_rna" ]; then python3 /usr/gitc/create_loom_optimus.py \ --empty_drops_file ~{empty_drops_result} \ --add_emptydrops_data "yes" \ ``` -------------------------------- ### WDL Workflow with Conditional Task Execution Source: https://github.com/openwdl/cookbook/blob/main/recipes/05-conditionals-input-size.md This WDL script demonstrates a workflow that conditionally executes either `task_A` or `task_B` based on the size of the `my_input` file compared to a specified `input_size_cutoff_mb`. It utilizes `if()` statements and the `size()` function to control task execution flow. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref File my_input String name # Specifies the cutoff size in megabytes for the following `if()` statements Float input_size_cutoff_mb } # Only run `task_A` if the size of `my_input` in megabytes is larger than the size # of the cutoff if (size(my_input, "MB") > input_size_cutoff_mb) { call task_A { input: ref = my_ref, in = my_input, id = name } } # Only run `task_B` if the size of `my_input` in megabytes is smaller than or equal # to the size of the cutoff if (size(my_input, "MB") <= input_size_cutoff_mb) { call task_B { input: ref = my_ref, in = my_input, id = name } } } task task_A {...} task task_B {...} ``` -------------------------------- ### Create snRNA Optimus Python Command Source: https://github.com/openwdl/cookbook/blob/main/recipes/04-different-parameters.md This snippet shows how to construct a Python command for the create_snrna_optimus.py script, conditionally including parameters based on their definition. It demonstrates the use of WDL's string interpolation and conditional logic to build the command. ```WDL if is_tenx_v3 then python3 /usr/gitc/create_snrna_optimus.py \ --annotation_file ~{annotation_file} \ --cell_metrics ~{cell_metrics} \ --gene_metrics ~{gene_metrics} \ --cell_id ~{cell_id} \ --gene_id ~{gene_id} \ --output_path_for_loom "~{input_id}.loom" \ --input_id ~{input_id} \ ~{"--input_name " + input_name} \ ~{"--input_id_metadata_field " + input_id_metadata_field} \ ~{"--input_name_metadata_field " + input_name_metadata_field} \ --count_matrix ~{sparse_count_matrix} \ --expression_data_type "exonic" \ --pipeline_version ~{pipeline_version} else python3 /usr/gitc/create_snrna_optimus.py \ --annotation_file ~{annotation_file} \ --cell_metrics ~{cell_metrics} \ --gene_metrics ~{gene_metrics} \ --cell_id ~{cell_id} \ --gene_id ~{gene_id} \ --output_path_for_loom "~{input_id}.loom" \ --input_id ~{input_id} \ ~{"--input_name " + input_name} \ ~{"--input_id_metadata_field " + input_id_metadata_field} \ ~{"--input_name_metadata_field " + input_name_metadata_field} \ --count_matrix ~{sparse_count_matrix} \ --expression_data_type "whole_transcript"\ --pipeline_version ~{pipeline_version} fi ``` -------------------------------- ### WDL Runtime Block Source: https://github.com/openwdl/cookbook/blob/main/recipes/04-different-parameters.md This snippet defines the runtime attributes for a WDL task, including docker image, CPU, memory, disk space, and preemptibility. These attributes control the execution environment of the task. ```WDL runtime { docker: docker cpu: cpu # note that only 1 thread is supported by pseudobam memory: "~{machine_mem_mb} GiB" disks: "local-disk ~{disk} HDD" preemptible: preemptible } ``` -------------------------------- ### WDL Workflow with Scatter Block Source: https://github.com/openwdl/cookbook/blob/main/recipes/08-scattering_array.md This WDL code demonstrates how to parallelize a workflow by scattering an input array. The 'scatter' block iterates over each 'file' in the 'my_input' array, executing 'task_A' for each file in parallel. The output of 'task_A' is implicitly collected into an array for subsequent tasks. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref Array[File] my_input String name } scatter (file in my_input) { call task_A { input: ref = my_ref, in = file, id = name } } call task_B { input: ref = my_ref, in = task_A.out, id = name } } task task_A {...} task task_B {...} ``` -------------------------------- ### Conditionally Include Annotations with True/False Placeholder in WDL Source: https://github.com/openwdl/cookbook/blob/main/recipes/04-different-parameters.md This snippet demonstrates how to conditionally include a command-line argument based on the definition of a boolean variable using the true/false expression placeholder. If `use_allele_specific_annotations` is defined and true, the argument is included; otherwise, it is omitted. ```WDL version 1.0 ~{true='--use-allele-specific-annotations' false='' use_allele_specific_annotations} ``` -------------------------------- ### Initial WDL Workflow Structure (Before Conditional Logic) Source: https://github.com/openwdl/cookbook/blob/main/recipes/07-conditional-input-type.md This WDL code represents the initial structure of a workflow where input files are scattered across two tasks, `task_A` and `task_B`, without any conditional logic based on file properties. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref Array[File] my_input String name } scatter (file in my_input) { call task_A { input: ref = my_ref, in = file, id = name } call task_B { input: ref = my_ref, in = file, id = name } } } task task_A {...} task task_B {...} ``` -------------------------------- ### Passing Scattered Outputs to Another Task Source: https://github.com/openwdl/cookbook/blob/main/recipes/09-scattering-index.md This WDL code demonstrates how to pass the results of a scatter block (an array of files) as input to another task ('task_B'). WDL automatically handles the gathering of results from the scatter. ```wdl version 1.0 workflow myWorkflowName { input { Array[File] my_ref Array[File] my_input String name } scatter (idx in range(length(my_input))) { call task_A { input: ref = my_ref[idx], in = my_input[idx], id = name } } call task_B { input: in_file = task_A.output_file } } task task_A { output { File output_file = "~{id}.ext" } } task task_B { input { Array[File] in_file } } ``` -------------------------------- ### WDL Imputation Workflow with Scatter-Gather Source: https://github.com/openwdl/cookbook/blob/main/recipes/08-scattering_array.md This WDL 1.0 workflow defines the Imputation pipeline, which scatters tasks based on an input array of contigs. It demonstrates how to construct file paths, define structs for reference panel information, and call tasks within a scatter block. The workflow also shows how outputs from scattered tasks are implicitly handled as arrays when passed to subsequent tasks. ```wdl version 1.0 workflow Imputation { input { File ref_dict # for reheadering / adding contig lengths in the header of the ouptut VCF, and calculating contig lengths Array[String] contigs String reference_panel_path # path to the bucket where the reference panel files are stored for all contigs # file extensions used to find reference panel files String vcf_suffix = ".vcf.gz" String vcf_index_suffix = ".vcf.gz.tbi" String bcf_suffix = ".bcf" String bcf_index_suffix = ".bcf.csi" String m3vcf_suffix = ".cleaned.m3vcf.gz" } scatter (contig in contigs) { String reference_filename = reference_panel_path + "ALL.chr" + contig + ".phase3_integrated.20130502.genotypes.cleaned" ReferencePanelContig referencePanelContig = { "vcf": reference_filename + vcf_suffix, "vcf_index": reference_filename + vcf_index_suffix, "bcf": reference_filename + bcf_suffix, "bcf_index": reference_filename + bcf_index_suffix, "m3vcf": reference_filename + m3vcf_suffix, "contig": contig } call tasks.CountVariantsInChunks { input: vcf = select_first([OptionalQCSites.output_vcf, GenerateChunk.output_vcf]), vcf_index = select_first([OptionalQCSites.output_vcf_index, GenerateChunk.output_vcf_index]), panel_vcf = referencePanelContig.vcf, panel_vcf_index = referencePanelContig.vcf_index } } call tasks.StoreChunksInfo { input: chroms = flatten(chunk_contig), starts = flatten(start), ends = flatten(end), vars_in_array = flatten(CountVariantsInChunks.var_in_original), vars_in_panel = flatten(CountVariantsInChunks.var_in_reference), valids = flatten(CheckChunks.valid), basename = output_callset_name } } ``` -------------------------------- ### WDL Workflow for Multi-Sample Smart-Seq2 Source: https://github.com/openwdl/cookbook/blob/main/recipes/10-scattering-optional.md This WDL code defines a workflow for processing single-cell RNA-seq data using the Smart-Seq2 assay. It demonstrates scattering paired-end sequencing reads across multiple samples, handling optional inputs like `input_names` by scattering them using an index. ```wdl version 1.0 workflow MultiSampleSmartSeq2 { input { # Gene Annotation File genome_ref_fasta File rrna_intervals File gene_ref_flat # Reference index information File hisat2_ref_name File hisat2_ref_trans_name File hisat2_ref_index File hisat2_ref_trans_index File rsem_ref_index # Sample information String stranded Array[String] input_ids Array[String]? input_names Array[String] fastq1_input_files Array[String] fastq2_input_files = [] String? input_name_metadata_field String? input_id_metadata_field Boolean paired_end } if (false) { String? none = "None" } ### Execution starts here ### if (paired_end) { scatter(idx in range(length(input_ids))) { call single_cell_run.SmartSeq2SingleSample as sc_pe { input: fastq1 = fastq1_input_files[idx], fastq2 = fastq2_input_files[idx], stranded = stranded, genome_ref_fasta = genome_ref_fasta, rrna_intervals = rrna_intervals, gene_ref_flat = gene_ref_flat, hisat2_ref_index = hisat2_ref_index, hisat2_ref_name = hisat2_ref_name, hisat2_ref_trans_index = hisat2_ref_trans_index, hisat2_ref_trans_name = hisat2_ref_trans_name, rsem_ref_index = rsem_ref_index, input_id = input_ids[idx], output_name = input_ids[idx], paired_end = paired_end, input_name_metadata_field = input_name_metadata_field, input_id_metadata_field = input_id_metadata_field, input_name = if defined(input_names) then select_first([input_names])[idx] else none } } } } ``` -------------------------------- ### WDL Conditional Task Execution Source: https://github.com/openwdl/cookbook/blob/main/recipes/06-conditional-optional-input.md This WDL snippet demonstrates conditional execution of a task within a workflow. The `MergeSingleSampleVcfs` task is executed only if the `single_sample_vcfs` input is defined. This pattern is useful for optional processing steps. ```wdl version 1.0 workflow Imputation { input { File? multi_sample_vcf File? Multi_sample_vcf_index Array[File]? single_sample_vcfs Array[File]? single_sample_vcf_indices Int merge_ssvcf_mem_mb = 3000 } if (defined(single_sample_vcfs)) { call tasks.MergeSingleSampleVcfs { input: input_vcfs = select_first([single_sample_vcfs]), input_vcf_indices = select_first([single_sample_vcf_indices]), output_vcf_basename = "merged_input_samples", memory_mb = merge_ssvcf_mem_mb } } } ``` -------------------------------- ### Chaining Task Outputs: Task A to Task B Source: https://github.com/openwdl/cookbook/blob/main/recipes/01-chain-tasks-together.md Demonstrates how to chain tasks in WDL by using the output of 'task_A' (out_A) as an input for 'task_B'. This is achieved by referencing 'task_A.out_A' in the input section of 'task_B'. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref File my_input String name } call task_A { input: ref = my_ref, in = my_input, id = name } call task_B { input: ref = my_ref, in = task_A.out_A, id = name } } task task_A {...} task task_B {...} ``` -------------------------------- ### WDL Workflow with Conditional Task Execution Source: https://github.com/openwdl/cookbook/blob/main/recipes/06-conditional-optional-input.md This WDL script demonstrates how to conditionally execute `task_A` only if the optional input `my_input_A` is defined. `task_B` runs regardless of `my_input_A`'s presence. The `defined()` function checks for the existence of optional inputs. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref File? my_input_A File my_input_B String name } if (defined(my_input_A)) { call task_A { input: ref = my_ref, in = my_input_A, id = name } } call task_B { input: ref = my_ref, in = my_input_B, id = name } } task task_A {...} task task_B {...} ``` -------------------------------- ### WDL Workflow Without Scatter Block Source: https://github.com/openwdl/cookbook/blob/main/recipes/08-scattering_array.md This WDL code represents a workflow before the implementation of scatter-gather parallelism. It shows the sequential structure where tasks are called without explicit parallelization for array inputs. This serves as a baseline to illustrate the benefit of adding a scatter block. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref Array[File] my_input String name } call task_A { input: ref = my_ref, in = my_input, id = name } call task_B { input: ref = my_ref, in = task_A.out, id = name } } task task_A {...} task task_B {...} ``` -------------------------------- ### WDL Workflow with Conditional Task Execution Source: https://github.com/openwdl/cookbook/blob/main/recipes/03-multipath-conditionals.md This WDL code defines a workflow that processes single-cell or single-nucleus RNA data. It uses an 'if' statement based on the 'counting_mode' input to conditionally execute either the 'TagGeneExon.TagGeneExon' or 'TagGeneExon.TagReadWithGeneFunction' task. The workflow then converges using 'select_first()' to handle the output from the chosen task. ```wdl version 1.0 workflow Optimus { input { # Mode for counting either "sc_rna" or "sn_rna" String counting_mode = "sc_rna" # organism reference parameters File annotations_gtf # Set to true to count reads in stranded mode String use_strand_info = "false" } if (counting_mode == "sc_rna") { call TagGeneExon.TagGeneExon as TagGenes { input: bam_input = StarAlign.bam_output, annotations_gtf = ModifyGtf.modified_gtf } } if (counting_mode == "sn_rna") { call TagGeneExon.TagReadWithGeneFunction as TagGeneFunction { input: bam_input = StarAlign.bam_output, annotations_gtf = ModifyGtf.modified_gtf, gene_name_tag = "GE", gene_strand_tag = "GS", gene_function_tag = "XF", use_strand_info = use_strand_info } } call Picard.SortBamAndIndex as PreUMISort { input: bam_input = select_first([TagGenes.bam_output, TagGeneFunction.bam_output]) } } ``` -------------------------------- ### WDL Task with Optional Parameter (Conditional) Source: https://github.com/openwdl/cookbook/blob/main/recipes/04-different-parameters.md This WDL code demonstrates the corrected approach. The 'id' parameter is conditionally included in the command string. If the 'id' input is defined, the '-O' flag and its value are passed to 'do_stuff'; otherwise, they are omitted, preventing errors. ```wdl version 1.0 workflow myWorkflowName { input { File my_ref File my_input String? name } call task_A { input: ref = my_ref, in = my_input, id = name } } task task_A { input { File ref File in String? id } command <<< do_stuff \ -R ~{ref} \ -I ~{in} \ ~{“-O ” + id} >>> } ``` -------------------------------- ### WDL Task for Input Array Validation Source: https://github.com/openwdl/cookbook/blob/main/recipes/09-scattering-index.md This WDL task, `checkInputArrays`, validates that several input arrays (input_ids, fastq1_input_files, fastq2_input_files, and optionally input_names) are of the same length. It uses shell commands to compare lengths and exits with an error if discrepancies are found. This ensures data integrity before proceeding with sample processing. ```wdl task checkInputArrays { input { Boolean paired_end Array[String] input_ids Array[String]? input_names Array[String] fastq1_input_files Array[String] fastq2_input_files } Int len_input_ids = length(input_ids) Int len_fastq1_input_files = length(fastq1_input_files) Int len_fastq2_input_files = length(fastq2_input_files) Int len_input_names = if defined(input_names) then length(select_first([input_names])) else 0 meta { description: "checks input arrays to ensure that all arrays are the same length" } command { set -e if [[ ~{len_input_ids} != ~{len_fastq1_input_files} ]] then echo "ERROR: Different number of arguments for input_id and fastq1 files" exit 1; fi if [[ ~{len_input_names} != 0 && ~{len_input_ids} != ~{len_input_names} ]] then echo "ERROR: Different number of arguments for input_name and input_id" exit 1; fi if ~{paired_end} && [[ ~{len_fastq2_input_files} != ~{len_input_ids} ]] then echo "ERROR: Different number of arguments for sample names and fastq1 files" exit 1; fi exit 0; } runtime { docker: "ubuntu:18.04" cpu: 1 memory: "1 GiB" disks: "local-disk 1 HDD" } } ``` -------------------------------- ### Optimus Workflow Definition Source: https://github.com/openwdl/cookbook/blob/main/recipes/04-different-parameters.md Defines the Optimus workflow with various inputs, including optional ones like 'input_name'. It calls the 'OptimusLoomGeneration' task, passing workflow inputs to it. ```wdl version 1.0 workflow Optimus { input { # Mode for counting either "sc_rna" or "sn_rna" String counting_mode = "sc_rna" # Sequencing data inputs String input_id String? input_name String? input_id_metadata_field String? Input_name_metadata_field # organism reference parameters File annotations_gtf } call LoomUtils.OptimusLoomGeneration{ input: input_id = input_id, input_name = input_name, input_id_metadata_field = input_id_metadata_field, input_name_metadata_field = input_name_metadata_field, annotation_file = annotations_gtf, cell_metrics = CellMetrics.cell_metrics, gene_metrics = GeneMetrics.gene_metrics, sparse_count_matrix = MergeStarOutputs.sparse_counts, cell_id = MergeStarOutputs.row_index, gene_id = MergeStarOutputs.col_index, empty_drops_result = RunEmptyDrops.empty_drops_result, counting_mode = counting_mode, } } ``` -------------------------------- ### Scatter on Index for Multiple Arrays Source: https://github.com/openwdl/cookbook/blob/main/recipes/09-scattering-index.md This WDL code snippet shows how to scatter multiple arrays ('my_ref' and 'my_input') together by scattering on an index. It uses 'range(length(my_input))' to generate indices and accesses array elements using these indices. ```wdl version 1.0 workflow myWorkflowName { input { Array[File] my_ref Array[File] my_input String name } scatter (idx in range(length(my_input))) { call task_A { input: ref = my_ref[idx], in = my_input[idx], id = name } } } task task_A {...} ```