"""
Entry point for all TopoStats programs.
Parses command-line arguments and passes input on to the relevant functions / modules.
"""
import argparse as arg
import sys
from pathlib import Path
from topostats import __version__
from topostats.io import write_config_with_comments
from topostats.plotting import run_toposum
from topostats.run_topostats import run_topostats
# pylint: disable=too-many-statements
[docs]
def create_parser() -> arg.ArgumentParser:
    """
    Create a parser for reading options.
    Creates a parser, with multiple sub-parsers for reading options to run 'topostats'.
    Returns
    -------
    arg.ArgumentParser
        Argument parser.
    """
    parser = arg.ArgumentParser(
        description="Run various programs relating to AFM data. Add the name of the program you wish to run."
    )
    parser.add_argument(
        "-v",
        "--version",
        action="version",
        version=f"Installed version of TopoStats: {__version__}",
        help="Report the current version of TopoStats that is installed",
    )
    subparsers = parser.add_subparsers(title="program", description="Available programs, listed below:", dest="program")
    # Create a sub-parsers for different stages of processing and tasks
    process_parser = subparsers.add_parser(
        "process",
        description="Process AFM images. Additional arguments over-ride defaults or those in the configuration file.",
        help="Process AFM images. Additional arguments over-ride defaults or those in the configuration file.",
    )
    process_parser.add_argument(
        "-c",
        "--config-file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML configuration file.",
    )
    process_parser.add_argument(
        "-s",
        "--summary-config",
        dest="summary_config",
        required=False,
        help="Path to a YAML configuration file for summary plots and statistics.",
    )
    process_parser.add_argument(
        "--matplotlibrc",
        dest="matplotlibrc",
        type=Path,
        required=False,
        help="Path to a matplotlibrc file.",
    )
    process_parser.add_argument(
        "-b",
        "--base-dir",
        dest="base_dir",
        type=Path,
        required=False,
        help="Base directory to scan for images.",
    )
    process_parser.add_argument(
        "-j",
        "--cores",
        dest="cores",
        type=int,
        required=False,
        help="Number of CPU cores to use when processing.",
    )
    process_parser.add_argument(
        "-l",
        "--log-level",
        dest="log_level",
        type=str,
        required=False,
        help="Logging level to use, default is 'info' for verbose output use 'debug'.",
    )
    process_parser.add_argument(
        "-f",
        "--file-ext",
        dest="file_ext",
        type=str,
        required=False,
        help="File extension to scan for.",
    )
    process_parser.add_argument(
        "--channel",
        dest="channel",
        type=str,
        required=False,
        help="Channel to extract.",
    )
    process_parser.add_argument(
        "-o",
        "--output-dir",
        dest="output_dir",
        type=Path,
        required=False,
        help="Output directory to write results to.",
    )
    process_parser.add_argument(
        "--save-plots",
        dest="save_plots",
        type=bool,
        required=False,
        help="Whether to save plots.",
    )
    process_parser.add_argument(
        "--savefig-format",
        dest="savefig_format",
        type=str,
        required=False,
        help="Format for saving figures to, options are 'png', 'svg', or other valid Matplotlib supported formats.",
    )
    process_parser.add_argument(
        "--savefig-dpi",
        dest="savefig_dpi",
        type=int,
        required=False,
        help="Dots Per Inch for plots, should be integer for dots per inch.",
    )
    process_parser.add_argument(
        "--cmap",
        dest="cmap",
        type=str,
        required=False,
        help="Colormap to use, options include 'nanoscope', 'afmhot' and any valid Matplotlib colormap.",
    )
    process_parser.add_argument("-m", "--mask", dest="mask", type=bool, required=False, help="Mask the image.")
    process_parser.add_argument(
        "-w",
        "--warnings",
        dest="warnings",
        type=bool,
        required=False,
        help="Whether to ignore warnings.",
    )
    process_parser.set_defaults(func=run_topostats)
    toposum_parser = subparsers.add_parser(
        "summary",
        description="Plotting and summary of TopoStats output statistics.",
        help="Plotting and summary of TopoStats output statistics.",
    )
    toposum_parser.add_argument("-i", "--input_csv", dest="csv_file", required=False, help="Path to CSV file to plot.")
    toposum_parser.add_argument(
        "-c",
        "--config-file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML plotting dictionary that maps variable names to labels.",
    )
    toposum_parser.add_argument(
        "-l",
        "--var-to-label",
        dest="var_to_label",
        type=Path,
        required=False,
        help="Path to a YAML plotting dictionary that maps variable names to labels.",
    )
    toposum_parser.add_argument(
        "--create-config-file",
        dest="create_config_file",
        type=Path,
        required=False,
        help="Filename to write a sample YAML configuration file to (should end in '.yaml').",
    )
    toposum_parser.add_argument(
        "--create-label-file",
        dest="create_label_file",
        type=Path,
        required=False,
        help="Filename to write a sample YAML label file to (should end in '.yaml').",
    )
    toposum_parser.add_argument(
        "--savefig-format",
        dest="savefig_format",
        type=str,
        required=False,
        help="Format for saving figures to, options are 'png', 'svg', or other valid Matplotlib supported formats.",
    )
    toposum_parser.set_defaults(func=run_toposum)
    load_parser = subparsers.add_parser(
        "load",
        description="Load and save all images as .topostats files for subsequent processing.",
        help="Load and save all images as .topostats files for subsequent processing.",
    )
    load_parser.add_argument(
        "-c",
        "--config-file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML configuration file.",
    )
    filter_parser = subparsers.add_parser(
        "filter",
        description="Load and filter images, saving as .topostats files for subsequent processing.",
        help="Load and filter images, saving as .topostats files for subsequent processing.",
    )
    filter_parser.add_argument(
        "-c",
        "--config-file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML configuration file.",
    )
    grain_parser = subparsers.add_parser(
        "grains",
        description="Load filtered images from '.topostats' files and detect grains.",
        help="Load filtered images from '.topostats' files and detect grains.",
    )
    grain_parser.add_argument(
        "-c",
        "--config-file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML configuration file.",
    )
    grainstats_parser = subparsers.add_parser(
        "grainstats",
        description="Load images with grains from '.topostats' files and calculate statistics.",
        help="Load images with grains from '.topostats' files and calculate statistics.",
    )
    grainstats_parser.add_argument(
        "-c",
        "--config-file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML configuration file.",
    )
    dnatracing_parser = subparsers.add_parser(
        "dnatracing",
        description="Load images with grains from '.topostats' files and trace DNA molecules.",
        help="Load images with grains from '.topostats' files and trace DNA molecules.",
    )
    dnatracing_parser.add_argument(
        "-c",
        "--config-file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML configuration file.",
    )
    tracingstats_parser = subparsers.add_parser(
        "tracingstats",
        description="Load images with grains from '.topostats' files and trace DNA molecules.",
        help="Load images with grains from '.topostats' files and trace DNA molecules.",
    )
    tracingstats_parser.add_argument(
        "-c",
        "--config-file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML configuration file.",
    )
    create_config_parser = subparsers.add_parser(
        "create-config",
        description="Create a configuration file using the defaults.",
        help="Create a configuration file using the defaults.",
    )
    create_config_parser.add_argument(
        "-f",
        "--filename",
        dest="filename",
        type=Path,
        required=False,
        default="config.yaml",
        help="Name of YAML file to save configuration to (default 'config.yaml').",
    )
    create_config_parser.add_argument(
        "-o",
        "--output-dir",
        dest="output_dir",
        type=Path,
        required=False,
        default="./",
        help="Path to where the YAML file should be saved (default './' the current directory).",
    )
    create_config_parser.add_argument(
        "-c",
        "--config",
        dest="config",
        type=str,
        default=None,
        help="Configuration to use, currently only one is supported, the 'default'.",
    )
    create_config_parser.set_defaults(func=write_config_with_comments)
    create_matplotlibrc_parser = subparsers.add_parser(
        "create-matplotlibrc",
        description="Create a Matplotlibrc parameters file.",
        help="Create a Matplotlibrc parameters file using the defaults.",
    )
    create_matplotlibrc_parser.add_argument(
        "-f",
        "--filename",
        dest="filename",
        type=Path,
        required=False,
        default="topostats.mplstyle",
        help="Name of file to save Matplotlibrc configuration to (default 'topostats.mplstyle').",
    )
    create_matplotlibrc_parser.add_argument(
        "-o",
        "--output-dir",
        dest="output_dir",
        type=Path,
        required=False,
        default="./",
        help="Path to where the YAML file should be saved (default './' the current directory).",
    )
    create_matplotlibrc_parser.add_argument(
        "-c",
        "--config",
        dest="config",
        default="topostats.mplstyle",
        help="Matplotlibrc style file to use, currently only one is supported, the 'topostats.mplstyle'.",
    )
    create_matplotlibrc_parser.set_defaults(func=write_config_with_comments)
    return parser 
[docs]
def entry_point(manually_provided_args=None, testing=False) -> None:
    """
    Entry point for all TopoStats programs.
    Main entry point for running 'topostats' which allows the different processing steps ('process', 'filter',
    'create_config' etc.) to be run.
    Parameters
    ----------
    manually_provided_args : None
        Manually provided arguments.
    testing : bool
        Whether testing is being carried out.
    Returns
    -------
    None
        Does not return anything.
    """
    # Parse command line options, load config (or default) and update with command line options
    parser = create_parser()
    args = parser.parse_args() if manually_provided_args is None else parser.parse_args(manually_provided_args)
    # No program specified, print help and exit
    if not args.program:
        parser.print_help()
        sys.exit()
    if testing:
        return args
    # call the relevant function
    args.func(args)
    return None 
[docs]
def create_legacy_run_topostats_parser() -> arg.ArgumentParser:
    """
    Create a parser reading options for the 'run_topostats' processing entry point.
    Returns
    -------
    arg.ArgumentParser
        Arguments to be passed to 'run_topostats'.
    """
    parser = arg.ArgumentParser(
        description="Process AFM images. Additional arguments over-ride those in the configuration file."
    )
    parser.add_argument(
        "-c",
        "--config_file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML configuration file.",
    )
    parser.add_argument(
        "-s",
        "--summary_config",
        dest="summary_config",
        type=Path,
        required=False,
        help="Path to a YAML configuration file for summary plots and statistics.",
    )
    parser.add_argument(
        "-b",
        "--base_dir",
        dest="base_dir",
        type=Path,
        required=False,
        help="Base directory to scan for images.",
    )
    parser.add_argument(
        "-j",
        "--cores",
        dest="cores",
        type=int,
        required=False,
        help="Number of CPU cores to use when processing.",
    )
    parser.add_argument(
        "-l",
        "--log_level",
        dest="log_level",
        type=str,
        required=False,
        help="Logging level to use, default is 'info' for verbose output use 'debug'.",
    )
    parser.add_argument(
        "-f",
        "--file_ext",
        dest="file_ext",
        type=str,
        required=False,
        help="File extension to scan for.",
    )
    parser.add_argument(
        "--channel",
        dest="channel",
        type=str,
        required=False,
        help="Channel to extract.",
    )
    parser.add_argument(
        "-o",
        "--output_dir",
        dest="output_dir",
        type=Path,
        required=False,
        help="Output directory to write results to.",
    )
    parser.add_argument(
        "--save_plots",
        dest="save_plots",
        type=bool,
        required=False,
        help="Whether to save plots.",
    )
    parser.add_argument("-m", "--mask", dest="mask", type=bool, required=False, help="Mask the image.")
    parser.add_argument(
        "-v",
        "--version",
        action="version",
        version=f"Installed version of TopoStats : {__version__}",
        help="Report the current version of TopoStats that is installed.",
    )
    parser.add_argument(
        "-w",
        "--warnings",
        dest="warnings",
        type=bool,
        required=False,
        help="Whether to ignore warnings.",
    )
    return parser 
[docs]
def create_legacy_toposum_parser() -> arg.ArgumentParser:
    """
    Create a parser reading options for the legacy 'toposum' summarize entry point.
    Returns
    -------
    arg.ArgumentParser
        Arguments to be passed to 'toposum'.
    """
    parser = arg.ArgumentParser(
        description="Summarise and plot histograms, kernel density estimates and scatter plots of TopoStats"
        "grain and DNA Tracing statistics."
    )
    parser.add_argument("-i", "--input_csv", dest="csv_file", required=False, help="Path to CSV file to plot.")
    parser.add_argument(
        "-c",
        "--config_file",
        dest="config_file",
        type=Path,
        required=False,
        help="Path to a YAML configuration file.",
    )
    parser.add_argument(
        "-l",
        "--var_to_label",
        dest="var_to_label",
        type=Path,
        required=False,
        help="Path to a YAML plotting dictionary that maps variable names to labels.",
    )
    parser.add_argument(
        "--create-config-file",
        dest="create_config_file",
        type=Path,
        required=False,
        help="Filename to write a sample YAML configuration file to (should end in '.yaml').",
    )
    parser.add_argument(
        "--create-label-file",
        dest="create_label_file",
        type=Path,
        required=False,
        help="Filename to write a sample YAML label file to (should end in '.yaml').",
    )
    return parser 
[docs]
def legacy_run_topostats_entry_point(args=None, testing=False) -> None:
    """
    Legacy entry point for the run_topostats processing function.
    Parameters
    ----------
    args : None
        Arguments.
    testing : bool
        Whether functions is being tested.
    Returns
    -------
    None
        Does not return anything.
    """
    parser = create_legacy_run_topostats_parser()
    args = parser.parse_args() if args is None else parser.parse_args(args)
    if testing:
        return args
    run_topostats(args=args)
    return None 
[docs]
def legacy_toposum_entry_point(args=None, testing=False) -> None:
    """
    Legacy entry point for the toposum summarizing function.
    Parameters
    ----------
    args : None
        Arguments.
    testing : bool
        Whether functions is being tested.
    Returns
    -------
    None
        Does not return anything.
    """
    parser = create_legacy_toposum_parser()
    args = parser.parse_args() if args is None else parser.parse_args(args)
    if testing:
        return args
    run_toposum(args=args)
    return None