#!/usr/bin/env bash

# cellranger_multi fix-integration-tests
# 
# 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:
#  * Angela Oliveira Pisco (author)
#  * Robrecht Cannoodt (author, maintainer)
#  * Dries De Maeyer (author)
#  * Weiwei Schultz (contributor)
#  * Dorien Roosen (author)

set -e

if [ -z "$VIASH_TEMP" ]; then
  VIASH_TEMP=${VIASH_TEMP:-$VIASH_TMPDIR}
  VIASH_TEMP=${VIASH_TEMP:-$VIASH_TEMPDIR}
  VIASH_TEMP=${VIASH_TEMP:-$VIASH_TMP}
  VIASH_TEMP=${VIASH_TEMP:-$TMPDIR}
  VIASH_TEMP=${VIASH_TEMP:-$TMP}
  VIASH_TEMP=${VIASH_TEMP:-$TEMPDIR}
  VIASH_TEMP=${VIASH_TEMP:-$TEMP}
  VIASH_TEMP=${VIASH_TEMP:-/tmp}
fi

# define helper functions
# ViashQuote: put quotes around non flag values
# $1     : unquoted string
# return : possibly quoted string
# examples:
#   ViashQuote --foo      # returns --foo
#   ViashQuote bar        # returns 'bar'
#   Viashquote --foo=bar  # returns --foo='bar'
function ViashQuote {
  if [[ "$1" =~ ^-+[a-zA-Z0-9_\-]+=.+$ ]]; then
    echo "$1" | sed "s#=\(.*\)#='\1'#"
  elif [[ "$1" =~ ^-+[a-zA-Z0-9_\-]+$ ]]; then
    echo "$1"
  else
    echo "'$1'"
  fi
}
# ViashRemoveFlags: Remove leading flag
# $1     : string with a possible leading flag
# return : string without possible leading flag
# examples:
#   ViashRemoveFlags --foo=bar  # returns bar
function ViashRemoveFlags {
  echo "$1" | sed 's/^--*[a-zA-Z0-9_\-]*=//'
}
# ViashSourceDir: return the path of a bash file, following symlinks
# usage   : ViashSourceDir ${BASH_SOURCE[0]}
# $1      : Should always be set to ${BASH_SOURCE[0]}
# returns : The absolute path of the bash file
function ViashSourceDir {
  local source="$1"
  while [ -h "$source" ]; do
    local dir="$( cd -P "$( dirname "$source" )" >/dev/null 2>&1 && pwd )"
    source="$(readlink "$source")"
    [[ $source != /* ]] && source="$dir/$source"
  done
  cd -P "$( dirname "$source" )" >/dev/null 2>&1 && pwd
}
# ViashFindTargetDir: return the path of the '.build.yaml' file, following symlinks
# usage   : ViashFindTargetDir 'ScriptPath'
# $1      : The location from where to start the upward search
# returns : The absolute path of the '.build.yaml' file
function ViashFindTargetDir {
  local source="$1"
  while [[ "$source" != "" && ! -e "$source/.build.yaml" ]]; do
    source=${source%/*}
  done
  echo $source
}
# see https://en.wikipedia.org/wiki/Syslog#Severity_level
VIASH_LOGCODE_EMERGENCY=0
VIASH_LOGCODE_ALERT=1
VIASH_LOGCODE_CRITICAL=2
VIASH_LOGCODE_ERROR=3
VIASH_LOGCODE_WARNING=4
VIASH_LOGCODE_NOTICE=5
VIASH_LOGCODE_INFO=6
VIASH_LOGCODE_DEBUG=7
VIASH_VERBOSITY=$VIASH_LOGCODE_NOTICE

# ViashLog: Log events depending on the verbosity level
# usage: ViashLog 1 alert Oh no something went wrong!
# $1: required verbosity level
# $2: display tag
# $3+: messages to display
# stdout: Your input, prepended by '[$2] '.
function ViashLog {
  local required_level="$1"
  local display_tag="$2"
  shift 2
  if [ $VIASH_VERBOSITY -ge $required_level ]; then
    >&2 echo "[$display_tag]" "$@"
  fi
}

# ViashEmergency: log events when the system is unstable
# usage: ViashEmergency Oh no something went wrong.
# stdout: Your input, prepended by '[emergency] '.
function ViashEmergency {
  ViashLog $VIASH_LOGCODE_EMERGENCY emergency "$@"
}

# ViashAlert: log events when actions must be taken immediately (e.g. corrupted system database)
# usage: ViashAlert Oh no something went wrong.
# stdout: Your input, prepended by '[alert] '.
function ViashAlert {
  ViashLog $VIASH_LOGCODE_ALERT alert "$@"
}

# ViashCritical: log events when a critical condition occurs
# usage: ViashCritical Oh no something went wrong.
# stdout: Your input, prepended by '[critical] '.
function ViashCritical {
  ViashLog $VIASH_LOGCODE_CRITICAL critical "$@"
}

# ViashError: log events when an error condition occurs
# usage: ViashError Oh no something went wrong.
# stdout: Your input, prepended by '[error] '.
function ViashError {
  ViashLog $VIASH_LOGCODE_ERROR error "$@"
}

# ViashWarning: log potentially abnormal events
# usage: ViashWarning Something may have gone wrong.
# stdout: Your input, prepended by '[warning] '.
function ViashWarning {
  ViashLog $VIASH_LOGCODE_WARNING warning "$@"
}

# ViashNotice: log significant but normal events
# usage: ViashNotice This just happened.
# stdout: Your input, prepended by '[notice] '.
function ViashNotice {
  ViashLog $VIASH_LOGCODE_NOTICE notice "$@"
}

# ViashInfo: log normal events
# usage: ViashInfo This just happened.
# stdout: Your input, prepended by '[info] '.
function ViashInfo {
  ViashLog $VIASH_LOGCODE_INFO info "$@"
}

# ViashDebug: log all events, for debugging purposes
# usage: ViashDebug This just happened.
# stdout: Your input, prepended by '[debug] '.
function ViashDebug {
  ViashLog $VIASH_LOGCODE_DEBUG debug "$@"
}

# find source folder of this component
VIASH_META_RESOURCES_DIR=`ViashSourceDir ${BASH_SOURCE[0]}`

# find the root of the built components & dependencies
VIASH_TARGET_DIR=`ViashFindTargetDir $VIASH_META_RESOURCES_DIR`

# define meta fields
VIASH_META_NAME="cellranger_multi"
VIASH_META_FUNCTIONALITY_NAME="cellranger_multi"
VIASH_META_EXECUTABLE="$VIASH_META_RESOURCES_DIR/$VIASH_META_NAME"
VIASH_META_CONFIG="$VIASH_META_RESOURCES_DIR/.config.vsh.yaml"
VIASH_META_TEMP_DIR="$VIASH_TEMP"


# ViashHelp: Display helpful explanation about this executable
function ViashHelp {
  echo "cellranger_multi fix-integration-tests"
  echo ""
  echo "Align fastq files using Cell Ranger multi."
  echo ""
  echo "Input files:"
  echo "    --input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed. FASTQ files should conform to the naming"
  echo "        conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "Feature type-specific input files:"
  echo "    Helper functionality to allow feature type-specific input files, without the"
  echo "    need to specify"
  echo "    library_type or library_id. The library_id will be inferred from the input"
  echo "    paths."
  echo ""
  echo "    --gex_input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed for Gene Expression. FASTQ files should"
  echo "        conform to the"
  echo "        naming conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "    --abc_input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed for Antibody Capture. FASTQ files should"
  echo "        conform to"
  echo "        the naming conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "    --cgc_input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed for CRISPR Guide Capture. FASTQ files"
  echo "        should conform to"
  echo "        the naming conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "    --mux_input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed for Multiplexing Capture. FASTQ files"
  echo "        should conform to"
  echo "        the naming conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "    --vdj_input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed for VDJ. FASTQ files should conform to"
  echo "        the"
  echo "        naming conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "    --vdj_t_input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed for VDJ-T. FASTQ files should conform to"
  echo "        the naming"
  echo "        conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "    --vdj_t_gd_input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed for VDJ-T-GD. FASTQ files should conform"
  echo "        to"
  echo "        the naming conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "    --vdj_b_input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed for VDJ-B. FASTQ files should conform to"
  echo "        the naming conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "    --agc_input"
  echo "        type: file, multiple values allowed, file must exist"
  echo "        example:"
  echo "mysample_S1_L001_R1_001.fastq.gz;mysample_S1_L001_R2_001.fastq.gz"
  echo "        The FASTQ files to be analyzed for Antigen Capture. FASTQ files should"
  echo "        conform to"
  echo "        the naming conventions of bcl2fastq and mkfastq:"
  echo "        \`[Sample Name]_S[Sample Index]_L00[Lane Number]_[Read"
  echo "        Type]_001.fastq.gz\`"
  echo ""
  echo "Library arguments:"
  echo "    --library_id"
  echo "        type: string, multiple values allowed"
  echo "        example: mysample1"
  echo "        The Illumina sample name to analyze. This must exactly match the 'Sample"
  echo "        Name'part"
  echo "        of the FASTQ files specified in the \`--input\` argument."
  echo ""
  echo "    --library_type"
  echo "        type: string, multiple values allowed"
  echo "        example: Gene Expression"
  echo "        choices: [ Gene Expression, VDJ, VDJ-T, VDJ-B, VDJ-T-GD, Antibody"
  echo "Capture, CRISPR Guide Capture, Multiplexing Capture, Antigen Capture, Custom ]"
  echo "        The underlying feature type of the library."
  echo ""
  echo "    --library_subsample"
  echo "        type: string, multiple values allowed"
  echo "        example: 0.5"
  echo "        The rate at which reads from the provided FASTQ files are sampled."
  echo "        Must be strictly greater than 0 and less than or equal to 1."
  echo ""
  echo "    --library_lanes"
  echo "        type: string, multiple values allowed"
  echo "        example: 1-4"
  echo "        Lanes associated with this sample. Defaults to using all lanes."
  echo ""
  echo "    --library_chemistry"
  echo "        type: string"
  echo "        Only applicable to FRP. Library-specific assay configuration. By"
  echo "        default,"
  echo "        the assay configuration is detected automatically. Typically, users will"
  echo "        not need to specify a chemistry."
  echo ""
  echo "Sample parameters:"
  echo "    --cell_multiplex_sample_id, --sample_ids"
  echo "        type: string, multiple values allowed"
  echo "        A name to identify a multiplexed sample. Must be alphanumeric with"
  echo "        hyphens and/or underscores,"
  echo "        and less than 64 characters. Required for Cell Multiplexing libraries."
  echo ""
  echo "    --cell_multiplex_description, --sample_description"
  echo "        type: string, multiple values allowed"
  echo "        A description for the sample."
  echo ""
  echo "    --sample_expect_cells"
  echo "        type: integer, multiple values allowed"
  echo "        example: 3000"
  echo "        Expected number of recovered cells, used as input to cell calling"
  echo "        algorithm."
  echo ""
  echo "    --sample_force_cells"
  echo "        type: integer, multiple values allowed"
  echo "        example: 3000"
  echo "        Force pipeline to use this number of cells, bypassing cell detection."
  echo ""
  echo "Feature Barcode library specific arguments:"
  echo "    --feature_reference"
  echo "        type: file, file must exist"
  echo "        example: feature_reference.csv"
  echo "        Path to the Feature reference CSV file, declaring Feature Barcode"
  echo "        constructs and associated barcodes."
  echo "        Required only for Antibody Capture or CRISPR Guide Capture libraries."
  echo "        See"
  echo "       "
  echo "https://support.10xgenomics.com/single-cell-gene-expression/software/pipelines/latest/using/feature-bc-analysis#feature-ref"
  echo "        for more information.\""
  echo ""
  echo "    --feature_r1_length"
  echo "        type: integer"
  echo "        Limit the length of the input Read 1 sequence of V(D)J libraries to the"
  echo "        first N bases,"
  echo "        where N is the user-supplied value. Note that the length includes the"
  echo "        Barcode and UMI"
  echo "        sequences so do not set this below 26."
  echo ""
  echo "    --feature_r2_length"
  echo "        type: integer"
  echo "        Limit the length of the input Read 2 sequence of V(D)J libraries to the"
  echo "        first N bases,"
  echo "        where N is a user-supplied value. Trimming occurs before sequencing"
  echo "        metrics are computed"
  echo "        and therefore, limiting the length of Read 2 may affect Q30 scores."
  echo ""
  echo "    --min_crispr_umi"
  echo "        type: integer"
  echo "        min: 1"
  echo "        Set the minimum number of CRISPR guide RNA UMIs required for protospacer"
  echo "        detection."
  echo "        If a lower or higher sensitivity is desired for detection, this value"
  echo "        can be customized"
  echo "        according to specific experimental needs. Applicable only to datasets"
  echo "        that include a"
  echo "        CRISPR Guide Capture library."
  echo ""
  echo "Gene expression arguments:"
  echo "    Arguments relevant to the analysis of gene expression data."
  echo ""
  echo "    --gex_reference"
  echo "        type: file, required parameter, file must exist"
  echo "        example: reference_genome.tar.gz"
  echo "        Genome refence index built by Cell Ranger mkref."
  echo ""
  echo "    --gex_secondary_analysis"
  echo "        type: boolean"
  echo "        default: false"
  echo "        Whether or not to run the secondary analysis e.g. clustering."
  echo ""
  echo "    --gex_generate_bam"
  echo "        type: boolean"
  echo "        default: false"
  echo "        Whether to generate a BAM file."
  echo ""
  echo "    --gex_expect_cells"
  echo "        type: integer"
  echo "        example: 3000"
  echo "        Expected number of recovered cells, used as input to cell calling"
  echo "        algorithm."
  echo ""
  echo "    --gex_force_cells"
  echo "        type: integer"
  echo "        example: 3000"
  echo "        Force pipeline to use this number of cells, bypassing cell detection."
  echo ""
  echo "    --gex_include_introns"
  echo "        type: boolean"
  echo "        default: true"
  echo "        Whether or not to include intronic reads in counts."
  echo "        This option does not apply to Fixed RNA Profiling analysis."
  echo ""
  echo "    --gex_r1_length"
  echo "        type: integer"
  echo "        Limit the length of the input Read 1 sequence of V(D)J libraries to the"
  echo "        first N bases,"
  echo "        where N is the user-supplied value. Note that the length includes the"
  echo "        Barcode and UMI"
  echo "        sequences so do not set this below 26."
  echo ""
  echo "    --gex_r2_length"
  echo "        type: integer"
  echo "        Limit the length of the input Read 2 sequence of V(D)J libraries to the"
  echo "        first N bases,"
  echo "        where N is a user-supplied value. Trimming occurs before sequencing"
  echo "        metrics are computed"
  echo "        and therefore, limiting the length of Read 2 may affect Q30 scores."
  echo ""
  echo "    --gex_chemistry"
  echo "        type: string"
  echo "        default: auto"
  echo "        choices: [ auto, threeprime, fiveprime, SC3Pv1, SC3Pv2, SC3Pv3, SC3Pv4,"
  echo "SC3Pv3LT, SC3Pv3HT, SC5P-PE, SC5P-R2, SC-FB, SC5P-R2-v3, SCP5-PE-v3, SC5PHT,"
  echo "MFRP, MFRP-R1, MFRP-RNA, MFRP-Ab, SFRP, MFRP-Ab-R2pos50, MFRP-RNA-R1,"
  echo "MFRP-Ab-R1, ARC-v1 ]"
  echo "        Assay configuration. Either specify a single value which will be applied"
  echo "        to all libraries,"
  echo "        or a number of values that is equal to the number of libararies. The"
  echo "        latter is only applicable"
  echo "        to only applicable to Fixed RNA Profiling."
  echo "          - auto: Chemistry autodetection (default)"
  echo "          - threeprime: Single Cell 3'"
  echo "          - SC3Pv1, SC3Pv2, SC3Pv3, SC3Pv4: Single Cell 3' v1, v2, v3, or v4"
  echo "          - SC3Pv3HT: Single Cell 3' v3.1 HT"
  echo "          - SC-FB: Single Cell Antibody-only 3' v2 or 5'"
  echo "          - fiveprime: Single Cell 5'"
  echo "          - SC5P-PE: Paired-end Single Cell 5'"
  echo "          - SC5P-R2: R2-only Single Cell 5'"
  echo "          - SC5P-R2-v3: R2-only Single Cell 5' v3"
  echo "          - SCP5-PE-v3: Single Cell 5' paired-end v3 (GEM-X)"
  echo "          - SC5PHT : Single Cell 5' v2 HT"
  echo "          - SFRP: Fixed RNA Profiling (Singleplex)"
  echo "          - MFRP: Fixed RNA Profiling (Multiplex, Probe Barcode on R2)"
  echo "          - MFRP-R1: Fixed RNA Profiling (Multiplex, Probe Barcode on R1)"
  echo "          - MFRP-RNA: Fixed RNA Profiling (Multiplex, RNA, Probe Barcode on R2)"
  echo "          - MFRP-Ab: Fixed RNA Profiling (Multiplex, Antibody, Probe Barcode at"
  echo "        R2:69)"
  echo "          - MFRP-Ab-R2pos50: Fixed RNA Profiling (Multiplex, Antibody, Probe"
  echo "        Barcode at R2:50)"
  echo "          - MFRP-RNA-R1: Fixed RNA Profiling (Multiplex, RNA, Probe Barcode on"
  echo "        R1)"
  echo "          - MFRP-Ab-R1: Fixed RNA Profiling (Multiplex, Antibody, Probe Barcode"
  echo "        on R1)"
  echo "          - ARC-v1 for analyzing the Gene Expression portion of Multiome data."
  echo "        If Cell Ranger auto-detects ARC-v1 chemistry, an error is triggered."
  echo "        See"
  echo "       "
  echo "https://kb.10xgenomics.com/hc/en-us/articles/115003764132-How-does-Cell-Ranger-auto-detect-chemistry-"
  echo "        for more information."
  echo ""
  echo "VDJ related parameters:"
  echo "    --vdj_reference"
  echo "        type: file, file must exist"
  echo "        example: reference_vdj.tar.gz"
  echo "        VDJ refence index built by Cell Ranger mkref."
  echo ""
  echo "    --vdj_inner_enrichment_primers"
  echo "        type: file, file must exist"
  echo "        example: enrichment_primers.txt"
  echo "        V(D)J Immune Profiling libraries: if inner enrichment primers other than"
  echo "        those provided"
  echo "        in the 10x Genomics kits are used, they need to be specified here as a"
  echo "        text file with one primer per line."
  echo ""
  echo "    --vdj_r1_length"
  echo "        type: integer"
  echo "        Limit the length of the input Read 1 sequence of V(D)J libraries to the"
  echo "        first N bases, where N is the user-supplied value."
  echo "        Note that the length includes the Barcode and UMI sequences so do not"
  echo "        set this below 26."
  echo ""
  echo "    --vdj_r2_length"
  echo "        type: integer"
  echo "        Limit the length of the input Read 2 sequence of V(D)J libraries to the"
  echo "        first N bases, where N is a user-supplied value."
  echo "        Trimming occurs before sequencing metrics are computed and therefore,"
  echo "        limiting the length of Read 2 may affect Q30 scores"
  echo ""
  echo "Cell multiplexing parameters:"
  echo "    --cell_multiplex_oligo_ids"
  echo "        type: string, multiple values allowed"
  echo "        The Cell Multiplexing oligo IDs used to multiplex this sample. If"
  echo "        multiple CMOs were used for a sample,"
  echo "        separate IDs with a pipe (e.g., CMO301|CMO302). Required for Cell"
  echo "        Multiplexing libraries."
  echo ""
  echo "    --min_assignment_confidence"
  echo "        type: double"
  echo "        The minimum estimated likelihood to call a sample as tagged with a Cell"
  echo "        Multiplexing Oligo (CMO) instead of \"Unassigned\"."
  echo "        Users may wish to tolerate a higher rate of mis-assignment in order to"
  echo "        obtain more singlets to include in their analysis,"
  echo "        or a lower rate of mis-assignment at the cost of obtaining fewer"
  echo "        singlets."
  echo ""
  echo "    --cmo_set"
  echo "        type: file, file must exist"
  echo "        Path to a custom CMO set CSV file, declaring CMO constructs and"
  echo "        associated barcodes. If the default CMO reference IDs that are built"
  echo "        into"
  echo "        the Cell Ranger software are required, this option does not need to be"
  echo "        used."
  echo ""
  echo "    --barcode_sample_assignment"
  echo "        type: file, file must exist"
  echo "        Path to a barcode-sample assignment CSV file that specifies the barcodes"
  echo "        that belong to each sample."
  echo ""
  echo "Fixed RNA profiling paramaters:"
  echo "    --probe_set"
  echo "        type: file, file must exist"
  echo "        A probe set reference CSV file. It specifies the sequences used as a"
  echo "        reference for probe alignment and the gene ID associated with each"
  echo "        probe."
  echo "        It must include 4 columns (probe file format 1.0.0):"
  echo "        gene_id,probe_seq,probe_id,included,region and an optional 5th column"
  echo "        (probe file format 1.0.1)."
  echo "        - gene_id: The Ensembl gene identifier targeted by the probe."
  echo "        - probe_seq: The nucleotide sequence of the probe, which is"
  echo "        complementary to the transcript sequence."
  echo "        - probe_id: The probe identifier, whose format is described in Probe"
  echo "        identifiers."
  echo "        - included: A TRUE or FALSE flag specifying whether the probe is"
  echo "        included in the filtered counts matrix output or excluded by the probe"
  echo "        filter."
  echo "                    See filter-probes option of cellranger multi. All probes of"
  echo "        a gene must be marked TRUE in the included column for that gene to be"
  echo "        included."
  echo "        - region: Present only in v1.0.1 probe set reference CSV. The gene"
  echo "        boundary targeted by the probe. Accepted values are spliced or"
  echo "        unspliced."
  echo "        The file also contains a number of required metadata fields in the"
  echo "        header in the format #key=value:"
  echo "        - panel_name: The name of the probe set."
  echo "        - panel_type: Always predesigned for predesigned probe sets."
  echo "        - reference_genome: The reference genome build used for probe design."
  echo "        - reference_version: The version of the Cell Ranger reference"
  echo "        transcriptome used for probe design."
  echo "        - probe_set_file_format: The version of the probe set file format"
  echo "        specification that this file conforms to."
  echo ""
  echo "    --filter_probes"
  echo "        type: boolean"
  echo "        If 'false', include all non-deprecated probes listed in the probe set"
  echo "        reference CSV file."
  echo "        If 'true' or not set, probes that are predicted to have off-target"
  echo "        activity to homologous genes are excluded from analysis."
  echo "        Not filtering will result in UMI counts from all non-deprecated probes,"
  echo "        including those with predicted off-target activity, to be used in the"
  echo "        analysis."
  echo "        Probes whose ID is prefixed with DEPRECATED are always excluded from the"
  echo "        analysis."
  echo ""
  echo "    --probe_barcode_ids"
  echo "        type: string, multiple values allowed"
  echo "        The Fixed RNA Probe Barcode ID used for this sample, and for multiplex"
  echo "        GEX + Antibody Capture libraries,"
  echo "        the corresponding Antibody Multiplexing Barcode IDs. 10x recommends"
  echo "        specifying both barcodes (e.g., BC001+AB001)"
  echo "        when an Antibody Capture library is present. The barcode pair order is"
  echo "        BC+AB and they"
  echo "        are separated with a \"+\" (no spaces). Alternatively, you can specify the"
  echo "        Probe Barcode ID alone and"
  echo "        Cell Ranger's barcode pairing auto-detection algorithm will"
  echo "        automatically match to the corresponding Antibody"
  echo "        Multiplexing Barcode."
  echo ""
  echo "Antigen Capture (BEAM) libary arguments:"
  echo "    These arguments are recommended if an Antigen Capture (BEAM) library is"
  echo "    present."
  echo "    It is needed to calculate the antigen specificity score."
  echo ""
  echo "    --control_id"
  echo "        type: string, multiple values allowed"
  echo "        A user-defined ID for any negative controls used in the T/BCR Antigen"
  echo "        Capture assay. Must match id specified in the feature reference CSV."
  echo "        May only include ASCII characters and must not use whitespace, slash,"
  echo "        quote, or comma characters."
  echo "        Each ID must be unique and must not collide with a gene identifier from"
  echo "        the transcriptome."
  echo ""
  echo "    --mhc_allele"
  echo "        type: string, multiple values allowed"
  echo "        The MHC allele for TCR Antigen Capture libraries. Must match mhc_allele"
  echo "        name specified in the Feature Reference CSV."
  echo ""
  echo "General arguments:"
  echo "    These arguments are applicable to all library types."
  echo ""
  echo "    --check_library_compatibility"
  echo "        type: boolean"
  echo "        default: true"
  echo "        Optional. This option allows users to disable the check that evaluates"
  echo "        10x Barcode overlap between"
  echo "        ibraries when multiple libraries are specified (e.g., Gene Expression +"
  echo "        Antibody Capture). Setting"
  echo "        this option to false will disable the check across all library"
  echo "        combinations. We recommend running"
  echo "        this check (default), however if the pipeline errors out, users can"
  echo "        bypass the check to generate"
  echo "        outputs for troubleshooting."
  echo ""
  echo "Outputs:"
  echo "    --output"
  echo "        type: file, required parameter, output, file must exist"
  echo "        example: /path/to/output"
  echo "        The folder to store the alignment results."
  echo ""
  echo "Executor arguments:"
  echo "    --dryrun"
  echo "        type: boolean_true"
  echo "        If true, the output directory will only contain the CWL input files, but"
  echo "        the pipeline itself will not be executed."
}

# initialise variables
VIASH_MODE='run'
VIASH_ENGINE_ID='docker'

######## Helper functions for setting up Docker images for viash ########
# expects: ViashDockerBuild

# ViashDockerInstallationCheck: check whether Docker is installed correctly
#
# examples:
#   ViashDockerInstallationCheck
function ViashDockerInstallationCheck {
  ViashDebug "Checking whether Docker is installed"
  if [ ! command -v docker &> /dev/null ]; then
    ViashCritical "Docker doesn't seem to be installed. See 'https://docs.docker.com/get-docker/' for instructions."
    exit 1
  fi

  ViashDebug "Checking whether the Docker daemon is running"
  local save=$-; set +e
  local docker_version=$(docker version --format '{{.Client.APIVersion}}' 2> /dev/null)
  local out=$?
  [[ $save =~ e ]] && set -e
  if [ $out -ne 0 ]; then
    ViashCritical "Docker daemon does not seem to be running. Try one of the following:"
    ViashCritical "- Try running 'dockerd' in the command line"
    ViashCritical "- See https://docs.docker.com/config/daemon/"
    exit 1
  fi
}

# ViashDockerRemoteTagCheck: check whether a Docker image is available 
# on a remote. Assumes `docker login` has been performed, if relevant.
#
# $1                  : image identifier with format `[registry/]image[:tag]`
# exit code $?        : whether or not the image was found
# examples:
#   ViashDockerRemoteTagCheck python:latest
#   echo $?                                     # returns '0'
#   ViashDockerRemoteTagCheck sdaizudceahifu
#   echo $?                                     # returns '1'
function ViashDockerRemoteTagCheck {
  docker manifest inspect $1 > /dev/null 2> /dev/null
}

# ViashDockerLocalTagCheck: check whether a Docker image is available locally
#
# $1                  : image identifier with format `[registry/]image[:tag]`
# exit code $?        : whether or not the image was found
# examples:
#   docker pull python:latest
#   ViashDockerLocalTagCheck python:latest
#   echo $?                                     # returns '0'
#   ViashDockerLocalTagCheck sdaizudceahifu
#   echo $?                                     # returns '1'
function ViashDockerLocalTagCheck {
  [ -n "$(docker images -q $1)" ]
}

# ViashDockerPull: pull a Docker image
#
# $1                  : image identifier with format `[registry/]image[:tag]`
# exit code $?        : whether or not the image was found
# examples:
#   ViashDockerPull python:latest
#   echo $?                                     # returns '0'
#   ViashDockerPull sdaizudceahifu
#   echo $?                                     # returns '1'
function ViashDockerPull {
  ViashNotice "Checking if Docker image is available at '$1'"
  if [ $VIASH_VERBOSITY -ge $VIASH_LOGCODE_INFO ]; then
    docker pull $1 && return 0 || return 1
  else
    local save=$-; set +e
    docker pull $1 2> /dev/null > /dev/null
    local out=$?
    [[ $save =~ e ]] && set -e
    if [ $out -ne 0 ]; then
      ViashWarning "Could not pull from '$1'. Docker image doesn't exist or is not accessible."
    fi
    return $out
  fi
}

# ViashDockerPush: push a Docker image
#
# $1                  : image identifier with format `[registry/]image[:tag]`
# exit code $?        : whether or not the image was found
# examples:
#   ViashDockerPush python:latest
#   echo $?                                     # returns '0'
#   ViashDockerPush sdaizudceahifu
#   echo $?                                     # returns '1'
function ViashDockerPush {
  ViashNotice "Pushing image to '$1'"
  local save=$-; set +e
  local out
  if [ $VIASH_VERBOSITY -ge $VIASH_LOGCODE_INFO ]; then
    docker push $1
    out=$?
  else
    docker push $1 2> /dev/null > /dev/null
    out=$?
  fi
  [[ $save =~ e ]] && set -e
  if [ $out -eq 0 ]; then
    ViashNotice "Container '$1' push succeeded."
  else
    ViashError "Container '$1' push errored. You might not be logged in or have the necessary permissions."
  fi
  return $out
}

# ViashDockerPullElseBuild: pull a Docker image, else build it
#
# $1                  : image identifier with format `[registry/]image[:tag]`
# ViashDockerBuild    : a Bash function which builds a docker image, takes image identifier as argument.
# examples:
#   ViashDockerPullElseBuild mynewcomponent
function ViashDockerPullElseBuild {
  local save=$-; set +e
  ViashDockerPull $1
  local out=$?
  [[ $save =~ e ]] && set -e
  if [ $out -ne 0 ]; then
    ViashDockerBuild $@
  fi
}

# ViashDockerSetup: create a Docker image, according to specified docker setup strategy
#
# $1          : image identifier with format `[registry/]image[:tag]`
# $2          : docker setup strategy, see DockerSetupStrategy.scala
# examples:
#   ViashDockerSetup mynewcomponent alwaysbuild
function ViashDockerSetup {
  local image_id="$1"
  local setup_strategy="$2"
  if [ "$setup_strategy" == "alwaysbuild" -o "$setup_strategy" == "build" -o "$setup_strategy" == "b" ]; then
    ViashDockerBuild $image_id --no-cache $(ViashDockerBuildArgs "$engine_id")
  elif [ "$setup_strategy" == "alwayspull" -o "$setup_strategy" == "pull" -o "$setup_strategy" == "p" ]; then
    ViashDockerPull $image_id
  elif [ "$setup_strategy" == "alwayspullelsebuild" -o "$setup_strategy" == "pullelsebuild" ]; then
    ViashDockerPullElseBuild $image_id --no-cache $(ViashDockerBuildArgs "$engine_id")
  elif [ "$setup_strategy" == "alwayspullelsecachedbuild" -o "$setup_strategy" == "pullelsecachedbuild" ]; then
    ViashDockerPullElseBuild $image_id $(ViashDockerBuildArgs "$engine_id")
  elif [ "$setup_strategy" == "alwayscachedbuild" -o "$setup_strategy" == "cachedbuild" -o "$setup_strategy" == "cb" ]; then
    ViashDockerBuild $image_id $(ViashDockerBuildArgs "$engine_id")
  elif [[ "$setup_strategy" =~ ^ifneedbe ]]; then
    local save=$-; set +e
    ViashDockerLocalTagCheck $image_id
    local outCheck=$?
    [[ $save =~ e ]] && set -e
    if [ $outCheck -eq 0 ]; then
      ViashInfo "Image $image_id already exists"
    elif [ "$setup_strategy" == "ifneedbebuild" ]; then
      ViashDockerBuild $image_id --no-cache $(ViashDockerBuildArgs "$engine_id")
    elif [ "$setup_strategy" == "ifneedbecachedbuild" ]; then
      ViashDockerBuild $image_id $(ViashDockerBuildArgs "$engine_id")
    elif [ "$setup_strategy" == "ifneedbepull" ]; then
      ViashDockerPull $image_id
    elif [ "$setup_strategy" == "ifneedbepullelsebuild" ]; then
      ViashDockerPullElseBuild $image_id --no-cache $(ViashDockerBuildArgs "$engine_id")
    elif [ "$setup_strategy" == "ifneedbepullelsecachedbuild" ]; then
      ViashDockerPullElseBuild $image_id $(ViashDockerBuildArgs "$engine_id")
    else
      ViashError "Unrecognised Docker strategy: $setup_strategy"
      exit 1
    fi
  elif [ "$setup_strategy" == "push" -o "$setup_strategy" == "forcepush" -o "$setup_strategy" == "alwayspush" ]; then
    ViashDockerPush "$image_id"
  elif [ "$setup_strategy" == "pushifnotpresent" -o "$setup_strategy" == "gentlepush" -o "$setup_strategy" == "maybepush" ]; then
    local save=$-; set +e
    ViashDockerRemoteTagCheck $image_id
    local outCheck=$?
    [[ $save =~ e ]] && set -e
    if [ $outCheck -eq 0 ]; then
      ViashNotice "Container '$image_id' exists, doing nothing."
    else
      ViashNotice "Container '$image_id' does not yet exist."
      ViashDockerPush "$image_id"
    fi
  elif [ "$setup_strategy" == "donothing" -o "$setup_strategy" == "meh" ]; then
    ViashNotice "Skipping setup."
  else
    ViashError "Unrecognised Docker strategy: $setup_strategy"
    exit 1
  fi
}

# ViashDockerCheckCommands: Check whether a docker container has the required commands
#
# $1                  : image identifier with format `[registry/]image[:tag]`
# $@                  : commands to verify being present
# examples:
#   ViashDockerCheckCommands bash:4.0 bash ps foo
function ViashDockerCheckCommands {
  local image_id="$1"
  shift 1
  local commands="$@"
  local save=$-; set +e
  local missing # mark 'missing' as local in advance, otherwise the exit code of the command will be missing and always be '0'
  missing=$(docker run --rm --entrypoint=sh "$image_id" -c "for command in $commands; do command -v \$command >/dev/null 2>&1; if [ \$? -ne 0 ]; then echo \$command; exit 1; fi; done")
  local outCheck=$?
  [[ $save =~ e ]] && set -e
  if [ $outCheck -ne 0 ]; then
  	ViashError "Docker container '$image_id' does not contain command '$missing'."
  	exit 1
  fi
}

# ViashDockerBuild: build a docker image
# $1                               : image identifier with format `[registry/]image[:tag]`
# $...                             : additional arguments to pass to docker build
# $VIASH_META_TEMP_DIR             : temporary directory to store dockerfile & optional resources in
# $VIASH_META_NAME                 : name of the component
# $VIASH_META_RESOURCES_DIR        : directory containing the resources
# $VIASH_VERBOSITY                 : verbosity level
# exit code $?                     : whether or not the image was built successfully
function ViashDockerBuild {
  local image_id="$1"
  shift 1

  # create temporary directory to store dockerfile & optional resources in
  local tmpdir=$(mktemp -d "$VIASH_META_TEMP_DIR/dockerbuild-$VIASH_META_NAME-XXXXXX")
  local dockerfile="$tmpdir/Dockerfile"
  function clean_up {
    rm -rf "$tmpdir"
  }
  trap clean_up EXIT

  # store dockerfile and resources
  ViashDockerfile "$VIASH_ENGINE_ID" > "$dockerfile"

  # generate the build command
  local docker_build_cmd="docker build -t '$image_id' $@ '$VIASH_META_RESOURCES_DIR' -f '$dockerfile'"

  # build the container
  ViashNotice "Building container '$image_id' with Dockerfile"
  ViashInfo "$docker_build_cmd"
  local save=$-; set +e
  if [ $VIASH_VERBOSITY -ge $VIASH_LOGCODE_INFO ]; then
    eval $docker_build_cmd
  else
    eval $docker_build_cmd &> "$tmpdir/docker_build.log"
  fi

  # check exit code
  local out=$?
  [[ $save =~ e ]] && set -e
  if [ $out -ne 0 ]; then
    ViashError "Error occurred while building container '$image_id'"
    if [ $VIASH_VERBOSITY -lt $VIASH_LOGCODE_INFO ]; then
      ViashError "Transcript: --------------------------------"
      cat "$tmpdir/docker_build.log"
      ViashError "End of transcript --------------------------"
    fi
    exit 1
  fi
}

######## End of helper functions for setting up Docker images for viash ########

# ViashDockerFile: print the dockerfile to stdout
# $1    : engine identifier
# return : dockerfile required to run this component
# examples:
#   ViashDockerFile
function ViashDockerfile {
  local engine_id="$1"

  if [[ "$engine_id" == "docker" ]]; then
    cat << 'VIASHDOCKER'
FROM ghcr.io/data-intuitive/cellranger:8.0
ENTRYPOINT []
RUN DEBIAN_FRONTEND=noninteractive apt update && \
apt upgrade -y && apt install -y procps && rm -rf /var/lib/apt/lists/*

RUN pip install --upgrade pip && \
  pip install --upgrade --no-cache-dir "pandas" "pyyaml"

LABEL org.opencontainers.image.authors="Angela Oliveira Pisco, Robrecht Cannoodt, Dries De Maeyer, Weiwei Schultz, Dorien Roosen"
LABEL org.opencontainers.image.description="Companion container for running component mapping cellranger_multi"
LABEL org.opencontainers.image.created="2024-11-18T09:23:00Z"
LABEL org.opencontainers.image.source="https://github.com/openpipelines-bio/openpipeline"
LABEL org.opencontainers.image.revision="5e3f3231456facaf14da57fa563d4de58492ca82"
LABEL org.opencontainers.image.version="fix-integration-tests"

VIASHDOCKER
  fi
}

# ViashDockerBuildArgs: return the arguments to pass to docker build
# $1    : engine identifier
# return : arguments to pass to docker build
function ViashDockerBuildArgs {
  local engine_id="$1"

  if [[ "$engine_id" == "docker" ]]; then
    echo ""
  fi
}

# ViashAbsolutePath: generate absolute path from relative path
# borrowed from https://stackoverflow.com/a/21951256
# $1     : relative filename
# return : absolute path
# examples:
#   ViashAbsolutePath some_file.txt   # returns /path/to/some_file.txt
#   ViashAbsolutePath /foo/bar/..     # returns /foo
function ViashAbsolutePath {
  local thePath
  local parr
  local outp
  local len
  if [[ ! "$1" =~ ^/ ]]; then
    thePath="$PWD/$1"
  else
    thePath="$1"
  fi
  echo "$thePath" | (
    IFS=/
    read -a parr
    declare -a outp
    for i in "${parr[@]}"; do
      case "$i" in
      ''|.) continue ;;
      ..)
        len=${#outp[@]}
        if ((len==0)); then
          continue
        else
          unset outp[$((len-1))]
        fi
        ;;
      *)
        len=${#outp[@]}
        outp[$len]="$i"
      ;;
      esac
    done
    echo /"${outp[*]}"
  )
}
# ViashDockerAutodetectMount: auto configuring docker mounts from parameters
# $1                             : The parameter value
# returns                        : New parameter
# $VIASH_DIRECTORY_MOUNTS        : Added another parameter to be passed to docker
# $VIASH_DOCKER_AUTOMOUNT_PREFIX : The prefix to be used for the automounts
# examples:
#   ViashDockerAutodetectMount /path/to/bar      # returns '/viash_automount/path/to/bar'
#   ViashDockerAutodetectMountArg /path/to/bar   # returns '--volume="/path/to:/viash_automount/path/to"'
function ViashDockerAutodetectMount {
  local abs_path=$(ViashAbsolutePath "$1")
  local mount_source
  local base_name
  if [ -d "$abs_path" ]; then
    mount_source="$abs_path"
    base_name=""
  else
    mount_source=`dirname "$abs_path"`
    base_name=`basename "$abs_path"`
  fi
  local mount_target="$VIASH_DOCKER_AUTOMOUNT_PREFIX$mount_source"
  if [ -z "$base_name" ]; then
    echo "$mount_target"
  else
    echo "$mount_target/$base_name"
  fi
}
function ViashDockerAutodetectMountArg {
  local abs_path=$(ViashAbsolutePath "$1")
  local mount_source
  local base_name
  if [ -d "$abs_path" ]; then
    mount_source="$abs_path"
    base_name=""
  else
    mount_source=`dirname "$abs_path"`
    base_name=`basename "$abs_path"`
  fi
  local mount_target="$VIASH_DOCKER_AUTOMOUNT_PREFIX$mount_source"
  ViashDebug "ViashDockerAutodetectMountArg $1 -> $mount_source -> $mount_target"
  echo "--volume=\"$mount_source:$mount_target\""
}
function ViashDockerStripAutomount {
  local abs_path=$(ViashAbsolutePath "$1")
  echo "${abs_path#$VIASH_DOCKER_AUTOMOUNT_PREFIX}"
}
# initialise variables
VIASH_DIRECTORY_MOUNTS=()

# configure default docker automount prefix if it is unset
if [ -z "${VIASH_DOCKER_AUTOMOUNT_PREFIX+x}" ]; then
  VIASH_DOCKER_AUTOMOUNT_PREFIX="/viash_automount"
fi

# initialise docker variables
VIASH_DOCKER_RUN_ARGS=(-i --rm)

# initialise array
VIASH_POSITIONAL_ARGS=''

while [[ $# -gt 0 ]]; do
    case "$1" in
        -h|--help)
            ViashHelp
            exit
            ;;
        ---v|---verbose)
            let "VIASH_VERBOSITY=VIASH_VERBOSITY+1"
            shift 1
            ;;
        ---verbosity)
            VIASH_VERBOSITY="$2"
            shift 2
            ;;
        ---verbosity=*)
            VIASH_VERBOSITY="$(ViashRemoveFlags "$1")"
            shift 1
            ;;
        --version)
            echo "cellranger_multi fix-integration-tests"
            exit
            ;;
        --input)
            if [ -z "$VIASH_PAR_INPUT" ]; then
              VIASH_PAR_INPUT="$2"
            else
              VIASH_PAR_INPUT="$VIASH_PAR_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --input=*)
            if [ -z "$VIASH_PAR_INPUT" ]; then
              VIASH_PAR_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_INPUT="$VIASH_PAR_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --gex_input)
            if [ -z "$VIASH_PAR_GEX_INPUT" ]; then
              VIASH_PAR_GEX_INPUT="$2"
            else
              VIASH_PAR_GEX_INPUT="$VIASH_PAR_GEX_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_input=*)
            if [ -z "$VIASH_PAR_GEX_INPUT" ]; then
              VIASH_PAR_GEX_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_GEX_INPUT="$VIASH_PAR_GEX_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --abc_input)
            if [ -z "$VIASH_PAR_ABC_INPUT" ]; then
              VIASH_PAR_ABC_INPUT="$2"
            else
              VIASH_PAR_ABC_INPUT="$VIASH_PAR_ABC_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --abc_input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --abc_input=*)
            if [ -z "$VIASH_PAR_ABC_INPUT" ]; then
              VIASH_PAR_ABC_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_ABC_INPUT="$VIASH_PAR_ABC_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --cgc_input)
            if [ -z "$VIASH_PAR_CGC_INPUT" ]; then
              VIASH_PAR_CGC_INPUT="$2"
            else
              VIASH_PAR_CGC_INPUT="$VIASH_PAR_CGC_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --cgc_input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --cgc_input=*)
            if [ -z "$VIASH_PAR_CGC_INPUT" ]; then
              VIASH_PAR_CGC_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_CGC_INPUT="$VIASH_PAR_CGC_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --mux_input)
            if [ -z "$VIASH_PAR_MUX_INPUT" ]; then
              VIASH_PAR_MUX_INPUT="$2"
            else
              VIASH_PAR_MUX_INPUT="$VIASH_PAR_MUX_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --mux_input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --mux_input=*)
            if [ -z "$VIASH_PAR_MUX_INPUT" ]; then
              VIASH_PAR_MUX_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_MUX_INPUT="$VIASH_PAR_MUX_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --vdj_input)
            if [ -z "$VIASH_PAR_VDJ_INPUT" ]; then
              VIASH_PAR_VDJ_INPUT="$2"
            else
              VIASH_PAR_VDJ_INPUT="$VIASH_PAR_VDJ_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --vdj_input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --vdj_input=*)
            if [ -z "$VIASH_PAR_VDJ_INPUT" ]; then
              VIASH_PAR_VDJ_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_VDJ_INPUT="$VIASH_PAR_VDJ_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --vdj_t_input)
            if [ -z "$VIASH_PAR_VDJ_T_INPUT" ]; then
              VIASH_PAR_VDJ_T_INPUT="$2"
            else
              VIASH_PAR_VDJ_T_INPUT="$VIASH_PAR_VDJ_T_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --vdj_t_input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --vdj_t_input=*)
            if [ -z "$VIASH_PAR_VDJ_T_INPUT" ]; then
              VIASH_PAR_VDJ_T_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_VDJ_T_INPUT="$VIASH_PAR_VDJ_T_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --vdj_t_gd_input)
            if [ -z "$VIASH_PAR_VDJ_T_GD_INPUT" ]; then
              VIASH_PAR_VDJ_T_GD_INPUT="$2"
            else
              VIASH_PAR_VDJ_T_GD_INPUT="$VIASH_PAR_VDJ_T_GD_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --vdj_t_gd_input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --vdj_t_gd_input=*)
            if [ -z "$VIASH_PAR_VDJ_T_GD_INPUT" ]; then
              VIASH_PAR_VDJ_T_GD_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_VDJ_T_GD_INPUT="$VIASH_PAR_VDJ_T_GD_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --vdj_b_input)
            if [ -z "$VIASH_PAR_VDJ_B_INPUT" ]; then
              VIASH_PAR_VDJ_B_INPUT="$2"
            else
              VIASH_PAR_VDJ_B_INPUT="$VIASH_PAR_VDJ_B_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --vdj_b_input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --vdj_b_input=*)
            if [ -z "$VIASH_PAR_VDJ_B_INPUT" ]; then
              VIASH_PAR_VDJ_B_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_VDJ_B_INPUT="$VIASH_PAR_VDJ_B_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --agc_input)
            if [ -z "$VIASH_PAR_AGC_INPUT" ]; then
              VIASH_PAR_AGC_INPUT="$2"
            else
              VIASH_PAR_AGC_INPUT="$VIASH_PAR_AGC_INPUT;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --agc_input. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --agc_input=*)
            if [ -z "$VIASH_PAR_AGC_INPUT" ]; then
              VIASH_PAR_AGC_INPUT=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_AGC_INPUT="$VIASH_PAR_AGC_INPUT;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --library_id)
            if [ -z "$VIASH_PAR_LIBRARY_ID" ]; then
              VIASH_PAR_LIBRARY_ID="$2"
            else
              VIASH_PAR_LIBRARY_ID="$VIASH_PAR_LIBRARY_ID;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --library_id. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --library_id=*)
            if [ -z "$VIASH_PAR_LIBRARY_ID" ]; then
              VIASH_PAR_LIBRARY_ID=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_LIBRARY_ID="$VIASH_PAR_LIBRARY_ID;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --library_type)
            if [ -z "$VIASH_PAR_LIBRARY_TYPE" ]; then
              VIASH_PAR_LIBRARY_TYPE="$2"
            else
              VIASH_PAR_LIBRARY_TYPE="$VIASH_PAR_LIBRARY_TYPE;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --library_type. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --library_type=*)
            if [ -z "$VIASH_PAR_LIBRARY_TYPE" ]; then
              VIASH_PAR_LIBRARY_TYPE=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_LIBRARY_TYPE="$VIASH_PAR_LIBRARY_TYPE;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --library_subsample)
            if [ -z "$VIASH_PAR_LIBRARY_SUBSAMPLE" ]; then
              VIASH_PAR_LIBRARY_SUBSAMPLE="$2"
            else
              VIASH_PAR_LIBRARY_SUBSAMPLE="$VIASH_PAR_LIBRARY_SUBSAMPLE;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --library_subsample. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --library_subsample=*)
            if [ -z "$VIASH_PAR_LIBRARY_SUBSAMPLE" ]; then
              VIASH_PAR_LIBRARY_SUBSAMPLE=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_LIBRARY_SUBSAMPLE="$VIASH_PAR_LIBRARY_SUBSAMPLE;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --library_lanes)
            if [ -z "$VIASH_PAR_LIBRARY_LANES" ]; then
              VIASH_PAR_LIBRARY_LANES="$2"
            else
              VIASH_PAR_LIBRARY_LANES="$VIASH_PAR_LIBRARY_LANES;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --library_lanes. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --library_lanes=*)
            if [ -z "$VIASH_PAR_LIBRARY_LANES" ]; then
              VIASH_PAR_LIBRARY_LANES=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_LIBRARY_LANES="$VIASH_PAR_LIBRARY_LANES;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --library_chemistry)
            [ -n "$VIASH_PAR_LIBRARY_CHEMISTRY" ] && ViashError Bad arguments for option \'--library_chemistry\': \'$VIASH_PAR_LIBRARY_CHEMISTRY\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_LIBRARY_CHEMISTRY="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --library_chemistry. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --library_chemistry=*)
            [ -n "$VIASH_PAR_LIBRARY_CHEMISTRY" ] && ViashError Bad arguments for option \'--library_chemistry=*\': \'$VIASH_PAR_LIBRARY_CHEMISTRY\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_LIBRARY_CHEMISTRY=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --sample_ids)
            if [ -z "$VIASH_PAR_SAMPLE_IDS" ]; then
              VIASH_PAR_SAMPLE_IDS="$2"
            else
              VIASH_PAR_SAMPLE_IDS="$VIASH_PAR_SAMPLE_IDS;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --sample_ids. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --sample_ids=*)
            if [ -z "$VIASH_PAR_SAMPLE_IDS" ]; then
              VIASH_PAR_SAMPLE_IDS=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_SAMPLE_IDS="$VIASH_PAR_SAMPLE_IDS;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --cell_multiplex_sample_id)
            if [ -z "$VIASH_PAR_SAMPLE_IDS" ]; then
              VIASH_PAR_SAMPLE_IDS="$2"
            else
              VIASH_PAR_SAMPLE_IDS="$VIASH_PAR_SAMPLE_IDS;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --cell_multiplex_sample_id. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --sample_description)
            if [ -z "$VIASH_PAR_SAMPLE_DESCRIPTION" ]; then
              VIASH_PAR_SAMPLE_DESCRIPTION="$2"
            else
              VIASH_PAR_SAMPLE_DESCRIPTION="$VIASH_PAR_SAMPLE_DESCRIPTION;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --sample_description. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --sample_description=*)
            if [ -z "$VIASH_PAR_SAMPLE_DESCRIPTION" ]; then
              VIASH_PAR_SAMPLE_DESCRIPTION=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_SAMPLE_DESCRIPTION="$VIASH_PAR_SAMPLE_DESCRIPTION;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --cell_multiplex_description)
            if [ -z "$VIASH_PAR_SAMPLE_DESCRIPTION" ]; then
              VIASH_PAR_SAMPLE_DESCRIPTION="$2"
            else
              VIASH_PAR_SAMPLE_DESCRIPTION="$VIASH_PAR_SAMPLE_DESCRIPTION;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --cell_multiplex_description. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --sample_expect_cells)
            if [ -z "$VIASH_PAR_SAMPLE_EXPECT_CELLS" ]; then
              VIASH_PAR_SAMPLE_EXPECT_CELLS="$2"
            else
              VIASH_PAR_SAMPLE_EXPECT_CELLS="$VIASH_PAR_SAMPLE_EXPECT_CELLS;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --sample_expect_cells. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --sample_expect_cells=*)
            if [ -z "$VIASH_PAR_SAMPLE_EXPECT_CELLS" ]; then
              VIASH_PAR_SAMPLE_EXPECT_CELLS=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_SAMPLE_EXPECT_CELLS="$VIASH_PAR_SAMPLE_EXPECT_CELLS;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --sample_force_cells)
            if [ -z "$VIASH_PAR_SAMPLE_FORCE_CELLS" ]; then
              VIASH_PAR_SAMPLE_FORCE_CELLS="$2"
            else
              VIASH_PAR_SAMPLE_FORCE_CELLS="$VIASH_PAR_SAMPLE_FORCE_CELLS;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --sample_force_cells. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --sample_force_cells=*)
            if [ -z "$VIASH_PAR_SAMPLE_FORCE_CELLS" ]; then
              VIASH_PAR_SAMPLE_FORCE_CELLS=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_SAMPLE_FORCE_CELLS="$VIASH_PAR_SAMPLE_FORCE_CELLS;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --feature_reference)
            [ -n "$VIASH_PAR_FEATURE_REFERENCE" ] && ViashError Bad arguments for option \'--feature_reference\': \'$VIASH_PAR_FEATURE_REFERENCE\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_FEATURE_REFERENCE="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --feature_reference. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --feature_reference=*)
            [ -n "$VIASH_PAR_FEATURE_REFERENCE" ] && ViashError Bad arguments for option \'--feature_reference=*\': \'$VIASH_PAR_FEATURE_REFERENCE\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_FEATURE_REFERENCE=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --feature_r1_length)
            [ -n "$VIASH_PAR_FEATURE_R1_LENGTH" ] && ViashError Bad arguments for option \'--feature_r1_length\': \'$VIASH_PAR_FEATURE_R1_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_FEATURE_R1_LENGTH="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --feature_r1_length. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --feature_r1_length=*)
            [ -n "$VIASH_PAR_FEATURE_R1_LENGTH" ] && ViashError Bad arguments for option \'--feature_r1_length=*\': \'$VIASH_PAR_FEATURE_R1_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_FEATURE_R1_LENGTH=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --feature_r2_length)
            [ -n "$VIASH_PAR_FEATURE_R2_LENGTH" ] && ViashError Bad arguments for option \'--feature_r2_length\': \'$VIASH_PAR_FEATURE_R2_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_FEATURE_R2_LENGTH="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --feature_r2_length. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --feature_r2_length=*)
            [ -n "$VIASH_PAR_FEATURE_R2_LENGTH" ] && ViashError Bad arguments for option \'--feature_r2_length=*\': \'$VIASH_PAR_FEATURE_R2_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_FEATURE_R2_LENGTH=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --min_crispr_umi)
            [ -n "$VIASH_PAR_MIN_CRISPR_UMI" ] && ViashError Bad arguments for option \'--min_crispr_umi\': \'$VIASH_PAR_MIN_CRISPR_UMI\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_MIN_CRISPR_UMI="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --min_crispr_umi. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --min_crispr_umi=*)
            [ -n "$VIASH_PAR_MIN_CRISPR_UMI" ] && ViashError Bad arguments for option \'--min_crispr_umi=*\': \'$VIASH_PAR_MIN_CRISPR_UMI\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_MIN_CRISPR_UMI=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --gex_reference)
            [ -n "$VIASH_PAR_GEX_REFERENCE" ] && ViashError Bad arguments for option \'--gex_reference\': \'$VIASH_PAR_GEX_REFERENCE\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_REFERENCE="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_reference. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_reference=*)
            [ -n "$VIASH_PAR_GEX_REFERENCE" ] && ViashError Bad arguments for option \'--gex_reference=*\': \'$VIASH_PAR_GEX_REFERENCE\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_REFERENCE=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --gex_secondary_analysis)
            [ -n "$VIASH_PAR_GEX_SECONDARY_ANALYSIS" ] && ViashError Bad arguments for option \'--gex_secondary_analysis\': \'$VIASH_PAR_GEX_SECONDARY_ANALYSIS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_SECONDARY_ANALYSIS="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_secondary_analysis. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_secondary_analysis=*)
            [ -n "$VIASH_PAR_GEX_SECONDARY_ANALYSIS" ] && ViashError Bad arguments for option \'--gex_secondary_analysis=*\': \'$VIASH_PAR_GEX_SECONDARY_ANALYSIS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_SECONDARY_ANALYSIS=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --gex_generate_bam)
            [ -n "$VIASH_PAR_GEX_GENERATE_BAM" ] && ViashError Bad arguments for option \'--gex_generate_bam\': \'$VIASH_PAR_GEX_GENERATE_BAM\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_GENERATE_BAM="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_generate_bam. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_generate_bam=*)
            [ -n "$VIASH_PAR_GEX_GENERATE_BAM" ] && ViashError Bad arguments for option \'--gex_generate_bam=*\': \'$VIASH_PAR_GEX_GENERATE_BAM\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_GENERATE_BAM=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --gex_expect_cells)
            [ -n "$VIASH_PAR_GEX_EXPECT_CELLS" ] && ViashError Bad arguments for option \'--gex_expect_cells\': \'$VIASH_PAR_GEX_EXPECT_CELLS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_EXPECT_CELLS="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_expect_cells. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_expect_cells=*)
            [ -n "$VIASH_PAR_GEX_EXPECT_CELLS" ] && ViashError Bad arguments for option \'--gex_expect_cells=*\': \'$VIASH_PAR_GEX_EXPECT_CELLS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_EXPECT_CELLS=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --gex_force_cells)
            [ -n "$VIASH_PAR_GEX_FORCE_CELLS" ] && ViashError Bad arguments for option \'--gex_force_cells\': \'$VIASH_PAR_GEX_FORCE_CELLS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_FORCE_CELLS="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_force_cells. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_force_cells=*)
            [ -n "$VIASH_PAR_GEX_FORCE_CELLS" ] && ViashError Bad arguments for option \'--gex_force_cells=*\': \'$VIASH_PAR_GEX_FORCE_CELLS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_FORCE_CELLS=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --gex_include_introns)
            [ -n "$VIASH_PAR_GEX_INCLUDE_INTRONS" ] && ViashError Bad arguments for option \'--gex_include_introns\': \'$VIASH_PAR_GEX_INCLUDE_INTRONS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_INCLUDE_INTRONS="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_include_introns. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_include_introns=*)
            [ -n "$VIASH_PAR_GEX_INCLUDE_INTRONS" ] && ViashError Bad arguments for option \'--gex_include_introns=*\': \'$VIASH_PAR_GEX_INCLUDE_INTRONS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_INCLUDE_INTRONS=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --gex_r1_length)
            [ -n "$VIASH_PAR_GEX_R1_LENGTH" ] && ViashError Bad arguments for option \'--gex_r1_length\': \'$VIASH_PAR_GEX_R1_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_R1_LENGTH="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_r1_length. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_r1_length=*)
            [ -n "$VIASH_PAR_GEX_R1_LENGTH" ] && ViashError Bad arguments for option \'--gex_r1_length=*\': \'$VIASH_PAR_GEX_R1_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_R1_LENGTH=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --gex_r2_length)
            [ -n "$VIASH_PAR_GEX_R2_LENGTH" ] && ViashError Bad arguments for option \'--gex_r2_length\': \'$VIASH_PAR_GEX_R2_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_R2_LENGTH="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_r2_length. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_r2_length=*)
            [ -n "$VIASH_PAR_GEX_R2_LENGTH" ] && ViashError Bad arguments for option \'--gex_r2_length=*\': \'$VIASH_PAR_GEX_R2_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_R2_LENGTH=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --gex_chemistry)
            [ -n "$VIASH_PAR_GEX_CHEMISTRY" ] && ViashError Bad arguments for option \'--gex_chemistry\': \'$VIASH_PAR_GEX_CHEMISTRY\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_CHEMISTRY="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --gex_chemistry. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --gex_chemistry=*)
            [ -n "$VIASH_PAR_GEX_CHEMISTRY" ] && ViashError Bad arguments for option \'--gex_chemistry=*\': \'$VIASH_PAR_GEX_CHEMISTRY\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_GEX_CHEMISTRY=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --vdj_reference)
            [ -n "$VIASH_PAR_VDJ_REFERENCE" ] && ViashError Bad arguments for option \'--vdj_reference\': \'$VIASH_PAR_VDJ_REFERENCE\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_VDJ_REFERENCE="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --vdj_reference. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --vdj_reference=*)
            [ -n "$VIASH_PAR_VDJ_REFERENCE" ] && ViashError Bad arguments for option \'--vdj_reference=*\': \'$VIASH_PAR_VDJ_REFERENCE\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_VDJ_REFERENCE=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --vdj_inner_enrichment_primers)
            [ -n "$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS" ] && ViashError Bad arguments for option \'--vdj_inner_enrichment_primers\': \'$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --vdj_inner_enrichment_primers. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --vdj_inner_enrichment_primers=*)
            [ -n "$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS" ] && ViashError Bad arguments for option \'--vdj_inner_enrichment_primers=*\': \'$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --vdj_r1_length)
            [ -n "$VIASH_PAR_VDJ_R1_LENGTH" ] && ViashError Bad arguments for option \'--vdj_r1_length\': \'$VIASH_PAR_VDJ_R1_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_VDJ_R1_LENGTH="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --vdj_r1_length. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --vdj_r1_length=*)
            [ -n "$VIASH_PAR_VDJ_R1_LENGTH" ] && ViashError Bad arguments for option \'--vdj_r1_length=*\': \'$VIASH_PAR_VDJ_R1_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_VDJ_R1_LENGTH=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --vdj_r2_length)
            [ -n "$VIASH_PAR_VDJ_R2_LENGTH" ] && ViashError Bad arguments for option \'--vdj_r2_length\': \'$VIASH_PAR_VDJ_R2_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_VDJ_R2_LENGTH="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --vdj_r2_length. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --vdj_r2_length=*)
            [ -n "$VIASH_PAR_VDJ_R2_LENGTH" ] && ViashError Bad arguments for option \'--vdj_r2_length=*\': \'$VIASH_PAR_VDJ_R2_LENGTH\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_VDJ_R2_LENGTH=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --cell_multiplex_oligo_ids)
            if [ -z "$VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS" ]; then
              VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS="$2"
            else
              VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS="$VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --cell_multiplex_oligo_ids. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --cell_multiplex_oligo_ids=*)
            if [ -z "$VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS" ]; then
              VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS="$VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --min_assignment_confidence)
            [ -n "$VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE" ] && ViashError Bad arguments for option \'--min_assignment_confidence\': \'$VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --min_assignment_confidence. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --min_assignment_confidence=*)
            [ -n "$VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE" ] && ViashError Bad arguments for option \'--min_assignment_confidence=*\': \'$VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --cmo_set)
            [ -n "$VIASH_PAR_CMO_SET" ] && ViashError Bad arguments for option \'--cmo_set\': \'$VIASH_PAR_CMO_SET\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_CMO_SET="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --cmo_set. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --cmo_set=*)
            [ -n "$VIASH_PAR_CMO_SET" ] && ViashError Bad arguments for option \'--cmo_set=*\': \'$VIASH_PAR_CMO_SET\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_CMO_SET=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --barcode_sample_assignment)
            [ -n "$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT" ] && ViashError Bad arguments for option \'--barcode_sample_assignment\': \'$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --barcode_sample_assignment. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --barcode_sample_assignment=*)
            [ -n "$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT" ] && ViashError Bad arguments for option \'--barcode_sample_assignment=*\': \'$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --probe_set)
            [ -n "$VIASH_PAR_PROBE_SET" ] && ViashError Bad arguments for option \'--probe_set\': \'$VIASH_PAR_PROBE_SET\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_PROBE_SET="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --probe_set. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --probe_set=*)
            [ -n "$VIASH_PAR_PROBE_SET" ] && ViashError Bad arguments for option \'--probe_set=*\': \'$VIASH_PAR_PROBE_SET\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_PROBE_SET=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --filter_probes)
            [ -n "$VIASH_PAR_FILTER_PROBES" ] && ViashError Bad arguments for option \'--filter_probes\': \'$VIASH_PAR_FILTER_PROBES\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_FILTER_PROBES="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --filter_probes. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --filter_probes=*)
            [ -n "$VIASH_PAR_FILTER_PROBES" ] && ViashError Bad arguments for option \'--filter_probes=*\': \'$VIASH_PAR_FILTER_PROBES\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_FILTER_PROBES=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --probe_barcode_ids)
            if [ -z "$VIASH_PAR_PROBE_BARCODE_IDS" ]; then
              VIASH_PAR_PROBE_BARCODE_IDS="$2"
            else
              VIASH_PAR_PROBE_BARCODE_IDS="$VIASH_PAR_PROBE_BARCODE_IDS;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --probe_barcode_ids. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --probe_barcode_ids=*)
            if [ -z "$VIASH_PAR_PROBE_BARCODE_IDS" ]; then
              VIASH_PAR_PROBE_BARCODE_IDS=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_PROBE_BARCODE_IDS="$VIASH_PAR_PROBE_BARCODE_IDS;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --control_id)
            if [ -z "$VIASH_PAR_CONTROL_ID" ]; then
              VIASH_PAR_CONTROL_ID="$2"
            else
              VIASH_PAR_CONTROL_ID="$VIASH_PAR_CONTROL_ID;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --control_id. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --control_id=*)
            if [ -z "$VIASH_PAR_CONTROL_ID" ]; then
              VIASH_PAR_CONTROL_ID=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_CONTROL_ID="$VIASH_PAR_CONTROL_ID;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --mhc_allele)
            if [ -z "$VIASH_PAR_MHC_ALLELE" ]; then
              VIASH_PAR_MHC_ALLELE="$2"
            else
              VIASH_PAR_MHC_ALLELE="$VIASH_PAR_MHC_ALLELE;""$2"
            fi
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --mhc_allele. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --mhc_allele=*)
            if [ -z "$VIASH_PAR_MHC_ALLELE" ]; then
              VIASH_PAR_MHC_ALLELE=$(ViashRemoveFlags "$1")
            else
              VIASH_PAR_MHC_ALLELE="$VIASH_PAR_MHC_ALLELE;"$(ViashRemoveFlags "$1")
            fi
            shift 1
            ;;
        --check_library_compatibility)
            [ -n "$VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY" ] && ViashError Bad arguments for option \'--check_library_compatibility\': \'$VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --check_library_compatibility. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --check_library_compatibility=*)
            [ -n "$VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY" ] && ViashError Bad arguments for option \'--check_library_compatibility=*\': \'$VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --output)
            [ -n "$VIASH_PAR_OUTPUT" ] && ViashError Bad arguments for option \'--output\': \'$VIASH_PAR_OUTPUT\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_OUTPUT="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to --output. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        --output=*)
            [ -n "$VIASH_PAR_OUTPUT" ] && ViashError Bad arguments for option \'--output=*\': \'$VIASH_PAR_OUTPUT\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_OUTPUT=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        --dryrun)
            [ -n "$VIASH_PAR_DRYRUN" ] && ViashError Bad arguments for option \'--dryrun\': \'$VIASH_PAR_DRYRUN\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_PAR_DRYRUN=true
            shift 1
            ;;
        ---engine)
            VIASH_ENGINE_ID="$2"
            shift 2
            ;;
        ---engine=*)
            VIASH_ENGINE_ID="$(ViashRemoveFlags "$1")"
            shift 1
            ;;
        ---setup)
            VIASH_MODE='setup'
            VIASH_SETUP_STRATEGY="$2"
            shift 2
            ;;
        ---setup=*)
            VIASH_MODE='setup'
            VIASH_SETUP_STRATEGY="$(ViashRemoveFlags "$1")"
            shift 1
            ;;
        ---dockerfile)
            VIASH_MODE='dockerfile'
            shift 1
            ;;
        ---docker_run_args)
            VIASH_DOCKER_RUN_ARGS+=("$2")
            shift 2
            ;;
        ---docker_run_args=*)
            VIASH_DOCKER_RUN_ARGS+=("$(ViashRemoveFlags "$1")")
            shift 1
            ;;
        ---docker_image_id)
            VIASH_MODE='docker_image_id'
            shift 1
            ;;
        ---debug)
            VIASH_MODE='debug'
            shift 1
            ;;
        ---cpus)
            [ -n "$VIASH_META_CPUS" ] && ViashError Bad arguments for option \'---cpus\': \'$VIASH_META_CPUS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_META_CPUS="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to ---cpus. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        ---cpus=*)
            [ -n "$VIASH_META_CPUS" ] && ViashError Bad arguments for option \'---cpus=*\': \'$VIASH_META_CPUS\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_META_CPUS=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        ---memory)
            [ -n "$VIASH_META_MEMORY" ] && ViashError Bad arguments for option \'---memory\': \'$VIASH_META_MEMORY\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_META_MEMORY="$2"
            [ $# -lt 2 ] && ViashError Not enough arguments passed to ---memory. Use "--help" to get more information on the parameters. && exit 1
            shift 2
            ;;
        ---memory=*)
            [ -n "$VIASH_META_MEMORY" ] && ViashError Bad arguments for option \'---memory=*\': \'$VIASH_META_MEMORY\' \& \'$2\' - you should provide exactly one argument for this option. && exit 1
            VIASH_META_MEMORY=$(ViashRemoveFlags "$1")
            shift 1
            ;;
        *)  # positional arg or unknown option
            # since the positional args will be eval'd, can we always quote, instead of using ViashQuote
            VIASH_POSITIONAL_ARGS="$VIASH_POSITIONAL_ARGS '$1'"
            [[ $1 == -* ]] && ViashWarning $1 looks like a parameter but is not a defined parameter and will instead be treated as a positional argument. Use "--help" to get more information on the parameters.
            shift # past argument
            ;;
    esac
done

# parse positional parameters
eval set -- $VIASH_POSITIONAL_ARGS


if   [ "$VIASH_ENGINE_ID" == "native" ]  ; then
  VIASH_ENGINE_TYPE='native'
elif   [ "$VIASH_ENGINE_ID" == "docker" ]  ; then
  VIASH_ENGINE_TYPE='docker'
else
  ViashError "Engine '$VIASH_ENGINE_ID' is not recognized. Options are: docker, native."
  exit 1
fi

if [[ "$VIASH_ENGINE_TYPE" == "docker" ]]; then
  # check if docker is installed properly
  ViashDockerInstallationCheck

  # determine docker image id
  if [[ "$VIASH_ENGINE_ID" == 'docker' ]]; then
    VIASH_DOCKER_IMAGE_ID='images.viash-hub.com/vsh/openpipeline/mapping/cellranger_multi:fix-integration-tests'
  fi

  # print dockerfile
  if [ "$VIASH_MODE" == "dockerfile" ]; then
    ViashDockerfile "$VIASH_ENGINE_ID"
    exit 0

  elif [ "$VIASH_MODE" == "docker_image_id" ]; then
    echo "$VIASH_DOCKER_IMAGE_ID"
    exit 0
  
  # enter docker container
  elif [[ "$VIASH_MODE" == "debug" ]]; then
    VIASH_CMD="docker run --entrypoint=bash ${VIASH_DOCKER_RUN_ARGS[@]} -v '$(pwd)':/pwd --workdir /pwd -t $VIASH_DOCKER_IMAGE_ID"
    ViashNotice "+ $VIASH_CMD"
    eval $VIASH_CMD
    exit 

  # build docker image
  elif [ "$VIASH_MODE" == "setup" ]; then
    ViashDockerSetup "$VIASH_DOCKER_IMAGE_ID" "$VIASH_SETUP_STRATEGY"
    ViashDockerCheckCommands "$VIASH_DOCKER_IMAGE_ID" 'bash'
    exit 0
  fi

  # check if docker image exists
  ViashDockerSetup "$VIASH_DOCKER_IMAGE_ID" ifneedbepullelsecachedbuild
  ViashDockerCheckCommands "$VIASH_DOCKER_IMAGE_ID" 'bash'
fi

# setting computational defaults

# helper function for parsing memory strings
function ViashMemoryAsBytes {
  local memory=`echo "$1" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]'`
  local memory_regex='^([0-9]+)([kmgtp]i?b?|b)$'
  if [[ $memory =~ $memory_regex ]]; then
    local number=${memory/[^0-9]*/}
    local symbol=${memory/*[0-9]/}
    
    case $symbol in
      b)      memory_b=$number ;;
      kb|k)   memory_b=$(( $number * 1000 )) ;;
      mb|m)   memory_b=$(( $number * 1000 * 1000 )) ;;
      gb|g)   memory_b=$(( $number * 1000 * 1000 * 1000 )) ;;
      tb|t)   memory_b=$(( $number * 1000 * 1000 * 1000 * 1000 )) ;;
      pb|p)   memory_b=$(( $number * 1000 * 1000 * 1000 * 1000 * 1000 )) ;;
      kib|ki)   memory_b=$(( $number * 1024 )) ;;
      mib|mi)   memory_b=$(( $number * 1024 * 1024 )) ;;
      gib|gi)   memory_b=$(( $number * 1024 * 1024 * 1024 )) ;;
      tib|ti)   memory_b=$(( $number * 1024 * 1024 * 1024 * 1024 )) ;;
      pib|pi)   memory_b=$(( $number * 1024 * 1024 * 1024 * 1024 * 1024 )) ;;
    esac
    echo "$memory_b"
  fi
}
# compute memory in different units
if [ ! -z ${VIASH_META_MEMORY+x} ]; then
  VIASH_META_MEMORY_B=`ViashMemoryAsBytes $VIASH_META_MEMORY`
  # do not define other variables if memory_b is an empty string
  if [ ! -z "$VIASH_META_MEMORY_B" ]; then
    VIASH_META_MEMORY_KB=$(( ($VIASH_META_MEMORY_B+999) / 1000 ))
    VIASH_META_MEMORY_MB=$(( ($VIASH_META_MEMORY_KB+999) / 1000 ))
    VIASH_META_MEMORY_GB=$(( ($VIASH_META_MEMORY_MB+999) / 1000 ))
    VIASH_META_MEMORY_TB=$(( ($VIASH_META_MEMORY_GB+999) / 1000 ))
    VIASH_META_MEMORY_PB=$(( ($VIASH_META_MEMORY_TB+999) / 1000 ))
    VIASH_META_MEMORY_KIB=$(( ($VIASH_META_MEMORY_B+1023) / 1024 ))
    VIASH_META_MEMORY_MIB=$(( ($VIASH_META_MEMORY_KIB+1023) / 1024 ))
    VIASH_META_MEMORY_GIB=$(( ($VIASH_META_MEMORY_MIB+1023) / 1024 ))
    VIASH_META_MEMORY_TIB=$(( ($VIASH_META_MEMORY_GIB+1023) / 1024 ))
    VIASH_META_MEMORY_PIB=$(( ($VIASH_META_MEMORY_TIB+1023) / 1024 ))
  else
    # unset memory if string is empty
    unset $VIASH_META_MEMORY_B
  fi
fi
# unset nproc if string is empty
if [ -z "$VIASH_META_CPUS" ]; then
  unset $VIASH_META_CPUS
fi


# check whether required parameters exist
if [ -z ${VIASH_PAR_GEX_REFERENCE+x} ]; then
  ViashError '--gex_reference' is a required argument. Use "--help" to get more information on the parameters.
  exit 1
fi
if [ -z ${VIASH_PAR_OUTPUT+x} ]; then
  ViashError '--output' is a required argument. Use "--help" to get more information on the parameters.
  exit 1
fi
if [ -z ${VIASH_META_NAME+x} ]; then
  ViashError 'name' is a required argument. Use "--help" to get more information on the parameters.
  exit 1
fi
if [ -z ${VIASH_META_FUNCTIONALITY_NAME+x} ]; then
  ViashError 'functionality_name' is a required argument. Use "--help" to get more information on the parameters.
  exit 1
fi
if [ -z ${VIASH_META_RESOURCES_DIR+x} ]; then
  ViashError 'resources_dir' is a required argument. Use "--help" to get more information on the parameters.
  exit 1
fi
if [ -z ${VIASH_META_EXECUTABLE+x} ]; then
  ViashError 'executable' is a required argument. Use "--help" to get more information on the parameters.
  exit 1
fi
if [ -z ${VIASH_META_CONFIG+x} ]; then
  ViashError 'config' is a required argument. Use "--help" to get more information on the parameters.
  exit 1
fi
if [ -z ${VIASH_META_TEMP_DIR+x} ]; then
  ViashError 'temp_dir' is a required argument. Use "--help" to get more information on the parameters.
  exit 1
fi

# filling in defaults
if [ -z ${VIASH_PAR_GEX_SECONDARY_ANALYSIS+x} ]; then
  VIASH_PAR_GEX_SECONDARY_ANALYSIS="false"
fi
if [ -z ${VIASH_PAR_GEX_GENERATE_BAM+x} ]; then
  VIASH_PAR_GEX_GENERATE_BAM="false"
fi
if [ -z ${VIASH_PAR_GEX_INCLUDE_INTRONS+x} ]; then
  VIASH_PAR_GEX_INCLUDE_INTRONS="true"
fi
if [ -z ${VIASH_PAR_GEX_CHEMISTRY+x} ]; then
  VIASH_PAR_GEX_CHEMISTRY="auto"
fi
if [ -z ${VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY+x} ]; then
  VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY="true"
fi
if [ -z ${VIASH_PAR_DRYRUN+x} ]; then
  VIASH_PAR_DRYRUN="false"
fi

# check whether required files exist
if [ ! -z "$VIASH_PAR_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_GEX_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_GEX_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_ABC_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_ABC_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_CGC_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_CGC_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_MUX_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_MUX_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_VDJ_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_VDJ_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_VDJ_T_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_VDJ_T_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_VDJ_T_GD_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_VDJ_T_GD_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_VDJ_B_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_VDJ_B_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_AGC_INPUT" ]; then
  IFS=';'
  set -f
  for file in $VIASH_PAR_AGC_INPUT; do
    unset IFS
    if [ ! -e "$file" ]; then
      ViashError "Input file '$file' does not exist."
      exit 1
    fi
  done
  set +f
fi
if [ ! -z "$VIASH_PAR_FEATURE_REFERENCE" ] && [ ! -e "$VIASH_PAR_FEATURE_REFERENCE" ]; then
  ViashError "Input file '$VIASH_PAR_FEATURE_REFERENCE' does not exist."
  exit 1
fi
if [ ! -z "$VIASH_PAR_GEX_REFERENCE" ] && [ ! -e "$VIASH_PAR_GEX_REFERENCE" ]; then
  ViashError "Input file '$VIASH_PAR_GEX_REFERENCE' does not exist."
  exit 1
fi
if [ ! -z "$VIASH_PAR_VDJ_REFERENCE" ] && [ ! -e "$VIASH_PAR_VDJ_REFERENCE" ]; then
  ViashError "Input file '$VIASH_PAR_VDJ_REFERENCE' does not exist."
  exit 1
fi
if [ ! -z "$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS" ] && [ ! -e "$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS" ]; then
  ViashError "Input file '$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS' does not exist."
  exit 1
fi
if [ ! -z "$VIASH_PAR_CMO_SET" ] && [ ! -e "$VIASH_PAR_CMO_SET" ]; then
  ViashError "Input file '$VIASH_PAR_CMO_SET' does not exist."
  exit 1
fi
if [ ! -z "$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT" ] && [ ! -e "$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT" ]; then
  ViashError "Input file '$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT' does not exist."
  exit 1
fi
if [ ! -z "$VIASH_PAR_PROBE_SET" ] && [ ! -e "$VIASH_PAR_PROBE_SET" ]; then
  ViashError "Input file '$VIASH_PAR_PROBE_SET' does not exist."
  exit 1
fi

# check whether parameters values are of the right type
if [ -n "$VIASH_PAR_SAMPLE_EXPECT_CELLS" ]; then
  IFS=';'
  set -f
  for val in $VIASH_PAR_SAMPLE_EXPECT_CELLS; do
    if ! [[ "${val}" =~ ^[-+]?[0-9]+$ ]]; then
      ViashError '--sample_expect_cells' has to be an integer. Use "--help" to get more information on the parameters.
      exit 1
    fi
  done
  set +f
  unset IFS
fi

if [ -n "$VIASH_PAR_SAMPLE_FORCE_CELLS" ]; then
  IFS=';'
  set -f
  for val in $VIASH_PAR_SAMPLE_FORCE_CELLS; do
    if ! [[ "${val}" =~ ^[-+]?[0-9]+$ ]]; then
      ViashError '--sample_force_cells' has to be an integer. Use "--help" to get more information on the parameters.
      exit 1
    fi
  done
  set +f
  unset IFS
fi

if [[ -n "$VIASH_PAR_FEATURE_R1_LENGTH" ]]; then
  if ! [[ "$VIASH_PAR_FEATURE_R1_LENGTH" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError '--feature_r1_length' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_FEATURE_R2_LENGTH" ]]; then
  if ! [[ "$VIASH_PAR_FEATURE_R2_LENGTH" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError '--feature_r2_length' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_MIN_CRISPR_UMI" ]]; then
  if ! [[ "$VIASH_PAR_MIN_CRISPR_UMI" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError '--min_crispr_umi' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
  if [[ $VIASH_PAR_MIN_CRISPR_UMI -lt 1 ]]; then
    ViashError '--min_crispr_umi' has be more than or equal to 1. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_GEX_SECONDARY_ANALYSIS" ]]; then
  if ! [[ "$VIASH_PAR_GEX_SECONDARY_ANALYSIS" =~ ^(true|True|TRUE|false|False|FALSE|yes|Yes|YES|no|No|NO)$ ]]; then
    ViashError '--gex_secondary_analysis' has to be a boolean. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_GEX_GENERATE_BAM" ]]; then
  if ! [[ "$VIASH_PAR_GEX_GENERATE_BAM" =~ ^(true|True|TRUE|false|False|FALSE|yes|Yes|YES|no|No|NO)$ ]]; then
    ViashError '--gex_generate_bam' has to be a boolean. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_GEX_EXPECT_CELLS" ]]; then
  if ! [[ "$VIASH_PAR_GEX_EXPECT_CELLS" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError '--gex_expect_cells' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_GEX_FORCE_CELLS" ]]; then
  if ! [[ "$VIASH_PAR_GEX_FORCE_CELLS" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError '--gex_force_cells' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_GEX_INCLUDE_INTRONS" ]]; then
  if ! [[ "$VIASH_PAR_GEX_INCLUDE_INTRONS" =~ ^(true|True|TRUE|false|False|FALSE|yes|Yes|YES|no|No|NO)$ ]]; then
    ViashError '--gex_include_introns' has to be a boolean. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_GEX_R1_LENGTH" ]]; then
  if ! [[ "$VIASH_PAR_GEX_R1_LENGTH" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError '--gex_r1_length' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_GEX_R2_LENGTH" ]]; then
  if ! [[ "$VIASH_PAR_GEX_R2_LENGTH" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError '--gex_r2_length' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_VDJ_R1_LENGTH" ]]; then
  if ! [[ "$VIASH_PAR_VDJ_R1_LENGTH" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError '--vdj_r1_length' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_VDJ_R2_LENGTH" ]]; then
  if ! [[ "$VIASH_PAR_VDJ_R2_LENGTH" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError '--vdj_r2_length' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE" ]]; then
  if ! [[ "$VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE" =~ ^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$ ]]; then
    ViashError '--min_assignment_confidence' has to be a double. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_FILTER_PROBES" ]]; then
  if ! [[ "$VIASH_PAR_FILTER_PROBES" =~ ^(true|True|TRUE|false|False|FALSE|yes|Yes|YES|no|No|NO)$ ]]; then
    ViashError '--filter_probes' has to be a boolean. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY" ]]; then
  if ! [[ "$VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY" =~ ^(true|True|TRUE|false|False|FALSE|yes|Yes|YES|no|No|NO)$ ]]; then
    ViashError '--check_library_compatibility' has to be a boolean. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_PAR_DRYRUN" ]]; then
  if ! [[ "$VIASH_PAR_DRYRUN" =~ ^(true|True|TRUE|false|False|FALSE|yes|Yes|YES|no|No|NO)$ ]]; then
    ViashError '--dryrun' has to be a boolean_true. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_CPUS" ]]; then
  if ! [[ "$VIASH_META_CPUS" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'cpus' has to be an integer. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_B" ]]; then
  if ! [[ "$VIASH_META_MEMORY_B" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_b' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_KB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_KB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_kb' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_MB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_MB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_mb' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_GB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_GB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_gb' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_TB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_TB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_tb' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_PB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_PB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_pb' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_KIB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_KIB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_kib' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_MIB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_MIB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_mib' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_GIB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_GIB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_gib' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_TIB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_TIB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_tib' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi
if [[ -n "$VIASH_META_MEMORY_PIB" ]]; then
  if ! [[ "$VIASH_META_MEMORY_PIB" =~ ^[-+]?[0-9]+$ ]]; then
    ViashError 'memory_pib' has to be a long. Use "--help" to get more information on the parameters.
    exit 1
  fi
fi

# check whether value is belongs to a set of choices
if [ ! -z "$VIASH_PAR_LIBRARY_TYPE" ]; then
  VIASH_PAR_LIBRARY_TYPE_CHOICES=("Gene Expression;VDJ;VDJ-T;VDJ-B;VDJ-T-GD;Antibody Capture;CRISPR Guide Capture;Multiplexing Capture;Antigen Capture;Custom")
  IFS=';'
  set -f
  for val in $VIASH_PAR_LIBRARY_TYPE; do
    if ! [[ ";${VIASH_PAR_LIBRARY_TYPE_CHOICES[*]};" =~ ";${val};" ]]; then
      ViashError '--library_type' specified value of \'${val}\' is not in the list of allowed values. Use "--help" to get more information on the parameters.
      exit 1
    fi
  done
  set +f
  unset IFS
fi

if [ ! -z "$VIASH_PAR_GEX_CHEMISTRY" ]; then
  VIASH_PAR_GEX_CHEMISTRY_CHOICES=("auto;threeprime;fiveprime;SC3Pv1;SC3Pv2;SC3Pv3;SC3Pv4;SC3Pv3LT;SC3Pv3HT;SC5P-PE;SC5P-R2;SC-FB;SC5P-R2-v3;SCP5-PE-v3;SC5PHT;MFRP;MFRP-R1;MFRP-RNA;MFRP-Ab;SFRP;MFRP-Ab-R2pos50;MFRP-RNA-R1;MFRP-Ab-R1;ARC-v1")
  IFS=';'
  set -f
  if ! [[ ";${VIASH_PAR_GEX_CHEMISTRY_CHOICES[*]};" =~ ";$VIASH_PAR_GEX_CHEMISTRY;" ]]; then
    ViashError '--gex_chemistry' specified value of \'$VIASH_PAR_GEX_CHEMISTRY\' is not in the list of allowed values. Use "--help" to get more information on the parameters.
    exit 1
  fi
  set +f
  unset IFS
fi

# create parent directories of output files, if so desired
if [ ! -z "$VIASH_PAR_OUTPUT" ] && [ ! -d "$(dirname "$VIASH_PAR_OUTPUT")" ]; then
  mkdir -p "$(dirname "$VIASH_PAR_OUTPUT")"
fi

if  [ "$VIASH_ENGINE_ID" == "native" ]  ; then
  if [ "$VIASH_MODE" == "run" ]; then
    VIASH_CMD="bash"
  else
    ViashError "Engine '$VIASH_ENGINE_ID' does not support mode '$VIASH_MODE'."
    exit 1
  fi
fi

if [[ "$VIASH_ENGINE_TYPE" == "docker" ]]; then
  # detect volumes from file arguments
  VIASH_CHOWN_VARS=()
if [ ! -z "$VIASH_PAR_INPUT" ]; then
  VIASH_TEST_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_INPUT+=( "$var" )
  done
  VIASH_PAR_INPUT=$(IFS=';' ; echo "${VIASH_TEST_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_GEX_INPUT" ]; then
  VIASH_TEST_GEX_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_GEX_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_GEX_INPUT+=( "$var" )
  done
  VIASH_PAR_GEX_INPUT=$(IFS=';' ; echo "${VIASH_TEST_GEX_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_ABC_INPUT" ]; then
  VIASH_TEST_ABC_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_ABC_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_ABC_INPUT+=( "$var" )
  done
  VIASH_PAR_ABC_INPUT=$(IFS=';' ; echo "${VIASH_TEST_ABC_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_CGC_INPUT" ]; then
  VIASH_TEST_CGC_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_CGC_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_CGC_INPUT+=( "$var" )
  done
  VIASH_PAR_CGC_INPUT=$(IFS=';' ; echo "${VIASH_TEST_CGC_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_MUX_INPUT" ]; then
  VIASH_TEST_MUX_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_MUX_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_MUX_INPUT+=( "$var" )
  done
  VIASH_PAR_MUX_INPUT=$(IFS=';' ; echo "${VIASH_TEST_MUX_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_VDJ_INPUT" ]; then
  VIASH_TEST_VDJ_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_VDJ_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_VDJ_INPUT+=( "$var" )
  done
  VIASH_PAR_VDJ_INPUT=$(IFS=';' ; echo "${VIASH_TEST_VDJ_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_VDJ_T_INPUT" ]; then
  VIASH_TEST_VDJ_T_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_VDJ_T_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_VDJ_T_INPUT+=( "$var" )
  done
  VIASH_PAR_VDJ_T_INPUT=$(IFS=';' ; echo "${VIASH_TEST_VDJ_T_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_VDJ_T_GD_INPUT" ]; then
  VIASH_TEST_VDJ_T_GD_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_VDJ_T_GD_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_VDJ_T_GD_INPUT+=( "$var" )
  done
  VIASH_PAR_VDJ_T_GD_INPUT=$(IFS=';' ; echo "${VIASH_TEST_VDJ_T_GD_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_VDJ_B_INPUT" ]; then
  VIASH_TEST_VDJ_B_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_VDJ_B_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_VDJ_B_INPUT+=( "$var" )
  done
  VIASH_PAR_VDJ_B_INPUT=$(IFS=';' ; echo "${VIASH_TEST_VDJ_B_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_AGC_INPUT" ]; then
  VIASH_TEST_AGC_INPUT=()
  IFS=';'
  for var in $VIASH_PAR_AGC_INPUT; do
    unset IFS
    VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$var")" )
    var=$(ViashDockerAutodetectMount "$var")
    VIASH_TEST_AGC_INPUT+=( "$var" )
  done
  VIASH_PAR_AGC_INPUT=$(IFS=';' ; echo "${VIASH_TEST_AGC_INPUT[*]}")
fi
if [ ! -z "$VIASH_PAR_FEATURE_REFERENCE" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_PAR_FEATURE_REFERENCE")" )
  VIASH_PAR_FEATURE_REFERENCE=$(ViashDockerAutodetectMount "$VIASH_PAR_FEATURE_REFERENCE")
fi
if [ ! -z "$VIASH_PAR_GEX_REFERENCE" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_PAR_GEX_REFERENCE")" )
  VIASH_PAR_GEX_REFERENCE=$(ViashDockerAutodetectMount "$VIASH_PAR_GEX_REFERENCE")
fi
if [ ! -z "$VIASH_PAR_VDJ_REFERENCE" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_PAR_VDJ_REFERENCE")" )
  VIASH_PAR_VDJ_REFERENCE=$(ViashDockerAutodetectMount "$VIASH_PAR_VDJ_REFERENCE")
fi
if [ ! -z "$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS")" )
  VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS=$(ViashDockerAutodetectMount "$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS")
fi
if [ ! -z "$VIASH_PAR_CMO_SET" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_PAR_CMO_SET")" )
  VIASH_PAR_CMO_SET=$(ViashDockerAutodetectMount "$VIASH_PAR_CMO_SET")
fi
if [ ! -z "$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT")" )
  VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT=$(ViashDockerAutodetectMount "$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT")
fi
if [ ! -z "$VIASH_PAR_PROBE_SET" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_PAR_PROBE_SET")" )
  VIASH_PAR_PROBE_SET=$(ViashDockerAutodetectMount "$VIASH_PAR_PROBE_SET")
fi
if [ ! -z "$VIASH_PAR_OUTPUT" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_PAR_OUTPUT")" )
  VIASH_PAR_OUTPUT=$(ViashDockerAutodetectMount "$VIASH_PAR_OUTPUT")
  VIASH_CHOWN_VARS+=( "$VIASH_PAR_OUTPUT" )
fi
if [ ! -z "$VIASH_META_RESOURCES_DIR" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_META_RESOURCES_DIR")" )
  VIASH_META_RESOURCES_DIR=$(ViashDockerAutodetectMount "$VIASH_META_RESOURCES_DIR")
fi
if [ ! -z "$VIASH_META_EXECUTABLE" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_META_EXECUTABLE")" )
  VIASH_META_EXECUTABLE=$(ViashDockerAutodetectMount "$VIASH_META_EXECUTABLE")
fi
if [ ! -z "$VIASH_META_CONFIG" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_META_CONFIG")" )
  VIASH_META_CONFIG=$(ViashDockerAutodetectMount "$VIASH_META_CONFIG")
fi
if [ ! -z "$VIASH_META_TEMP_DIR" ]; then
  VIASH_DIRECTORY_MOUNTS+=( "$(ViashDockerAutodetectMountArg "$VIASH_META_TEMP_DIR")" )
  VIASH_META_TEMP_DIR=$(ViashDockerAutodetectMount "$VIASH_META_TEMP_DIR")
fi
  
  # get unique mounts
  VIASH_UNIQUE_MOUNTS=($(for val in "${VIASH_DIRECTORY_MOUNTS[@]}"; do echo "$val"; done | sort -u))
fi

if [[ "$VIASH_ENGINE_TYPE" == "docker" ]]; then
  # change file ownership
  function ViashPerformChown {
    if (( ${#VIASH_CHOWN_VARS[@]} )); then
      set +e
      VIASH_CMD="docker run --entrypoint=bash --rm ${VIASH_UNIQUE_MOUNTS[@]} $VIASH_DOCKER_IMAGE_ID -c 'chown $(id -u):$(id -g) --silent --recursive ${VIASH_CHOWN_VARS[@]}'"
      ViashDebug "+ $VIASH_CMD"
      eval $VIASH_CMD
      set -e
    fi
  }
  trap ViashPerformChown EXIT
fi

if [[ "$VIASH_ENGINE_TYPE" == "docker" ]]; then
  # helper function for filling in extra docker args
  if [ ! -z "$VIASH_META_MEMORY_B" ]; then
    VIASH_DOCKER_RUN_ARGS+=("--memory=${VIASH_META_MEMORY_B}")
  fi
  if [ ! -z "$VIASH_META_CPUS" ]; then
    VIASH_DOCKER_RUN_ARGS+=("--cpus=${VIASH_META_CPUS}")
  fi
fi

if [[ "$VIASH_ENGINE_TYPE" == "docker" ]]; then
  VIASH_CMD="docker run --entrypoint=bash ${VIASH_DOCKER_RUN_ARGS[@]} ${VIASH_UNIQUE_MOUNTS[@]} $VIASH_DOCKER_IMAGE_ID"
fi


# set dependency paths


ViashDebug "Running command: $(echo $VIASH_CMD)"
cat << VIASHEOF | eval $VIASH_CMD
set -e
tempscript=\$(mktemp "$VIASH_META_TEMP_DIR/viash-run-cellranger_multi-XXXXXX").py
function clean_up {
  rm "\$tempscript"
}
function interrupt {
  echo -e "\nCTRL-C Pressed..."
  exit 1
}
trap clean_up EXIT
trap interrupt INT SIGINT
cat > "\$tempscript" << 'VIASHMAIN'
from __future__ import annotations

import sys
import re
import subprocess
import tempfile
import pandas as pd
import yaml
from typing import Optional, Any, Union
import tarfile
from pathlib import Path
import shutil
from itertools import chain

## VIASH START
# The following code has been auto-generated by Viash.
par = {
  'input': $( if [ ! -z ${VIASH_PAR_INPUT+x} ]; then echo "r'${VIASH_PAR_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'gex_input': $( if [ ! -z ${VIASH_PAR_GEX_INPUT+x} ]; then echo "r'${VIASH_PAR_GEX_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'abc_input': $( if [ ! -z ${VIASH_PAR_ABC_INPUT+x} ]; then echo "r'${VIASH_PAR_ABC_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'cgc_input': $( if [ ! -z ${VIASH_PAR_CGC_INPUT+x} ]; then echo "r'${VIASH_PAR_CGC_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'mux_input': $( if [ ! -z ${VIASH_PAR_MUX_INPUT+x} ]; then echo "r'${VIASH_PAR_MUX_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'vdj_input': $( if [ ! -z ${VIASH_PAR_VDJ_INPUT+x} ]; then echo "r'${VIASH_PAR_VDJ_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'vdj_t_input': $( if [ ! -z ${VIASH_PAR_VDJ_T_INPUT+x} ]; then echo "r'${VIASH_PAR_VDJ_T_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'vdj_t_gd_input': $( if [ ! -z ${VIASH_PAR_VDJ_T_GD_INPUT+x} ]; then echo "r'${VIASH_PAR_VDJ_T_GD_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'vdj_b_input': $( if [ ! -z ${VIASH_PAR_VDJ_B_INPUT+x} ]; then echo "r'${VIASH_PAR_VDJ_B_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'agc_input': $( if [ ! -z ${VIASH_PAR_AGC_INPUT+x} ]; then echo "r'${VIASH_PAR_AGC_INPUT//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'library_id': $( if [ ! -z ${VIASH_PAR_LIBRARY_ID+x} ]; then echo "r'${VIASH_PAR_LIBRARY_ID//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'library_type': $( if [ ! -z ${VIASH_PAR_LIBRARY_TYPE+x} ]; then echo "r'${VIASH_PAR_LIBRARY_TYPE//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'library_subsample': $( if [ ! -z ${VIASH_PAR_LIBRARY_SUBSAMPLE+x} ]; then echo "r'${VIASH_PAR_LIBRARY_SUBSAMPLE//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'library_lanes': $( if [ ! -z ${VIASH_PAR_LIBRARY_LANES+x} ]; then echo "r'${VIASH_PAR_LIBRARY_LANES//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'library_chemistry': $( if [ ! -z ${VIASH_PAR_LIBRARY_CHEMISTRY+x} ]; then echo "r'${VIASH_PAR_LIBRARY_CHEMISTRY//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'sample_ids': $( if [ ! -z ${VIASH_PAR_SAMPLE_IDS+x} ]; then echo "r'${VIASH_PAR_SAMPLE_IDS//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'sample_description': $( if [ ! -z ${VIASH_PAR_SAMPLE_DESCRIPTION+x} ]; then echo "r'${VIASH_PAR_SAMPLE_DESCRIPTION//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'sample_expect_cells': $( if [ ! -z ${VIASH_PAR_SAMPLE_EXPECT_CELLS+x} ]; then echo "list(map(int, r'${VIASH_PAR_SAMPLE_EXPECT_CELLS//\'/\'\"\'\"r\'}'.split(';')))"; else echo None; fi ),
  'sample_force_cells': $( if [ ! -z ${VIASH_PAR_SAMPLE_FORCE_CELLS+x} ]; then echo "list(map(int, r'${VIASH_PAR_SAMPLE_FORCE_CELLS//\'/\'\"\'\"r\'}'.split(';')))"; else echo None; fi ),
  'feature_reference': $( if [ ! -z ${VIASH_PAR_FEATURE_REFERENCE+x} ]; then echo "r'${VIASH_PAR_FEATURE_REFERENCE//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'feature_r1_length': $( if [ ! -z ${VIASH_PAR_FEATURE_R1_LENGTH+x} ]; then echo "int(r'${VIASH_PAR_FEATURE_R1_LENGTH//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'feature_r2_length': $( if [ ! -z ${VIASH_PAR_FEATURE_R2_LENGTH+x} ]; then echo "int(r'${VIASH_PAR_FEATURE_R2_LENGTH//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'min_crispr_umi': $( if [ ! -z ${VIASH_PAR_MIN_CRISPR_UMI+x} ]; then echo "int(r'${VIASH_PAR_MIN_CRISPR_UMI//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'gex_reference': $( if [ ! -z ${VIASH_PAR_GEX_REFERENCE+x} ]; then echo "r'${VIASH_PAR_GEX_REFERENCE//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'gex_secondary_analysis': $( if [ ! -z ${VIASH_PAR_GEX_SECONDARY_ANALYSIS+x} ]; then echo "r'${VIASH_PAR_GEX_SECONDARY_ANALYSIS//\'/\'\"\'\"r\'}'.lower() == 'true'"; else echo None; fi ),
  'gex_generate_bam': $( if [ ! -z ${VIASH_PAR_GEX_GENERATE_BAM+x} ]; then echo "r'${VIASH_PAR_GEX_GENERATE_BAM//\'/\'\"\'\"r\'}'.lower() == 'true'"; else echo None; fi ),
  'gex_expect_cells': $( if [ ! -z ${VIASH_PAR_GEX_EXPECT_CELLS+x} ]; then echo "int(r'${VIASH_PAR_GEX_EXPECT_CELLS//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'gex_force_cells': $( if [ ! -z ${VIASH_PAR_GEX_FORCE_CELLS+x} ]; then echo "int(r'${VIASH_PAR_GEX_FORCE_CELLS//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'gex_include_introns': $( if [ ! -z ${VIASH_PAR_GEX_INCLUDE_INTRONS+x} ]; then echo "r'${VIASH_PAR_GEX_INCLUDE_INTRONS//\'/\'\"\'\"r\'}'.lower() == 'true'"; else echo None; fi ),
  'gex_r1_length': $( if [ ! -z ${VIASH_PAR_GEX_R1_LENGTH+x} ]; then echo "int(r'${VIASH_PAR_GEX_R1_LENGTH//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'gex_r2_length': $( if [ ! -z ${VIASH_PAR_GEX_R2_LENGTH+x} ]; then echo "int(r'${VIASH_PAR_GEX_R2_LENGTH//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'gex_chemistry': $( if [ ! -z ${VIASH_PAR_GEX_CHEMISTRY+x} ]; then echo "r'${VIASH_PAR_GEX_CHEMISTRY//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'vdj_reference': $( if [ ! -z ${VIASH_PAR_VDJ_REFERENCE+x} ]; then echo "r'${VIASH_PAR_VDJ_REFERENCE//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'vdj_inner_enrichment_primers': $( if [ ! -z ${VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS+x} ]; then echo "r'${VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'vdj_r1_length': $( if [ ! -z ${VIASH_PAR_VDJ_R1_LENGTH+x} ]; then echo "int(r'${VIASH_PAR_VDJ_R1_LENGTH//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'vdj_r2_length': $( if [ ! -z ${VIASH_PAR_VDJ_R2_LENGTH+x} ]; then echo "int(r'${VIASH_PAR_VDJ_R2_LENGTH//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'cell_multiplex_oligo_ids': $( if [ ! -z ${VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS+x} ]; then echo "r'${VIASH_PAR_CELL_MULTIPLEX_OLIGO_IDS//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'min_assignment_confidence': $( if [ ! -z ${VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE+x} ]; then echo "float(r'${VIASH_PAR_MIN_ASSIGNMENT_CONFIDENCE//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'cmo_set': $( if [ ! -z ${VIASH_PAR_CMO_SET+x} ]; then echo "r'${VIASH_PAR_CMO_SET//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'barcode_sample_assignment': $( if [ ! -z ${VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT+x} ]; then echo "r'${VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'probe_set': $( if [ ! -z ${VIASH_PAR_PROBE_SET+x} ]; then echo "r'${VIASH_PAR_PROBE_SET//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'filter_probes': $( if [ ! -z ${VIASH_PAR_FILTER_PROBES+x} ]; then echo "r'${VIASH_PAR_FILTER_PROBES//\'/\'\"\'\"r\'}'.lower() == 'true'"; else echo None; fi ),
  'probe_barcode_ids': $( if [ ! -z ${VIASH_PAR_PROBE_BARCODE_IDS+x} ]; then echo "r'${VIASH_PAR_PROBE_BARCODE_IDS//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'control_id': $( if [ ! -z ${VIASH_PAR_CONTROL_ID+x} ]; then echo "r'${VIASH_PAR_CONTROL_ID//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'mhc_allele': $( if [ ! -z ${VIASH_PAR_MHC_ALLELE+x} ]; then echo "r'${VIASH_PAR_MHC_ALLELE//\'/\'\"\'\"r\'}'.split(';')"; else echo None; fi ),
  'check_library_compatibility': $( if [ ! -z ${VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY+x} ]; then echo "r'${VIASH_PAR_CHECK_LIBRARY_COMPATIBILITY//\'/\'\"\'\"r\'}'.lower() == 'true'"; else echo None; fi ),
  'output': $( if [ ! -z ${VIASH_PAR_OUTPUT+x} ]; then echo "r'${VIASH_PAR_OUTPUT//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'dryrun': $( if [ ! -z ${VIASH_PAR_DRYRUN+x} ]; then echo "r'${VIASH_PAR_DRYRUN//\'/\'\"\'\"r\'}'.lower() == 'true'"; else echo None; fi )
}
meta = {
  'name': $( if [ ! -z ${VIASH_META_NAME+x} ]; then echo "r'${VIASH_META_NAME//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'functionality_name': $( if [ ! -z ${VIASH_META_FUNCTIONALITY_NAME+x} ]; then echo "r'${VIASH_META_FUNCTIONALITY_NAME//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'resources_dir': $( if [ ! -z ${VIASH_META_RESOURCES_DIR+x} ]; then echo "r'${VIASH_META_RESOURCES_DIR//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'executable': $( if [ ! -z ${VIASH_META_EXECUTABLE+x} ]; then echo "r'${VIASH_META_EXECUTABLE//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'config': $( if [ ! -z ${VIASH_META_CONFIG+x} ]; then echo "r'${VIASH_META_CONFIG//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'temp_dir': $( if [ ! -z ${VIASH_META_TEMP_DIR+x} ]; then echo "r'${VIASH_META_TEMP_DIR//\'/\'\"\'\"r\'}'"; else echo None; fi ),
  'cpus': $( if [ ! -z ${VIASH_META_CPUS+x} ]; then echo "int(r'${VIASH_META_CPUS//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_b': $( if [ ! -z ${VIASH_META_MEMORY_B+x} ]; then echo "int(r'${VIASH_META_MEMORY_B//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_kb': $( if [ ! -z ${VIASH_META_MEMORY_KB+x} ]; then echo "int(r'${VIASH_META_MEMORY_KB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_mb': $( if [ ! -z ${VIASH_META_MEMORY_MB+x} ]; then echo "int(r'${VIASH_META_MEMORY_MB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_gb': $( if [ ! -z ${VIASH_META_MEMORY_GB+x} ]; then echo "int(r'${VIASH_META_MEMORY_GB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_tb': $( if [ ! -z ${VIASH_META_MEMORY_TB+x} ]; then echo "int(r'${VIASH_META_MEMORY_TB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_pb': $( if [ ! -z ${VIASH_META_MEMORY_PB+x} ]; then echo "int(r'${VIASH_META_MEMORY_PB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_kib': $( if [ ! -z ${VIASH_META_MEMORY_KIB+x} ]; then echo "int(r'${VIASH_META_MEMORY_KIB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_mib': $( if [ ! -z ${VIASH_META_MEMORY_MIB+x} ]; then echo "int(r'${VIASH_META_MEMORY_MIB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_gib': $( if [ ! -z ${VIASH_META_MEMORY_GIB+x} ]; then echo "int(r'${VIASH_META_MEMORY_GIB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_tib': $( if [ ! -z ${VIASH_META_MEMORY_TIB+x} ]; then echo "int(r'${VIASH_META_MEMORY_TIB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
  'memory_pib': $( if [ ! -z ${VIASH_META_MEMORY_PIB+x} ]; then echo "int(r'${VIASH_META_MEMORY_PIB//\'/\'\"\'\"r\'}')"; else echo None; fi )
}
dep = {
  
}

## VIASH END

sys.path.append(meta["resources_dir"])
# START TEMPORARY WORKAROUND setup_logger
# reason: resources aren't available when using Nextflow fusion
# from setup_logger import setup_logger
def setup_logger():
    import logging
    from sys import stdout

    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    console_handler = logging.StreamHandler(stdout)
    logFormatter = logging.Formatter("%(asctime)s %(levelname)-8s %(message)s")
    console_handler.setFormatter(logFormatter)
    logger.addHandler(console_handler)

    return logger
# END TEMPORARY WORKAROUND setup_logger
logger = setup_logger()

# Tested with cellranger 7.0:
# - omitting the lane number is allowed (e.g. \`_L001\`)
# - lane number should be omitted across all files if omitted in one
# - replacing \`.fastq.\` for \`.fq.\` is NOT allowed
# - omitting \`.gz\` is allowed

fastq_regex = r'^([A-Za-z0-9\\-_\\.]+)_S(\\d+)_(L(\\d+)_)?[RI](\\d+)_(\\d+)\\.fastq(\\.gz)?\$'
# assert re.match(fastq_regex, "5k_human_GEX_1_subset_S1_L001_R1_001.fastq.gz") is not None
# assert re.match(fastq_regex, "5k_human_GEX_1_subset_S1_R1_001.fastq") is not None
# assert re.match(fastq_regex, "5k_human_GEX_1_subset_S1_R1_001.fastq.gz.txt") is None

# Invert some parameters. Keep the original ones in the config for compatibility
inverted_params = {
    "gex_no_secondary_analysis": "gex_secondary_analysis",
}
for inverted_param, param in inverted_params.items():
    par[inverted_param] = not par[param] if par[param] is not None else None
    del par[param]

GEX_CONFIG_KEYS = {
    "gex_reference": "reference",
    "gex_expect_cells": "expect-cells",
    "gex_force_cells": "force-cells",
    "gex_chemistry": "chemistry",
    "gex_no_secondary_analysis": "no-secondary",
    "gex_generate_bam": "create-bam",
    "gex_include_introns": "include-introns",
    "min_assignment_confidence": "min-assignment-confidence",
    "check_library_compatibility": "check-library-compatibility",
    "barcode_sample_assignment": "barcode-sample-assignment",
    "cmo_set": "cmo-set",
    "probe_set": "probe-set",
    "filter_probes": "filter-probes",
    "gex_r1_length": "r1-length",
    "gex_r2_length": "r2-length",
}

FEATURE_CONFIG_KEYS = {
    "feature_reference": "reference",
    "feature_r1_length": "r1-length",
    "feature_r2_length": "r2-length",
    "min_crispr_umi": "min-crispr-umi",
}

VDJ_CONFIG_KEYS = {"vdj_reference": "reference",
                   "vdj_inner_enrichment_primers": "inner-enrichment-primers",
                   "vdj_r1_length": "r1-length",
                   "vdj_r2_length": "r2-length",
                  }


ANTIGEN_SPECIFICITY_CONFIG_KEYS = {
    "control_id": "control_id",
    "mhc_allele": "mhc_allele",
}


REFERENCE_SECTIONS = {
    "gene-expression": (GEX_CONFIG_KEYS, "index"),
    "feature": (FEATURE_CONFIG_KEYS, "index"),
    "vdj": (VDJ_CONFIG_KEYS, "index"),
    "antigen-specificity": (ANTIGEN_SPECIFICITY_CONFIG_KEYS, "columns"),
}

LIBRARY_CONFIG_KEYS = {'library_id': 'fastq_id',
                       'library_type': 'feature_types',
                       'library_subsample': 'subsample_rate',
                       'library_lanes': 'lanes',
                       'library_chemistry': 'chemistry',
                       }


SAMPLE_PARAMS_CONFIG_KEYS = {'sample_ids': 'sample_id',
                             'cell_multiplex_oligo_ids': 'cmo_ids',
                             'sample_description': 'description',
                             'probe_barcode_ids': 'probe_barcode_ids',
                             'sample_expect_cells': 'expect_cells',
                             'sample_force_cells': 'force_cells'}


# These are derived from the dictionaries above
REFERENCES = tuple(reference_param for reference_param, cellranger_param
                   in chain(GEX_CONFIG_KEYS.items(), FEATURE_CONFIG_KEYS.items(), VDJ_CONFIG_KEYS.items())
                   if cellranger_param == "reference")
LIBRARY_PARAMS = tuple(LIBRARY_CONFIG_KEYS.keys())
SAMPLE_PARAMS = tuple(SAMPLE_PARAMS_CONFIG_KEYS.keys())
HELPER_INPUT = {
    'gex_input': 'Gene Expression',
    'abc_input': 'Antibody Capture',
    'cgc_input': 'CRISPR Guide Capture',
    'mux_input': 'Multiplexing Capture',
    'vdj_input': 'VDJ',
    'vdj_t_input': 'VDJ-T',
    'vdj_t_gd_input': 'VDJ-T-GD',
    'vdj_b_input': 'VDJ-B',
    'agc_input': 'Antigen Capture'
}


def infer_library_id_from_path(input_path: str) -> str:
    match = re.match(fastq_regex, input_path)
    assert match is not None, \\
        f"File name of '{input_path}' should match regex {fastq_regex}."
    return match.group(1)

def transform_helper_inputs(par: dict[str, Any]) -> dict[str, Any]:
    helper_input = {
        "input": [],
        "library_id": [],
        "library_type": []
    }
    for input_type, library_type in HELPER_INPUT.items():
        if par[input_type]:
            par[input_type] = resolve_input_directories_to_fastq_paths(par[input_type])

            library_ids = [
                infer_library_id_from_path(path.name) for path in par[input_type]
                ]

            library_id_dict = {}
            for fastq, library_id in zip(par[input_type], library_ids):
                library_id_dict.setdefault(library_id, []).append(fastq)

            for library_id, input in library_id_dict.items():
                helper_input["input"] += input
                helper_input["library_id"].append(library_id)
                helper_input["library_type"].append(library_type)

    assert len(helper_input["library_id"]) == len(set(helper_input["library_id"])), "File names passed to feature type-specific inputs must be unique"

    return helper_input

def lengths_gt1(dic: dict[str, Optional[list[Any]]]) -> dict[str, int]:
    return {key: len(li) for key, li in dic.items()
            if li is not None and isinstance(li, (list, tuple, set))}

def strip_margin(text: str) -> str:
    return re.sub('(\\n?)[ \\t]*\\|', '\\\\1', text)

def subset_dict(dictionary: dict[str, str],
                keys: Union[dict[str, str], list[str]]) -> dict[str, str]:
    if isinstance(keys, (list, tuple)):
        keys = {key: key for key in keys}
    return {dest_key: dictionary[orig_key]
            for orig_key, dest_key in keys.items()
            if dictionary[orig_key] is not None}

def check_subset_dict_equal_length(group_name: str,
                                   dictionary: dict[str, list[str]]) -> None:
    lens = lengths_gt1(dictionary)
    assert len(set(lens.values())) <= 1, f"The number of values passed to {group_name} "\\
                                         f"arguments must be 0, 1 or all the same. Offenders: {lens}"

def resolve_input_directories_to_fastq_paths(input_paths: list[str]) -> list[Path]:

    input_paths = [Path(fastq) for fastq in input_paths]
    if len(input_paths) == 1 and input_paths[0].is_dir():
        logger.info("Detected a directory in input paths, "
                    "traversing to see if we can detect any FASTQ files.")
        input_paths = [input_path for input_path in input_paths[0].rglob('*')
                        if re.match(fastq_regex, input_path.name) ]

    # check input fastq files
    for input_path in input_paths:
        assert re.match(fastq_regex, input_path.name) is not None, \\
            f"File name of --input '{input_path}' should match regex {fastq_regex}."

    return input_paths

def make_paths_absolute(par: dict[str, Any], config: Path | str):
    with open(config, 'r', encoding="utf-8") as open_viash_config:
        config = yaml.safe_load(open_viash_config)

    arguments = {
        arg["name"].removeprefix("-").removeprefix("-"): arg
        for group in config["argument_groups"]
        for arg in group["arguments"]
    }
    for arg_name, arg in arguments.items():
        if not par.get(arg_name) or arg["type"] != "file":
            continue
        par_value, is_multiple = par[arg_name], arg["multiple"]
        assert is_multiple in (True, False)
        def make_path_absolute(file: str | Path) -> Path:
            logger.info('Making path %s absolute', file)
            return Path(file).resolve()
        
        new_arg = [make_path_absolute(file) for file in par_value] if is_multiple else make_path_absolute(par_value)
        par[arg_name] = new_arg
    return par

def handle_integers_not_set(par: dict[str, Any], viash_config: Path | str) -> str:
    """
    Allow to use \`-1\` to define a 'not set' value for arguments of \`type: integer\` with \`multiple: true\`.
    """
    with open(viash_config, 'r', encoding="utf-8") as open_viash_config:
        config = yaml.safe_load(open_viash_config)

    arguments = {
        arg["name"].removeprefix("-").removeprefix("-"): arg
        for group in config["argument_groups"]
        for arg in group["arguments"]
    }
    for arg_name, arg in arguments.items():
        if not par.get(arg_name) or arg["type"] != "integer":
            continue
        par_value, is_multiple = par[arg_name], arg["multiple"]
        assert is_multiple in (True, False)

        if not is_multiple:
            continue

        def replace_notset_values(integer_value: int) -> int | None:
            return None if integer_value == -1 else integer_value
        
        # Use an extension array to handle "None" values, otherwise int + NA
        # values would be converted to a "float" dtype
        new_arg = pd.array([replace_notset_values(value) for value in par_value], dtype="Int64")
        par[arg_name] = new_arg
    return par

def process_params(par: dict[str, Any], viash_config: Path | str) -> str:

    if par["input"]:
        assert len(par["library_type"]) > 0, "--library_type must be defined when passing input to --input"
        assert len(par["library_id"]) > 0, "--library_id must be defined when passing input to --input"

        # if par["input"] is a directory, look for fastq files
        par["input"] = resolve_input_directories_to_fastq_paths(par["input"])

    # add helper input
    helper_input = transform_helper_inputs(par)
    for key in ["input", "library_id", "library_type"]:
      par[key] = (par[key] if par[key] else []) + helper_input[key]

      assert len(par[key]) > 0, f"Either --{key} or feature type-specific input (e.g. --gex_input, --abc_input, ...) must be defined"

    # check lengths of libraries metadata
    library_dict = subset_dict(par, LIBRARY_PARAMS)
    check_subset_dict_equal_length("Library", library_dict)

    samples_dict = subset_dict(par, SAMPLE_PARAMS)
    check_subset_dict_equal_length("Samples", samples_dict)

    # Allow using -1 to indicate unset integers for arguments
    # that accept multiple integers.
    par = handle_integers_not_set(par, viash_config)

    # use absolute paths
    return make_paths_absolute(par, viash_config)


def generate_csv_category(name: str, args: dict[str, str], orient: str) -> list[str]:
    assert orient in ("index", "columns")
    if not args:
        return []
    title = [ f'[{name}]' ]
    # Which index to include in csv section is based on orientation
    to_csv_args = {"index": (orient=="index"), "header": (orient=="columns")}
    values = [pd.DataFrame.from_dict(args, orient=orient).to_csv(**to_csv_args).strip()]
    return title + values + [""]


def generate_config(par: dict[str, Any], fastq_dir: str) -> str:
    content_list = []
    par["fastqs"] = fastq_dir
    libraries = dict(LIBRARY_CONFIG_KEYS, **{"fastqs": "fastqs"})
    #TODO: use the union (|) operator when python is updated to 3.9
    all_sections = REFERENCE_SECTIONS | {"libraries": (libraries, "columns"), 
                                         "samples": (SAMPLE_PARAMS_CONFIG_KEYS, "columns")}
    for section_name, (section_params, orientation) in all_sections.items():
        reference_pars = subset_dict(par, section_params)
        content_list += generate_csv_category(section_name, reference_pars, orient=orientation)

    return '\\n'.join(content_list)

def main(par: dict[str, Any], meta: dict[str, Any]):
    logger.info("  Processing params")
    par = process_params(par, meta['config'])
    logger.info(par)

    # TODO: throw error or else Cell Ranger will
    with tempfile.TemporaryDirectory(prefix="cellranger_multi-",
                                     dir=meta["temp_dir"]) as temp_dir:
        temp_dir_path = Path(temp_dir)
        for reference_par_name in REFERENCES:
            reference = par[reference_par_name]
            logger.info('Looking at %s to check if it needs decompressing', reference)
            if reference and Path(reference).is_file() and tarfile.is_tarfile(reference):
                extaction_dir_name = Path(reference.stem).stem # Remove two extensions (if they exist)
                unpacked_directory = temp_dir_path / extaction_dir_name
                logger.info('Extracting %s to %s', reference, unpacked_directory)

                with tarfile.open(reference, 'r') as open_tar:
                    members = open_tar.getmembers()
                    root_dirs = [member for member in members if member.isdir()
                                 and member.name != '.' and '/' not in member.name]
                    # if there is only one root_dir (and there are files in that directory)
                    # strip that directory name from the destination folder
                    if len(root_dirs) == 1:
                        for mem in members:
                            mem.path = Path(*Path(mem.path).parts[1:])
                    members_to_move = [mem for mem in members if mem.path != Path('.')]
                    open_tar.extractall(unpacked_directory, members=members_to_move)
                par[reference_par_name] = unpacked_directory

        # Creating symlinks of fastq files to tempdir
        input_symlinks_dir = temp_dir_path / "input_symlinks"
        input_symlinks_dir.mkdir()
        for fastq in par['input']:
            destination = input_symlinks_dir / fastq.name
            destination.symlink_to(fastq)

        logger.info("  Creating config file")
        config_content = generate_config(par, input_symlinks_dir)

        logger.info("  Creating Cell Ranger argument")
        temp_id="run"
        proc_pars=["--disable-ui", "--id", temp_id]

        command_line_parameters = {
            "--localcores": meta['cpus'],
            "--localmem": int(meta['memory_gb']) - 2 if meta['memory_gb'] else None,
        }
        for param, param_value in command_line_parameters.items():
            if param_value:
                proc_pars.append(f"{param}={param_value}")

        ## Run pipeline
        if par["dryrun"]:
            par['output'].mkdir(parents=True, exist_ok=True)

            # write config file
            config_file = par['output'] / "config.csv"
            with open(config_file, "w") as f:
                f.write(config_content)
            proc_pars.append(f"--csv={config_file}")

            # display command that would've been used
            cmd = ["cellranger multi"] + proc_pars + ["--csv=config.csv"]
            logger.info("> " + ' '.join(cmd))
        else:
            # write config file to execution directory
            config_file = temp_dir_path / "config.csv"
            with open(config_file, "w") as f:
                f.write(config_content)
            proc_pars.append(f"--csv={config_file}")

            # Already copy config file to output directory
            par['output'].mkdir(parents=True, exist_ok=True)
            with (par['output'] / "config.csv").open('w') as open_config:
                open_config.write(config_content)

            # run process
            cmd = ["cellranger", "multi"] + proc_pars
            logger.info("> " + ' '.join(cmd))
            process_output = subprocess.run(
                cmd,
                cwd=temp_dir,
                check=False,
                capture_output=True
            )

            with (par["output"] / "cellranger_multi.log").open('w') as open_log:
                open_log.write(process_output.stdout.decode('utf-8'))
            try:
                process_output.check_returncode()
            except subprocess.CalledProcessError as e:
                logger.error(e.output.decode('utf-8'))
                print(e.output.decode('utf-8'), flush=True)
                raise e

            # look for output dir file
            tmp_output_dir = temp_dir_path / temp_id / "outs"
            expected_files = {
                Path("multi"): Path.is_dir,
                Path("per_sample_outs"): Path.is_dir,
                Path("config.csv"): Path.is_file,
            }
            for file_path, type_func in expected_files.items():
                output_path = tmp_output_dir / file_path
                if not type_func(output_path):
                    raise ValueError(f"Could not find expected '{output_path}'")

            for output_path in tmp_output_dir.rglob('*'):
                if output_path.name != "config.csv": # Already created
                    shutil.move(str(output_path), par['output'])

if __name__ == "__main__":
    main(par, meta)
VIASHMAIN
python -B "\$tempscript" &
wait "\$!"

VIASHEOF


if [[ "$VIASH_ENGINE_TYPE" == "docker" ]]; then
  # strip viash automount from file paths
  
  if [ ! -z "$VIASH_PAR_INPUT" ]; then
    unset VIASH_TEST_INPUT
    IFS=';'
    for var in $VIASH_PAR_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_INPUT" ]; then
      VIASH_TEST_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_INPUT="$VIASH_TEST_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_INPUT="$VIASH_TEST_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_GEX_INPUT" ]; then
    unset VIASH_TEST_GEX_INPUT
    IFS=';'
    for var in $VIASH_PAR_GEX_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_GEX_INPUT" ]; then
      VIASH_TEST_GEX_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_GEX_INPUT="$VIASH_TEST_GEX_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_GEX_INPUT="$VIASH_TEST_GEX_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_ABC_INPUT" ]; then
    unset VIASH_TEST_ABC_INPUT
    IFS=';'
    for var in $VIASH_PAR_ABC_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_ABC_INPUT" ]; then
      VIASH_TEST_ABC_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_ABC_INPUT="$VIASH_TEST_ABC_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_ABC_INPUT="$VIASH_TEST_ABC_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_CGC_INPUT" ]; then
    unset VIASH_TEST_CGC_INPUT
    IFS=';'
    for var in $VIASH_PAR_CGC_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_CGC_INPUT" ]; then
      VIASH_TEST_CGC_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_CGC_INPUT="$VIASH_TEST_CGC_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_CGC_INPUT="$VIASH_TEST_CGC_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_MUX_INPUT" ]; then
    unset VIASH_TEST_MUX_INPUT
    IFS=';'
    for var in $VIASH_PAR_MUX_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_MUX_INPUT" ]; then
      VIASH_TEST_MUX_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_MUX_INPUT="$VIASH_TEST_MUX_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_MUX_INPUT="$VIASH_TEST_MUX_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_VDJ_INPUT" ]; then
    unset VIASH_TEST_VDJ_INPUT
    IFS=';'
    for var in $VIASH_PAR_VDJ_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_VDJ_INPUT" ]; then
      VIASH_TEST_VDJ_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_VDJ_INPUT="$VIASH_TEST_VDJ_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_VDJ_INPUT="$VIASH_TEST_VDJ_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_VDJ_T_INPUT" ]; then
    unset VIASH_TEST_VDJ_T_INPUT
    IFS=';'
    for var in $VIASH_PAR_VDJ_T_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_VDJ_T_INPUT" ]; then
      VIASH_TEST_VDJ_T_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_VDJ_T_INPUT="$VIASH_TEST_VDJ_T_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_VDJ_T_INPUT="$VIASH_TEST_VDJ_T_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_VDJ_T_GD_INPUT" ]; then
    unset VIASH_TEST_VDJ_T_GD_INPUT
    IFS=';'
    for var in $VIASH_PAR_VDJ_T_GD_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_VDJ_T_GD_INPUT" ]; then
      VIASH_TEST_VDJ_T_GD_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_VDJ_T_GD_INPUT="$VIASH_TEST_VDJ_T_GD_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_VDJ_T_GD_INPUT="$VIASH_TEST_VDJ_T_GD_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_VDJ_B_INPUT" ]; then
    unset VIASH_TEST_VDJ_B_INPUT
    IFS=';'
    for var in $VIASH_PAR_VDJ_B_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_VDJ_B_INPUT" ]; then
      VIASH_TEST_VDJ_B_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_VDJ_B_INPUT="$VIASH_TEST_VDJ_B_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_VDJ_B_INPUT="$VIASH_TEST_VDJ_B_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_AGC_INPUT" ]; then
    unset VIASH_TEST_AGC_INPUT
    IFS=';'
    for var in $VIASH_PAR_AGC_INPUT; do
      unset IFS
      if [ -z "$VIASH_TEST_AGC_INPUT" ]; then
      VIASH_TEST_AGC_INPUT="$(ViashDockerStripAutomount "$var")"
    else
      VIASH_TEST_AGC_INPUT="$VIASH_TEST_AGC_INPUT;""$(ViashDockerStripAutomount "$var")"
    fi
    done
    VIASH_PAR_AGC_INPUT="$VIASH_TEST_AGC_INPUT"
  fi
  if [ ! -z "$VIASH_PAR_FEATURE_REFERENCE" ]; then
    VIASH_PAR_FEATURE_REFERENCE=$(ViashDockerStripAutomount "$VIASH_PAR_FEATURE_REFERENCE")
  fi
  if [ ! -z "$VIASH_PAR_GEX_REFERENCE" ]; then
    VIASH_PAR_GEX_REFERENCE=$(ViashDockerStripAutomount "$VIASH_PAR_GEX_REFERENCE")
  fi
  if [ ! -z "$VIASH_PAR_VDJ_REFERENCE" ]; then
    VIASH_PAR_VDJ_REFERENCE=$(ViashDockerStripAutomount "$VIASH_PAR_VDJ_REFERENCE")
  fi
  if [ ! -z "$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS" ]; then
    VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS=$(ViashDockerStripAutomount "$VIASH_PAR_VDJ_INNER_ENRICHMENT_PRIMERS")
  fi
  if [ ! -z "$VIASH_PAR_CMO_SET" ]; then
    VIASH_PAR_CMO_SET=$(ViashDockerStripAutomount "$VIASH_PAR_CMO_SET")
  fi
  if [ ! -z "$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT" ]; then
    VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT=$(ViashDockerStripAutomount "$VIASH_PAR_BARCODE_SAMPLE_ASSIGNMENT")
  fi
  if [ ! -z "$VIASH_PAR_PROBE_SET" ]; then
    VIASH_PAR_PROBE_SET=$(ViashDockerStripAutomount "$VIASH_PAR_PROBE_SET")
  fi
  if [ ! -z "$VIASH_PAR_OUTPUT" ]; then
    VIASH_PAR_OUTPUT=$(ViashDockerStripAutomount "$VIASH_PAR_OUTPUT")
  fi
  if [ ! -z "$VIASH_META_RESOURCES_DIR" ]; then
    VIASH_META_RESOURCES_DIR=$(ViashDockerStripAutomount "$VIASH_META_RESOURCES_DIR")
  fi
  if [ ! -z "$VIASH_META_EXECUTABLE" ]; then
    VIASH_META_EXECUTABLE=$(ViashDockerStripAutomount "$VIASH_META_EXECUTABLE")
  fi
  if [ ! -z "$VIASH_META_CONFIG" ]; then
    VIASH_META_CONFIG=$(ViashDockerStripAutomount "$VIASH_META_CONFIG")
  fi
  if [ ! -z "$VIASH_META_TEMP_DIR" ]; then
    VIASH_META_TEMP_DIR=$(ViashDockerStripAutomount "$VIASH_META_TEMP_DIR")
  fi
fi


# check whether required files exist
if [ ! -z "$VIASH_PAR_OUTPUT" ] && [ ! -e "$VIASH_PAR_OUTPUT" ]; then
  ViashError "Output file '$VIASH_PAR_OUTPUT' does not exist."
  exit 1
fi


exit 0
