Runs step12 (flag HW).

    :param in_prefix: the prefix of the input files.
    :param in_type: the type of the input files.
    :param out_prefix: the output prefix.
    :param base_dir: the output directory.
    :param options: the options needed.

    :type in_prefix: str
    :type in_type: str
    :type out_prefix: str
    :type base_dir: str
    :type options: list

    :returns: a tuple containing the prefix of the output files (the input
              prefix for the next script) and the type of the output files
              (``bfile``).

    This function calls the :py:mod:`pyGenClean.FlagHW.flag_hw` module. The
    required file type for this module is ``bfile``, hence the need to use the
    :py:func:`check_input_files` to check if the file input file type is the
    good one, or to create it if needed.

    .. note::
        The :py:mod:`pyGenClean.FlagHW.flag_hw` module doesn't return usable
        output files. Hence, this function returns the input file prefix and
        its type.

def run_flag_hw(in_prefix, in_type, out_prefix, base_dir, options):
    """Runs step12 (flag HW).

    :param in_prefix: the prefix of the input files.
    :param in_type: the type of the input files.
    :param out_prefix: the output prefix.
    :param base_dir: the output directory.
    :param options: the options needed.

    :type in_prefix: str
    :type in_type: str
    :type out_prefix: str
    :type base_dir: str
    :type options: list

    :returns: a tuple containing the prefix of the output files (the input
              prefix for the next script) and the type of the output files
              (``bfile``).

    This function calls the :py:mod:`pyGenClean.FlagHW.flag_hw` module. The
    required file type for this module is ``bfile``, hence the need to use the
    :py:func:`check_input_files` to check if the file input file type is the
    good one, or to create it if needed.

    .. note::
        The :py:mod:`pyGenClean.FlagHW.flag_hw` module doesn't return usable
        output files. Hence, this function returns the input file prefix and
        its type.

    """
    # Creating the output directory
    os.mkdir(out_prefix)

    # We know we need bfile
    required_type = "bfile"
    check_input_files(in_prefix, in_type, required_type)

    # We need to inject the name of the input file and the name of the output
    # prefix
    script_prefix = os.path.join(out_prefix, "flag_hw")
    options += ["--{}".format(required_type), in_prefix,
                "--out", script_prefix]

    # We run the script
    try:
        flag_hw.main(options)
    except flag_hw.ProgramError as e:
        msg = "flag_hw: {}".format(e)
        raise ProgramError(msg)

    # Finding the two files containing the list of flagged markers
    filenames = glob(script_prefix + ".snp_flag_threshold_[0-9]*")
    thresholds = {}
    for filename in filenames:
        # Finding the threshold of the file
        threshold = re.sub(
            r"^flag_hw.snp_flag_threshold_",
            "",
            os.path.basename(filename),
        )

        # Counting the number of markers in the file
        nb_markers = None
        with open(filename, "r") as i_file:
            nb_markers = len(i_file.read().splitlines())

        # Saving the values
        thresholds[threshold] = (nb_markers, filename)

    # We create the LaTeX summary
    latex_file = os.path.join(script_prefix + ".summary.tex")
    try:
        with open(latex_file, "w") as o_file:
            print >>o_file, latex_template.subsection(
                flag_hw.pretty_name
            )

            # Data to write
            sorted_keys = sorted(thresholds.keys(), key=float)

            text = (
                "Markers which failed Hardy-Weinberg equilibrium test (using "
                "Plink) were flagged. A total of {:,d} marker{} failed with a "
                "threshold of {}. A total of {:,d} marker{} failed with a "
                "threshold of {}. For a total list, check the files {} and "
                "{}, respectively.".format(
                    thresholds[sorted_keys[0]][0],
                    "s" if thresholds[sorted_keys[0]][0] - 1 > 1 else "",
                    latex_template.format_numbers(sorted_keys[0]),
                    thresholds[sorted_keys[1]][0],
                    "s" if thresholds[sorted_keys[1]][0] - 1 > 1 else "",
                    latex_template.format_numbers(sorted_keys[1]),
                    latex_template.texttt(
                        latex_template.sanitize_tex(os.path.basename(
                            thresholds[sorted_keys[0]][1],
                        )),
                    ),
                    latex_template.texttt(
                        latex_template.sanitize_tex(os.path.basename(
                            thresholds[sorted_keys[1]][1],
                        )),
                    ),
                )
            )
            print >>o_file, latex_template.wrap_lines(text)

    except IOError:
        msg = "{}: cannot write LaTeX summary".format(latex_file)
        raise ProgramError(msg)

    # Writing the summary results
    with open(os.path.join(base_dir, "results_summary.txt"), "a") as o_file:
        print >>o_file, "# {}".format(script_prefix)
        print >>o_file, "Number of markers flagged for HW"
        print >>o_file, "  - {}\t{:,d}".format(
                            sorted_keys[0],
                            thresholds[sorted_keys[0]][0],
                        )
        print >>o_file, "  - {}\t{:,d}".format(
                            sorted_keys[1],
                            thresholds[sorted_keys[1]][0],
                        )
        print >>o_file, "---"

    # We know this step doesn't produce an new data set, so we return the old
    # prefix and the old in_type
    return _StepResult(
        next_file=in_prefix,
        next_file_type=required_type,
        latex_summary=latex_file,
        description=flag_hw.desc,
        long_description=flag_hw.long_desc,
        graph_path=None,
    )