예제 #1
0
def main():

    #setup argparser to display help if no arguments
    class MyParser(argparse.ArgumentParser):
        def error(self, message):
            self.print_help()
            sys.stderr.write('\nerror: %s\n' % message)
            sys.exit(1)

    docker_config_path = os.path.abspath(
        os.path.dirname(__file__) + '/' + 'core/docker_config.json')

    parser = MyParser(
        description=f"StaPH-B ToolKit Programs v{autoupdate.version}",
        usage=
        "staphb-tk [optional arguments] <application> [application arguments]",
        add_help=True)
    subparsers = parser.add_subparsers(title='custom toolkit applications',
                                       metavar='',
                                       dest="subparser_name",
                                       parser_class=MyParser)
    parser.add_argument(
        "--docker_config",
        "-c",
        default=docker_config_path,
        metavar="<path>",
        help=
        "Configuration file for container images and tags; if none provided, default container versions will be used."
    )
    parser.add_argument(
        "--get_docker_config",
        default=False,
        action="store_true",
        help="Get the default docker container configureation file.")
    parser.add_argument(
        "--list",
        "-l",
        default=False,
        action="store_true",
        help="List all of the software available in the toolkit.")
    parser.add_argument("--update",
                        default=False,
                        action="store_true",
                        help="Check for and install a ToolKit update.")
    parser.add_argument(
        "--auto_update",
        default=False,
        action="store_true",
        help="Toggle automatic ToolKit updates. Default is off.")
    ###custom apps
    ## Mash Species
    parser_mash_species = subparsers.add_parser(
        'mash_species',
        help=
        'MASH_species uses a pre-sketched RefSeq database to identify the isolate species from paired-end read data.',
        usage="sb_mash_species <input> [options]")
    parser_mash_species.add_argument(
        "input",
        type=str,
        nargs='?',
        help="path to dir containing paire-end read files")
    parser_mash_species.add_argument("-o",
                                     metavar='path',
                                     default="",
                                     type=str,
                                     help="Path for output directory",
                                     required=False)

    #parser for applications
    #-----------------------------------------
    parser_abricate = subparsers.add_parser('abricate', add_help=False)
    parser_augur = subparsers.add_parser('augur', add_help=False)
    parser_bbtools = subparsers.add_parser('bbtools', add_help=False)
    parser_bwa = subparsers.add_parser('bwa', add_help=False)
    parser_canuracon = subparsers.add_parser('canu-racon', add_help=False)
    parser_centroid = subparsers.add_parser('centroid', add_help=False)
    parser_cfsansnp = subparsers.add_parser('cfsan-snp', add_help=False)
    parser_circlator = subparsers.add_parser('circlator', add_help=False)
    parser_clustalo = subparsers.add_parser('clustalo', add_help=False)
    parser_emmtypingtool = subparsers.add_parser('emm-typing-tool',
                                                 add_help=False)
    parser_fastani = subparsers.add_parser('fastani', add_help=False)
    parser_fastqc = subparsers.add_parser('fastqc', add_help=False)
    parser_fasttree = subparsers.add_parser('fasttree', add_help=False)
    parser_filtong = subparsers.add_parser('filtlong', add_help=False)
    parser_flye = subparsers.add_parser('flye', add_help=False)
    parser_iqtree = subparsers.add_parser('iqtree', add_help=False)
    parser_ivar = subparsers.add_parser('ivar', add_help=False)
    parser_ivar_SC2 = subparsers.add_parser('ivar-SC2', add_help=False)
    parser_kma = subparsers.add_parser('kma', add_help=False)
    parser_kraken = subparsers.add_parser('kraken', add_help=False)
    parser_krakenbuild = subparsers.add_parser('kraken-build', add_help=False)
    parser_kraken2 = subparsers.add_parser('kraken2', add_help=False)
    parser_kraken2build = subparsers.add_parser('kraken2-build',
                                                add_help=False)
    parser_ksnp3 = subparsers.add_parser('ksnp3', add_help=False)
    parser_legsta = subparsers.add_parser('legsta', add_help=False)
    parser_lyveset = subparsers.add_parser('lyveset', add_help=False)
    parser_mafft = subparsers.add_parser('mafft', add_help=False)
    parser_mash = subparsers.add_parser('mash', add_help=False)
    parser_mashtree = subparsers.add_parser('mashtree', add_help=False)
    parser_medaka = subparsers.add_parser('medaka', add_help=False)
    parser_minimap2 = subparsers.add_parser('minimap2', add_help=False)
    parser_mlst = subparsers.add_parser('mlst', add_help=False)
    parser_mugsy = subparsers.add_parser('mugsy', add_help=False)
    parser_multiqc = subparsers.add_parser('multiqc', add_help=False)
    parser_nanoplot = subparsers.add_parser('nanoplot', add_help=False)
    parser_ncbiamrfinder_plus = subparsers.add_parser('ncbi-amrfinder-plus',
                                                      add_help=False)
    parser_orthofinder = subparsers.add_parser('orthofinder', add_help=False)
    parser_pangolin = subparsers.add_parser('pangolin', add_help=False)
    parser_pilon = subparsers.add_parser('pilon', add_help=False)
    parser_plasmidseeker = subparsers.add_parser('plasmidseeker',
                                                 add_help=False)
    parser_prokka = subparsers.add_parser('prokka', add_help=False)
    parser_quast = subparsers.add_parser('quast', add_help=False)
    parser_rasusa = subparsers.add_parser('rasusa', add_help=False)
    parser_raxml = subparsers.add_parser('raxml', add_help=False)
    parser_roary = subparsers.add_parser('roary', add_help=False)
    parser_salmid = subparsers.add_parser('salmid', add_help=False)
    parser_samtools = subparsers.add_parser('samtools', add_help=False)
    parser_seqsero = subparsers.add_parser('seqsero', add_help=False)
    parser_seqsero2 = subparsers.add_parser('seqsero2', add_help=False)
    parser_seqyclean = subparsers.add_parser('seqyclean', add_help=False)
    parser_seroba = subparsers.add_parser('seroba', add_help=False)
    parser_serotypefinder = subparsers.add_parser('serotypefinder',
                                                  add_help=False)
    parser_shovill = subparsers.add_parser('shovill', add_help=False)
    parser_sistr = subparsers.add_parser('sistr', add_help=False)
    parser_skesa = subparsers.add_parser('skesa', add_help=False)
    parser_snippy = subparsers.add_parser('snippy', add_help=False)
    parser_snpdists = subparsers.add_parser('snp-dists', add_help=False)
    parser_snpsites = subparsers.add_parser('snp-sites', add_help=False)
    parser_spades = subparsers.add_parser('spades', add_help=False)
    parser_sratoolkit = subparsers.add_parser('sra-toolkit', add_help=False)
    parser_staramr = subparsers.add_parser('staramr', add_help=False)
    parser_tiptoft = subparsers.add_parser('tiptoft', add_help=False)
    parser_trimmomatic = subparsers.add_parser('trimmomatic', add_help=False)
    parser_unicycler = subparsers.add_parser('unicycler', add_help=False)
    parser_wtdbg2 = subparsers.add_parser('wtdbg2', add_help=False)

    #-----------------------------------------

    def print_prog_list():
        print("Available programs:")
        header = ["Command", "Description", "-------", "-----------"]
        print(f"{header[0]:<25}{header[1]:^10}")
        print(f"{header[2]:<25}{header[3]:^10}")
        for key in progs:
            print(f"{key:<25}{progs[key]:^10}")
        return

    #handle the arguments and perform automatic path replacement
    parser_args = parser.parse_known_args()
    program = parser_args[0].subparser_name
    args = parser_args[1]

    #check for updates
    if parser_args[0].update:
        autoupdate.check_for_updates()
        sys.exit(0)

    if parser_args[0].auto_update:
        #get current status
        update_status = autoupdate.check_update_status()
        if update_status:
            autoupdate.toggle_updater(False)
        else:
            autoupdate.toggle_updater(True)

    if autoupdate.check_update_status():
        autoupdate.check_for_updates()

    #give user docker config if asked
    if parser_args[0].get_docker_config:
        cwd = os.getcwd()
        copy(
            docker_config_path,
            os.path.join(
                os.getcwd(),
                date.today().strftime("%y-%m-%d") + "_docker_config.json"))
        sys.exit(0)

    #display list of programs if needed
    if parser_args[0].list:
        print_prog_list()
        sys.exit(0)

    if program == None:
        parser.print_help()
        sys.exit(1)

    #Run autopathing
    arg_string, path_map = path_replacer(args, os.getcwd())

    # set the configuration file
    if parser_args[0].docker_config == "/core/docker_config.json":
        # use default
        config_file_path = os.path.abspath(
            os.path.dirname(
                os.path.realpath(__file__))) + parser_args[0].docker_config
    else:
        config_file_path = os.path.abspath(parser_args[0].docker_config)

    with open(config_file_path, 'r') as config_file:
        config = json.load(config_file)

    #Custom program specific execution code
    #-----------------------------------------
    if program == 'mash_species':
        #get output dir if supplied, if not set it to cwd
        output_dir = None
        if not parser_args[0].o:
            output_dir = os.getcwd()
        else:
            try:
                output_dir = os.path.abspath(parser_args[0].o)
            except (AttributeError, TypeError):
                print("Please enter a valid output path.")
                sys.exit(1)

        #get input path, if not supplied print help
        try:
            path = os.path.abspath(parser_args[0].input)
        except (AttributeError, TypeError) as e:
            parser_mash_species.print_help()
            print("Please enter a valid input path.")
            sys.exit(1)

        #create and run the mash species object
        mash_species_obj = MashSpecies(path=path, output_dir=output_dir)
        mash_species_obj.run()

    #Program specific execution code
    #-----------------------------------------
    if program == 'ivar-SC2':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = " "
        command = "ivar " + arg_string
        program_configuration = config["parameters"]["ivar-SC2"]

    if program == 'ivar':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = " "
        command = "ivar " + arg_string
        program_configuration = config["parameters"]["ivar"]

    if program == 'wtdbg2':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "wtdbg2 " + arg_string
        program_configuration = config["parameters"]["wtdbg2"]

    if program == 'trimmomatic':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "trimmomatic " + arg_string
        program_configuration = config["parameters"]["trimmomatic"]

    if program == 'tiptoft':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "tiptoft " + arg_string
        program_configuration = config["parameters"]["tiptoft"]

    if program == 'staramr':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "staramr " + arg_string
        program_configuration = config["parameters"]["staramr"]

    if program == 'sra-toolkit':
        if not re.search('[a-zA-Z]', arg_string):
            print(
                "SRA toolkit tool must be specified, e.g. staphb-tk sra-toolkit fasterq-dump, staphb-tk sra-toolkit sra-pileup, etc. \n\nMore info on SRA Toolkit usage at: https://trace.ncbi.nlm.nih.gov/Traces/sra/sra.cgi?view=toolkit_doc."
            )
            sys.exit()
        command = " " + arg_string
        program_configuration = config["parameters"]["sra-toolkit"]

    if program == 'snp-dists':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "snp-dists " + arg_string
        program_configuration = config["parameters"]["snp-dists"]

    if program == 'snp-sites':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "snp-sites " + arg_string
        program_configuration = config["parameters"]["snp-sites"]

    if program == 'snippy':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "snippy " + arg_string
        program_configuration = config["parameters"]["snippy"]

    if program == 'skesa':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "skesa " + arg_string
        program_configuration = config["parameters"]["skesa"]

    if program == 'sistr':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "sistr " + arg_string
        program_configuration = config["parameters"]["sistr"]

    if program == 'seroba':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "seroba " + arg_string
        program_configuration = config["parameters"]["seroba"]

    if program == 'seqsero2':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "SeqSero2_package.py " + arg_string
        program_configuration = config["parameters"]["seqsero2"]

    if program == 'salmid':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "SalmID.py " + arg_string
        program_configuration = config["parameters"]["salmid"]

    if program == 'rasusa':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "rasusa " + arg_string
        program_configuration = config["parameters"]["rasusa"]

    if program == 'plasmidseeker':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "plasmidseeker.pl " + arg_string
        program_configuration = config["parameters"]["plasmidseeker"]

    if program == 'pangolin':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "--help"
        command = "pangolin " + arg_string
        program_configuration = config["parameters"]["pangolin"]

    if program == 'pilon':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "--help"
        command = "pilon " + arg_string
        program_configuration = config["parameters"]["pilon"]

    if program == 'orthofinder':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "orthofinder " + arg_string
        program_configuration = config["parameters"]["orthofinder"]

    if program == 'ncbi-amrfinder-plus':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "--help"
        command = "amrfinder " + arg_string
        program_configuration = config["parameters"]["ncbi-amrfinder-plus"]

    if program == 'nanoplot':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "NanoPlot " + arg_string
        program_configuration = config["parameters"]["nanoplot"]

    if program == 'multiqc':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "multiqc " + arg_string
        program_configuration = config["parameters"]["multiqc"]

    if program == 'mugsy':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "mugsy " + arg_string
        program_configuration = config["parameters"]["mugsy"]

    if program == 'mlst':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "mlst " + arg_string
        program_configuration = config["parameters"]["mlst"]

    if program == 'medaka':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "medaka " + arg_string
        program_configuration = config["parameters"]["medaka"]

    if program == 'mashtree':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "mashtree " + arg_string
        program_configuration = config["parameters"]["mashtree"]

    if program == 'legsta':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "legsta " + arg_string
        program_configuration = config["parameters"]["legsta"]

    if program == 'ksnp3':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = ""
        command = "kSNP3 " + arg_string
        program_configuration = config["parameters"]["ksnp3"]

    if program == 'kraken2-build':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "kraken2-build " + arg_string
        program_configuration = config["parameters"]["kraken2"]

    if program == 'kraken2':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "kraken2 " + arg_string
        program_configuration = config["parameters"]["kraken2"]

    if program == 'kraken-build':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "kraken-build " + arg_string
        program_configuration = config["parameters"]["kraken"]

    if program == 'kraken':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "kraken " + arg_string
        program_configuration = config["parameters"]["kraken"]

    if program == 'kma':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "kma " + arg_string
        program_configuration = config["parameters"]["kma"]

    if program == 'flye':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "flye " + arg_string
        program_configuration = config["parameters"]["flye"]

    if program == 'filtlong':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "filtlong " + arg_string
        program_configuration = config["parameters"]["filtlong"]

    if program == 'fastqc':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "fastqc " + arg_string
        program_configuration = config["parameters"]["fastqc"]

    if program == 'fasttree':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "FastTree " + arg_string
        program_configuration = config["parameters"]["fasttree"]

    if program == 'fastani':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "fastANI " + arg_string
        program_configuration = config["parameters"]["fastani"]

    if program == 'emm-typing-tool':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "emm_typing.py " + arg_string
        program_configuration = config["parameters"]["emm-typing-tool"]

    if program == 'circlator':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "circlator " + arg_string
        program_configuration = config["parameters"]["circlator"]

    if program == 'cfsan-snp':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "cfsan_snp_pipeline " + arg_string
        program_configuration = config["parameters"]["cfsan-snp-pipeline"]

    if program == 'canu-racon':
        if not re.search('[a-zA-Z]', arg_string):
            print(
                "This is a bundled application that requires a specific commands to be used (i.e. staphb-tk canu-racon canu -h) please see the documentation for Canu, Minimap2 and Racon to use."
            )
            sys.exit()
        command = " " + arg_string
        program_configuration = config["parameters"]["canu-racon"]

    if program == 'bbtools':
        if not re.search('[a-zA-Z]', arg_string):
            print(
                "BBTools shell script must be specified, e.g. staphb-tk bbtools bbmap.sh, staphb-tk bbtools bbduk.sh, etc. \n\nMore info on BBTools at https://jgi.doe.gov/data-and-tools/bbtools/bb-tools-user-guide/."
            )
            sys.exit()
        command = " " + arg_string
        program_configuration = config["parameters"]["bbtools"]

    if program == 'raxml':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "raxmlHPC " + arg_string
        program_configuration = config["parameters"]["raxml"]

    if program == 'spades':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "spades.py " + arg_string
        program_configuration = config["parameters"]["spades"]

    if program == 'mash':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "mash " + arg_string
        program_configuration = config["parameters"]["mash"]

    if program == 'seqyclean':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "seqyclean " + arg_string
        program_configuration = config["parameters"]["seqyclean"]

    if program == 'shovill':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "shovill " + arg_string
        program_configuration = config["parameters"]["shovill"]

    if program == 'prokka':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "prokka " + arg_string
        program_configuration = config["parameters"]["prokka"]

    if program == 'clustalo':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "clustalo " + arg_string
        program_configuration = config["parameters"]["clustalo"]

    if program == 'abricate':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "abricate " + arg_string
        program_configuration = config["parameters"]["abricate"]

    if program == 'augur':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "augur " + arg_string
        program_configuration = config["parameters"]["augur"]

    if program == 'iqtree':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "iqtree " + arg_string
        program_configuration = config["parameters"]["iqtree"]

    if program == 'lyveset':
        if not re.search('[a-zA-Z]', arg_string):
            print(
                "Lyev-SET perl script must be specified, e.g. staphb-tk lyveset launch_set.pl, staphb-tk lyveset set_manage.pl, staphb-tk lyveset run_assembly_readMeterics.pl. \n\nMore info on Lyve-SET usage at: github.com/lskatz/lyve-SET."
            )
            sys.exit()
        command = "" + arg_string
        program_configuration = config["parameters"]["lyveset"]

    if program == 'quast':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "quast.py " + arg_string
        program_configuration = config["parameters"]["quast"]

    if program == 'roary':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "roary " + arg_string
        program_configuration = config["parameters"]["roary"]

    if program == 'seqsero':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "SeqSero.py " + arg_string
        program_configuration = config["parameters"]["seqsero"]

    if program == 'samtools':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = ""
        command = "samtools " + arg_string
        program_configuration = config["parameters"]["samtools"]

    if program == 'serotypefinder':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "serotypefinder.pl " + arg_string
        program_configuration = config["parameters"]["serotypefinder"]

    if program == 'bwa':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = ""
        command = "bwa " + arg_string
        program_configuration = config["parameters"]["bwa"]

    if program == 'minimap2':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "minimap2 " + arg_string
        program_configuration = config["parameters"]["minimap2"]

    if program == 'centroid':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "centroid.py " + arg_string
        program_configuration = config["parameters"]["centroid"]

    if program == 'unicycler':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "unicycler " + arg_string
        program_configuration = config["parameters"]["unicycler"]

    if program == 'mafft':
        if not re.search('[a-zA-Z]', arg_string):
            arg_string = "-h"
        command = "mafft " + arg_string
        program_configuration = config["parameters"]["mafft"]

    #Run the program
    #-----------------------------------------
    program_object = sb_prog.Run(command=command,
                                 path=path_map,
                                 image=program_configuration["image"],
                                 tag=program_configuration["tag"])
    program_object.run()
예제 #2
0
def main():
    #get nextflow executable
    lib_path = os.path.abspath(os.path.dirname(__file__) + '/' + 'lib')
    workflows_path = os.path.abspath(os.path.dirname(__file__) + '/' + 'workflows')
    nextflow_path = os.path.join(lib_path,'nextflow')

    #setup argparser to display help if no arguments
    class MyParser(argparse.ArgumentParser):
        def error(self, message):
            sys.stderr.write('error: %s\n' % message)
            self.print_help()
            sys.exit(2)

    parser = MyParser(description=f"StaPH-B ToolKit Workflows v{autoupdate.version}",usage=f"staphb-wf [optional arguments] <workflow> [workflow arguments]")
    parser.add_argument("--update",default=False,action="store_true",help="Check for and install a ToolKit update.")
    parser.add_argument("--auto_update",default=False,action="store_true",help="Toggle automatic ToolKit updates. Default is off.")
    subparsers = parser.add_subparsers(title='workflows',metavar='',dest="subparser_name")

    #parser for workflows
    #tredegar-----------------------------------------
    parser_tredegar = subparsers.add_parser('tredegar', help='Quality control of WGS read data.', add_help=False)
    parser_tredegar.add_argument('reads_path', type=str,help="path to the location of the reads in a fastq format",nargs='?', default=False)
    parser_tredegar.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"tredegar_results\".",default="tredegar_results")
    parser_tredegar.add_argument('--profile', type=str,choices=["docker","singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")
    parser_tredegar.add_argument('--config','-c', type=str,help="Nextflow custom configuration.")
    parser_tredegar.add_argument('--get_config',action="store_true",help="Get a Nextflow configuration template for tredegar.")
    parser_tredegar.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")

    #monroe-----------------------------------------
    parser_monroe = subparsers.add_parser('monroe', help='Consensus assembly for SARS-CoV-2 from ARTIC + Illumina protocols.', add_help=False)
    monroe_subparsers = parser_monroe.add_subparsers(title='monroe_commands',metavar='',dest='monroe_command')
    parser_monroe.add_argument('--get_config',type=str,choices=["pe_assembly", "se_assembly", "clearlabs_assembly", "ont_assembly", "cluster_analysis"],help="Get a Nextflow configuration template for the chosen workflow.")

    ##monroe_pe_assembly----------------------------
    subparser_monroe_pe_assembly = monroe_subparsers.add_parser('pe_assembly',help='Assembly SARS-CoV-2 genomes from paired-end read data generated from ARTIC amplicons', add_help=False)
    subparser_monroe_pe_assembly.add_argument('reads_path', type=str,help="path to the location of the reads in a fastq format")
    subparser_monroe_pe_assembly.add_argument('--primers', type=str, choices=["V1","V2","V3"], help="indicate which ARTIC primers were used (V1, V2, or V3)")
    subparser_monroe_pe_assembly.add_argument('--profile', type=str,choices=["docker", "singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")
    subparser_monroe_pe_assembly.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"monroe_results\".",default="monroe_results")
    subparser_monroe_pe_assembly.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")
    subparser_monroe_pe_assembly.add_argument('--config','-c', type=str,help="Nextflow custom configuration.")

    ##monroe_se_assembly----------------------------
    subparser_monroe_se_assembly = monroe_subparsers.add_parser('se_assembly',help='Assembly SARS-CoV-2 genomes from single-end read data generated from ARTIC amplicons', add_help=False)
    subparser_monroe_se_assembly.add_argument('reads_path', type=str,help="path to the location of the single-end reads in a fastq format")
    subparser_monroe_se_assembly.add_argument('--primers', type=str, choices=["V1","V2","V3"], help="indicate which ARTIC primers were used (V1, V2, or V3)")
    subparser_monroe_se_assembly.add_argument('--profile', type=str,choices=["docker", "singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")
    subparser_monroe_se_assembly.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"monroe_results\".",default="monroe_results")
    subparser_monroe_se_assembly.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")
    subparser_monroe_se_assembly.add_argument('--config','-c', type=str,help="Nextflow custom configuration.")

    ##monroe_clearlabs_assembly----------------------------
    subparser_monroe_clearlabs_assembly = monroe_subparsers.add_parser('clearlabs_assembly',help='Assembly SARS-CoV-2 genomes from Clear Labs ont read data', add_help=False)
    subparser_monroe_clearlabs_assembly.add_argument('reads_path', type=str,help="path to the location of the clearlabs reads in a fastq format")
    subparser_monroe_clearlabs_assembly.add_argument('--profile', type=str,choices=["docker", "singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")
    subparser_monroe_clearlabs_assembly.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"monroe_results\".",default="monroe_results")
    subparser_monroe_clearlabs_assembly.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")
    subparser_monroe_clearlabs_assembly.add_argument('--config','-c', type=str,help="Nextflow custom configuration.")

    ##monroe_ont_assembly----------------------------
    ##medaka nanopolish
    subparser_monroe_ont_assembly = monroe_subparsers.add_parser('ont_assembly',help='Assembly SARS-CoV-2 genomes from ONT read data generated from ARTIC amplicons', add_help=False)
    subparser_monroe_ont_assembly.add_argument('--fast5_path', type=str,help="path to the location of the reads in a fast5 format")
    subparser_monroe_ont_assembly.add_argument('--fastq_path', type=str,help="path to the location of the reads in a fastq format")
    subparser_monroe_ont_assembly.add_argument('--demultiplexed', default="false",action="store_const",const="true",help="flag if fastq files have already been demultiplexed")
    subparser_monroe_ont_assembly.add_argument('--medaka_model',default="r941_min_high_g360",help="medaka model to use for polishing, default: r941_min_fast_g303")
    subparser_monroe_ont_assembly.add_argument('--run_prefix', type=str,help="desired run prefix. Default \"artic_ncov19\"",default="artic_ncov19")
    subparser_monroe_ont_assembly.add_argument('--primers', type=str,choices=["V1", "V2", "V3"], help="indicate which ARTIC primers were used (V1, V2, or V3), default V3",default="V3")
    subparser_monroe_ont_assembly.add_argument('--config','-c', type=str,help="Nextflow custom configuration.")
    subparser_monroe_ont_assembly.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"monroe_results\".",default="monroe_results")
    subparser_monroe_ont_assembly.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")
    subparser_monroe_ont_assembly.add_argument('--profile', type=str,choices=["docker","singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")

    ##monroe_cluster_analysis-----------------------
    subparser_monroe_cluster_analysis = monroe_subparsers.add_parser('cluster_analysis',help='Perform multiple sequence alinmment of SC2 assemblies to generate a SNP-distance matrix & ML phylogenetic tree', add_help=False)
    subparser_monroe_cluster_analysis.add_argument('assemblies_path', type=str,help="path to the location of the SC2 assemblies in a fasta format",nargs='?', default=False)
    subparser_monroe_cluster_analysis.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"monroe_results\".",default="monroe_results")
    subparser_monroe_cluster_analysis.add_argument('--rtemplate','-rt', type=str, help="path to report rmarkdown", default=os.path.join(workflows_path,"monroe/report/report.Rmd"))
    subparser_monroe_cluster_analysis.add_argument('--profile', type=str,choices=["docker","singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")
    subparser_monroe_cluster_analysis.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")
    subparser_monroe_cluster_analysis.add_argument('--config','-c', type=str,help="Nextflow custom configuration.")
    subparser_monroe_cluster_analysis.add_argument('--get_rtemplate',action="store_true",help="Get a Rmd configuration template for report building.")

    #foushee-----------------------------------------
    parser_foushee = subparsers.add_parser('foushee', help='Reference-free SNP calling for Streptococcus pyogenes isolates.', add_help=False)
    parser_foushee.add_argument('reads_path', type=str,help="path to the directory of raw reads in the fastq format",nargs='?', default=False)
    parser_foushee.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"tredegar_results\".",default="foushee_results")
    parser_foushee.add_argument('--rtemplate','-rt', type=str, help="path to report rmarkdown", default=os.path.join(workflows_path,"foushee/report/report.Rmd"))
    parser_foushee.add_argument('--profile', type=str,choices=["docker","singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")
    parser_foushee.add_argument('--config','-c', type=str,help="Nextflow custom configuration.")
    parser_foushee.add_argument('--get_config',action="store_true",help="Get a Nextflow configuration template for foushee.")
    parser_foushee.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")

    #dryad-----------------------------------------
    parser_dryad = subparsers.add_parser('dryad', help='A comprehensive tree building program.', add_help=False)
    subparser_dryad = parser_dryad.add_subparsers(title='dryad apps',metavar='',dest='dryad_app')

    subparser_dryad_main = subparser_dryad.add_parser('main',help="dryad workflow")
    subparser_dryad_main.add_argument('reads_path', type=str,help="path to the directory of raw reads in the fastq format",nargs='?', default=False)
    subparser_dryad_main.add_argument('--output','-o',metavar="<output_path>",type=str,help="path to ouput directory, default \"dryad_results\"",default="dryad_results")
    subparser_dryad_main.add_argument('--core-genome','-cg',default=False, action="store_true", help="construct a core-genome tree")
    subparser_dryad_main.add_argument('--snp','-s',default=False, action="store_true", help="construct a SNP tree, requires a reference sequence in fasta format (-r)")
    subparser_dryad_main.add_argument('-r',metavar='<path>', type=str,help="reference sequence for SNP pipeline")
    subparser_dryad_main.add_argument('-ar',default=False, action="store_true", help="detect AR mechanisms")
    subparser_dryad_main.add_argument('--profile', type=str,choices=["docker", "singularity"],help="specify nextflow profile, dryad will try to use docker first, then singularity")
    subparser_dryad_main.add_argument('--config','-c', type=str,help="Nextflow custom configuration")
    subparser_dryad_main.add_argument('--get_config',action="store_true",help="get a Nextflow configuration template for dryad")
    subparser_dryad_main.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")
    subparser_dryad_main.add_argument('--report',action="store_true",help="generte a pdf report")

    subparser_dryad_report = subparser_dryad.add_parser('rebuild_report',help='rebuild a previously generated PDF report')
    subparser_dryad_report.add_argument('rmd',type=str,help="path to Rmarkdown file (.Rmd)",nargs='?', default=False)
    subparser_dryad_report.add_argument('snp_matrix',type=str,help="path to snp matrix",nargs='?', default=False)
    subparser_dryad_report.add_argument('cg_tree',type=str,help="path to core genome tree",nargs='?', default=False)
    subparser_dryad_report.add_argument('--output','-o',metavar="<output_path>",type=str,help="path to ouput directory, default \"./\"",default="./")
    subparser_dryad_report.add_argument('--ar',type=str,help="path to ar TSV file")
    subparser_dryad_report.add_argument('--profile', type=str,choices=["docker", "singularity"],help="specify nextflow profile, dryad_report will try to use docker first, then singularity")
    subparser_dryad_report.add_argument('--get_config',action="store_true",help="get a Nextflow configuration template for dryad")
    subparser_dryad_report.add_argument('--config','-c', type=str,help="Nextflow custom configuration")

    #hickory-----------------------------------------
    parser_hickory = subparsers.add_parser('hickory', help='Determining an ideal reference genome.', add_help=False)
    parser_hickory.add_argument('reads_path', type=str,help="path to the location of the reads in a fastq format",nargs='?', default=False)
    parser_hickory.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"hickory_results\".",default="hickory_results")
    parser_hickory.add_argument('--profile', type=str,choices=["docker","singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")
    parser_hickory.add_argument('--config','-c', type=str,help="Nextflow custom configuration.")
    parser_hickory.add_argument('--get_config',action="store_true",help="Get a Nextflow configuration template for hickory.")
    parser_hickory.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")

    #cutshaw-----------------------------------------
    parser_cutshaw = subparsers.add_parser('cutshaw', help='WGS competency assessment and instrument validation.', add_help=False)
    parser_cutshaw.add_argument('reads_path', type=str,help="path to the location of the reads in a fastq format",nargs='?', default=False)
    parser_cutshaw.add_argument('--isolate_key', type=str,help="path to the location of the isolation key file",nargs='?', default=False)
    parser_cutshaw.add_argument('--report_title', type=str,help="title of the cutshaw report (e.g. name of instrument or scientist being assessed); must enclose in quotes",default="Unnamed Assessment")
    parser_cutshaw.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"cutshaw_results\".",default="cutshaw_results")
    parser_cutshaw.add_argument('--profile', type=str,choices=["docker","singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")
    parser_cutshaw.add_argument('--config','-c', type=str,help="Nextflow custom configuration.")
    parser_cutshaw.add_argument('--get_config',action="store_true",help="Get a Nextflow configuration template for cutshaw.")
    parser_cutshaw.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")

    #cecret-----------------------------------------
    parser_cecret = subparsers.add_parser('cecret', help='Consensus fasta creation of amplicon-based SARS-CoV-2 Illumina sequencing.', add_help=False)
    parser_cecret.add_argument('reads_path', type=str,help="path to the location of reads in a fastq format",nargs='?', default=False)
    parser_cecret.add_argument('--reads_type',type=str,choices=["paired","single"],help="Specify either \"paired\"-end or \"single\"-end reads, default \"paired\".",default="paired")
    parser_cecret.add_argument('--annotation',action="store_true",help="Annotate fastas instead of creating fastas.")
    parser_cecret.add_argument('--output','-o',metavar="<output_path>",type=str,help="Path to ouput directory, default \"cecret\".",default="cecret")
    parser_cecret.add_argument('--profile',type=str,choices=["docker","singularity"],help="Nextflow profile. Default will try docker first, then singularity if the docker executable cannot be found.")
    parser_cecret.add_argument('--config','-c',type=str,help="Nextflow custom configuration.")
    parser_cecret.add_argument('--get_config',action="store_true",help="Get a Nextflow configuration template for cecret.")
    parser_cecret.add_argument('--resume', default="", action="store_const",const="-resume",help="resume a previous run")

    #----------------------------------------------
    args = parser.parse_args()

    #check if we are using docker or singularity
    if which('docker'):
        profile = '-profile docker'
    elif which('singularity'):
        profile = '-profile singularity'
    else:
        profile = ''

    #check for updates
    if args.update:
        autoupdate.check_for_updates()

    if args.auto_update:
        #get current status
        update_status = autoupdate.check_update_status()
        if update_status:
            autoupdate.toggle_updater(False)
        else:
            autoupdate.toggle_updater(True)

    if autoupdate.check_update_status():
        autoupdate.check_for_updates()

    if args.subparser_name == None:
        parser.print_help()
        sys.exit(1)
    program = args.subparser_name

    #current time for log files
    exec_time = datetime.now().strftime("%y_%m_%d_%H_%M_%S_")

    #################################
    #Program specific execution code#
    #################################

    #tredegar--------------------------------

    if program == 'tredegar':
        #tredegar path
        tredegar_path = os.path.join(workflows_path,"tredegar/")

        #give config to user if requested
        if args.get_config:
            config_path = os.path.join(tredegar_path,"configs/tredegar_config_template.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_tredegar.config")
            copyfile(config_path,dest_path)
            sys.exit()

        #check for reads_path
        if not args.reads_path:
            parser_tredegar.print_help()
            print("Please specify a path to a directory containing the raw reads.")
            sys.exit(1)


        #check for config or profile
        config = ""
        if args.config:
            config = "-C " + os.path.abspath(args.config)
            profile = ""
        elif args.profile:
            profile = f"-profile {args.profile}"
        elif not profile:
            print('Singularity or Docker is not installed or not in found in PATH.')
            sys.exit(1)

        #set work dir into local logs dir if profile not aws
        work = ""
        if profile and not args.config:
            work = f"-w {args.output}/logs/work"

        #build command
        command = nextflow_path
        command = command + f" {config} run {tredegar_path}/tredegar.nf {profile} {args.resume} --reads {args.reads_path} --outdir {args.output} -with-trace {args.output}/logs/{exec_time}Tredegar_trace.txt -with-report {args.output}/logs/{exec_time}Tredegar_execution_report.html {work}"
        print(command)

        #run command using nextflow in a subprocess
        print("Starting the Tredegar pipeline:")
        child = pexpect.spawn(command)
        child.interact()

    #monroe----------------------------------

    if program == 'monroe':
        #monroe path
        monroe_path = os.path.join(workflows_path,"monroe/")

        #give config to user if requested
        if args.get_config == "pe_assembly":
            config_path = os.path.join(monroe_path,"configs/pe_user_config.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_pe_assembly.config")
            copyfile(config_path,dest_path)
            sys.exit()
        elif args.get_config == "se_assembly":
            config_path = os.path.join(monroe_path,"configs/se_user_config.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_se_assembly.config")
            copyfile(config_path,dest_path)
            sys.exit()
        elif args.get_config == "clearlabs_assembly":
            config_path = os.path.join(monroe_path,"configs/clearlabs_user_config.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_clearlabs_assembly.config")
            copyfile(config_path,dest_path)
            sys.exit()
        elif args.get_config == "ont_assembly":
            config_path = os.path.join(monroe_path,"configs/ont_user_config.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_ont_assembly.config")
            copyfile(config_path,dest_path)
            sys.exit()
        elif args.get_config == "cluster_analysis":
            config_path = os.path.join(monroe_path,"configs/cluster_user_config.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_cluster_analysis.config")
            copyfile(config_path,dest_path)
            sys.exit()

        if args.monroe_command == None:
            parser_monroe.print_help()
            sys.exit(1)

        #check for config or profile
        config = ""
        if args.config:
            config = "-C " + os.path.abspath(args.config)
            profile = ""
        elif args.profile:
            profile = f"-profile {args.profile}"
        elif not profile:
            print('Singularity or Docker is not installed or not in found in PATH.')
            sys.exit(1)

        #set work dir into local logs dir if profile not aws
        work = ""
        if profile and not args.config:
            work = f"-w {args.output}/logs/work"

        if args.monroe_command == 'pe_assembly':
            #check for either standard ARTIC primer version, or a custom config
            if not args.config and not args.primers:
                raise Exception(f"argument --primers: no primer set selected, choose from ('V1', 'V2', 'V3') or use a custom configuration.")
            if not args.config:
                primer_set = f"/configs/artic_{args.primers}_nCoV-2019.bed"
                profile = profile + f" --primerSet {primer_set}"
            #build command
            command = nextflow_path + f" {config} run {monroe_path}/monroe_pe_assembly.nf {profile} {args.resume} --pipe pe --reads {args.reads_path} --outdir {args.output} -with-trace {args.output}/logs/{exec_time}Monroe_trace.txt -with-report {args.output}/logs/{exec_time}Monroe_execution_report.html {work}"
            #run command using nextflow in a subprocess
            print("Starting the Monroe paired-end assembly:")
            child = pexpect.spawn(command)
            child.interact()

        if args.monroe_command == 'se_assembly':
            #check for either standard ARTIC primer version, or a custom config
            if not args.config and not args.primers:
                raise Exception(f"argument --primers: no primer set selected, choose from ('V1', 'V2', 'V3') or use a custom configuration.")
            if not args.config:
                primer_set = f"/configs/artic_{args.primers}_nCoV-2019.bed"
                profile = profile + f" --primerSet {primer_set}"
            #build command
            command = nextflow_path + f" {config} run {monroe_path}/monroe_se_assembly.nf {profile} {args.resume} --pipe pe --reads {args.reads_path} --outdir {args.output} -with-trace {args.output}/logs/{exec_time}Monroe_trace.txt -with-report {args.output}/logs/{exec_time}Monroe_execution_report.html {work}"
            #run command using nextflow in a subprocess
            print("Starting the Monroe single-end assembly:")
            child = pexpect.spawn(command)
            child.interact()

        if args.monroe_command == 'clearlabs_assembly':
            #build command
            command = nextflow_path + f" {config} run {monroe_path}/monroe_clearlabs_assembly.nf {profile} {args.resume} --pipe clearlabs --reads {args.reads_path} --outdir {args.output} -with-trace {args.output}/logs/{exec_time}Monroe_trace.txt -with-report {args.output}/logs/{exec_time}Monroe_execution_report.html {work}"
            #run command using nextflow in a subprocess
            print("Starting the Monroe Clear Labs assembly:")
            child = pexpect.spawn(command)
            child.interact()

        if args.monroe_command == 'cluster_analysis':
            #give report template to user if requested
            if args.get_rtemplate:
                rtemplate_path = os.path.join(monroe_path,"report/report.Rmd")
                dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_cluster_analysis_report.Rmd")
                copyfile(rtemplate_path,dest_path)
                sys.exit()

            #check for assemblies path
            if not args.assemblies_path:
                subparser_monroe_cluster_analysis.print_help()
                print("Please specify a path to a directory containing the raw reads.")
                sys.exit(1)

            #build command
            command = nextflow_path + f" {config} run {monroe_path}/monroe_cluster_analysis.nf {profile} {args.resume} --pipe cluster --assemblies {args.assemblies_path} --report {args.rtemplate} --outdir {args.output} -with-trace {args.output}/logs/{exec_time}Monroe_trace.txt -with-report {args.output}/logs/{exec_time}Monroe_execution_report.html {work}"
            #run command using nextflow in a subprocess
            print("Starting the Monroe cluster analysis:")
            child = pexpect.spawn(command)
            child.interact()

        if args.monroe_command == 'ont_assembly':
            #build command
            if args.fast5_path:
                read_paths = f"--fast5_dir {args.fast5_path}"
            elif args.fastq_path:
                read_paths = f"--fastq_dir {args.fastq_path}"
            else:
                subparser_monroe_ont_assembly.print_help()
                print("Please provide path to fast5 files to perform basecalling or fastq files, note: basecalling requires GPU")
                sys.exit(1)

            command = nextflow_path + f" {config} run {monroe_path}/monroe_ont_assembly.nf {profile} {args.resume} {read_paths} --pipe ont --primers {args.primers} --outdir {args.output} --run_prefix {args.run_prefix} --medaka_model {args.medaka_model} --demultiplexed {args.demultiplexed} -with-trace {args.output}/logs/{exec_time}Monroe_trace.txt -with-report {args.output}/logs/{exec_time}Monroe_execution_report.html {work}"
            #run command using nextflow in a subprocess
            print("Starting the Monroe ONT assembly:")
            child = pexpect.spawn(command)
            child.interact()

    #foushee---------------------------------

    if program == 'foushee':
        #tredegar path
        foushee_path = os.path.join(workflows_path,"foushee/")

        #give config to user if requested
        if args.get_config:
            config_path = os.path.join(foushee_path,"configs/foushee_config_template.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_foushee.config")
            copyfile(config_path,dest_path)
            sys.exit()

        #check for reads_path
        if not args.reads_path:
            parser_foushee.print_help()
            print("Please specify a path to a directory containing the raw reads.")
            sys.exit(1)


        #check for config or profile
        config = ""
        if args.config:
            config = "-C " + os.path.abspath(args.config)
            profile = ""
        elif args.profile:
            profile = f"-profile {args.profile}"
        elif not profile:
            print('Singularity or Docker is not installed or not in found in PATH.')
            sys.exit(1)

        #set work dir into local logs dir if profile not aws
        work = ""
        if profile and not args.config:
            work = f"-w {args.output}/logs/work"

        #build command
        command = nextflow_path
        command = command + f" {config} run {foushee_path}/foushee.nf {profile} {args.resume} --reads {args.reads_path} --report {args.rtemplate} --outdir {args.output} -with-trace {args.output}/logs/{exec_time}Foushee_trace.txt -with-report {args.output}/logs/{exec_time}Foushee_execution_report.html {work}"
        print(command)

        #run command using nextflow in a subprocess
        print("Starting the Foushee pipeline:")
        child = pexpect.spawn(command)
        child.interact()

    #dryad-----------------------------------

    if program == 'dryad':
        #dryad path
        dryad_path = os.path.join(workflows_path,"dryad/")

        if args.dryad_app == None:
            parser_dryad.print_help()
            sys.exit(1)

        #give config to user if requested
        if args.get_config:
            config_path = os.path.join(dryad_path,"configs/dryad_config_template.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_dryad.config")
            copyfile(config_path,dest_path)
            sys.exit()

        #rebuild report subroutine
        if args.dryad_app == "rebuild_report":
            #check for rmd path
            if not args.rmd or not args.snp_matrix or not args.cg_tree:
                subparser_dryad_report.print_help()
                sys.exit(1)

            #check for config or profile
            config = ""
            if args.config:
                config = "-C " + os.path.abspath(args.config)
                profile = ""
            elif args.profile:
                if which(args.profile):
                    profile = '-profile ' + args.profile
                else:
                    print(f"{args.profile} is not installed or found in PATH.")
            elif not profile:
                print('Singularity or Docker is not installed or not found in PATH.')
                sys.exit(1)

            #set work dir into local logs dir if profile not aws
            work = ""
            output_path = os.path.join(os.getcwd(),'rebuild_results')
            output_work = os.path.join(output_path,'report_work')
            if profile and not args.config:
                work = f"-w {output_work}"

            rmd = os.path.abspath(args.rmd)
            logo_path = os.path.join(dryad_path, 'assets/dryad_logo_250.png')
            snp_mat = "--snp_matrix " + os.path.abspath(args.snp_matrix)
            cg_tree = "--cg_tree " + os.path.abspath(args.cg_tree)
            if args.ar:
                ar_tsv = "--ar_tsv " + os.path.abspath(args.ar)
            else:
                ar_tsv = ""

            #build command
            command = nextflow_path
            command = command + f" {config} run {dryad_path}/rebuild_report.nf {profile} --logo {logo_path} --outdir {output_path} --rmd {rmd} {snp_mat} {cg_tree} {ar_tsv} -with-trace {args.output}/logs/{exec_time}dryad_trace.txt -with-report {args.output}/logs/{exec_time}dryad_execution_report.html {work}"

            #run command using nextflow in a subprocess
            print("Rebuilding Dryad Report:")
            child = pexpect.spawn(command)
            child.interact()

        #dryad main application
        if args.dryad_app == "main":
            #check for reads_path
            if not args.reads_path:
                subparser_dryad_main.print_help()
                print("Please specify a path to a directory containing the raw reads.")
                sys.exit(1)

            #check for reference sequence
            if args.snp and args.r == None:
                subparser_dryad_main.print_help()
                print("Please specify a reference sequence for the SNP pipeline.")
                sys.exit(1)

            #check for config or profile
            config = ""
            if args.config:
                config = "-C " + os.path.abspath(args.config)
                profile = ""
            elif args.profile:
                if which(args.profile):
                    profile = '-profile ' + args.profile
                else:
                    print(f"{args.profile} is not installed or found in PATH.")
            elif not profile:
                print('Singularity or Docker is not installed or not found in PATH.')
                sys.exit(1)

            #set work dir into local logs dir if profile not aws
            work = ""
            if profile and not args.config:
                work = f"-w {args.output}/logs/work"

            #build nextflow command
            logo_path = os.path.join(dryad_path,"assets/dryad_logo_250.png")
            selections = ""
            if args.ar:
                selections += " --ar"
            if args.core_genome:
                selections += " --cg"
            if args.snp:
                selections += f" --snp --snp_reference {args.r}"
            if args.report and args.snp and args.core_genome:
                report_template_path = os.path.join(dryad_path,"report/report.Rmd")
                selections += f" --report {report_template_path} --logo {logo_path}"

            #path for multiqc config
            mqc_config_path = f"--multiqc_config " + os.path.join(dryad_path,"configs/multiqc_config.yaml")
            mqc_logo_path =  f"--multiqc_logo " + logo_path

            #add other arguments
            other_args = f"--outdir {args.output}"

            #build command
            command = nextflow_path
            command = command + f" {config} run {dryad_path}/dryad.nf {profile} {args.resume} --reads {args.reads_path} {selections} {other_args} {mqc_config_path} {mqc_logo_path} -with-trace {args.output}/logs/{exec_time}dryad_trace.txt -with-report {args.output}/logs/{exec_time}dryad_execution_report.html {work}"

            #run command using nextflow in a subprocess
            print("Starting the Dryad pipeline:")
            child = pexpect.spawn(command)
            child.interact()

    #hickory--------------------------------

    if program == 'hickory':
        #Hickory path
        hickory_path = os.path.join(workflows_path,"hickory/")

        #give config to user if requested
        if args.get_config:
            config_path = os.path.join(hickory_path,"configs/hickory_config_template.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_hickory.config")
            copyfile(config_path,dest_path)
            sys.exit()

        #check for reads_path
        if not args.reads_path:
            parser_hickory.print_help()
            print("Please specify a path to a directory containing the raw reads.")
            sys.exit(1)


        #check for config or profile
        config = ""
        if args.config:
            config = "-C " + os.path.abspath(args.config)
            profile = ""
        elif args.profile:
            profile = f"-profile {args.profile}"
        elif not profile:
            print('Singularity or Docker is not installed or not in found in PATH.')
            sys.exit(1)

        #set work dir into local logs dir if profile not aws
        work = ""
        if profile and not args.config:
            work = f"-w {args.output}/logs/work"

        #build command
        command = nextflow_path
        command = command + f" {config} run {hickory_path}/hickory.nf {profile} {args.resume} --reads {args.reads_path} --outdir {args.output} -with-trace {args.output}/logs/{exec_time}hickory_trace.txt -with-report {args.output}/logs/{exec_time}hickory_execution_report.html {work}"
        print(command)

        #run command using nextflow in a subprocess
        print("Starting the Hickory pipeline:")
        child = pexpect.spawn(command)
        child.interact()

    #cutshaw--------------------------------

    if program == 'cutshaw':
        #cutshaw path
        cutshaw_path = os.path.join(workflows_path,"cutshaw/")

        #give config to user if requested
        if args.get_config:
            config_path = os.path.join(cutshaw_path,"configs/cutshaw_config_template.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_cutshaw.config")
            copyfile(config_path,dest_path)
            sys.exit()

        #check for reads_path
        if not args.reads_path:
            parser_cutshaw.print_help()
            print("Please specify a path to a directory containing the raw reads.")
            sys.exit(1)


        #check for config or profile
        config = ""
        if args.config:
            config = "-C " + os.path.abspath(args.config)
            profile = ""
        elif args.profile:
            profile = f"-profile {args.profile}"
        elif not profile:
            print('Singularity or Docker is not installed or not in found in PATH.')
            sys.exit(1)

        #set work dir into local logs dir if profile not aws
        work = ""
        if profile and not args.config:
            work = f"-w {args.output}/logs/work"

        #build command
        command = nextflow_path
        print(args.report_title)
        command = command + f" {config} run {cutshaw_path}/cutshaw.nf {profile} {args.resume} --reads {args.reads_path} --pt_genomes {cutshaw_path}/pt_genomes/* --isolate_key {args.isolate_key} --title \"{args.report_title}\" --outdir {args.output} -with-trace {args.output}/logs/{exec_time}Cutshaw_trace.txt -with-report {args.output}/logs/{exec_time}Cutshaw_execution_report.html {work}"
        print(command)

        #run command using nextflow in a subprocess
        print("Starting the Cutshaw pipeline:")
        child = pexpect.spawn(command)
        child.interact()

    #cecret--------------------------------

    if program == 'cecret':
        #cecret path
        cecret_path = os.path.join(workflows_path,"cecret/")

        #give config to user if requested
        if args.get_config:
            config_path = os.path.join(cecret_path,"configs/cecret_config_template.config")
            dest_path = os.path.join(os.getcwd(),date.today().strftime("%y-%m-%d")+"_cecret.config")
            copyfile(config_path,dest_path)
            sys.exit()

        #check for reads_path
        if not args.reads_path:
            parser_cecret.print_help()
            print("Please specify a path to a directory containing paired end raw reads.")
            print("Note: Can specify an empty directory if single reads parameter is set.")
            sys.exit()

        #check for config or profile
        config = ""
        if args.config:
            config = "-C " + os.path.abspath(args.config)
            profile = ""
        elif args.profile:
            profile = f"-profile {args.profile}"
        elif not profile:
            print('Singularity or Docker is not installed or not in found in PATH.')
            sys.exit(1)

        reads_type = ""
        if args.reads_type == "paired":
            reads_type = "--reads"
        elif args.reads_type == "single":
            reads_type = "--single_reads"
        elif not args.reads_type:
            print("Type of reads not specified for some reason")
            sys.exit(1)

        if args.annotation:
            flow = 'cecret_annotation.nf'
            reads_type = '--fastas'
        else:
            flow = 'cecret.nf'

        #set work dir into local logs dir if profile not aws
        work = ""
        if profile and not args.config:
            work = f"-w {args.output}/logs/work"

        #build command
        command = nextflow_path
        command = command + f" {config} run {cecret_path}/{flow} {profile} {args.resume} {reads_type} {args.reads_path} --outdir {args.output} -with-trace {args.output}/logs/{exec_time}cecret_trace.txt -with-report {args.output}/logs/{exec_time}cecret_execution_report.html {work}"
        print(command)

        #run command using nextflow in a subprocess
        print("Starting the cecret workflow:")
        child = pexpect.spawn(command)
        child.interact()