Checks the arguments and options.

    :param args: an object containing the options of the program.

    :type args: argparse.Namespace

    :returns: ``True`` if everything was OK.

    If there is a problem with an option, an exception is raised using the
    :py:class:`ProgramError` class, a message is printed to the
    :class:`sys.stderr` and the program exists with code 1.

    .. note::
        Only one operation for markers and one operation for samples can be
        done at a time. Hence, one of ``--exclude`` or ``--extract`` can be
        done for markers, and one of ``--remove`` or ``--keep`` can be done for
        samples.

def checkArgs(args):
    """Checks the arguments and options.

    :param args: an object containing the options of the program.

    :type args: argparse.Namespace

    :returns: ``True`` if everything was OK.

    If there is a problem with an option, an exception is raised using the
    :py:class:`ProgramError` class, a message is printed to the
    :class:`sys.stderr` and the program exists with code 1.

    .. note::
        Only one operation for markers and one operation for samples can be
        done at a time. Hence, one of ``--exclude`` or ``--extract`` can be
        done for markers, and one of ``--remove`` or ``--keep`` can be done for
        samples.

    """
    # Check the input files
    if not args.is_bfile and not args.is_tfile and not args.is_file:
        msg = "needs one input file type (--is-bfile, --is-tfile or --is-file)"
        raise ProgramError(msg)

    if args.is_bfile and not args.is_tfile and not args.is_file:
        for fileName in [args.ifile + i for i in [".bed", ".bim", ".fam"]]:
            if not os.path.isfile(fileName):
                msg = "{}: no such file".format(fileName)
                raise ProgramError(msg)

    elif args.is_tfile and not args.is_bfile and not args.is_file:
        for fileName in [args.ifile + i for i in [".tped", ".tfam"]]:
            if not os.path.isfile(fileName):
                msg = "{}: no such file".format(fileName)
                raise ProgramError(msg)

    elif args.is_file and not args.is_bfile and not args.is_tfile:
        for fileName in [args.ifile + i for i in [".ped", ".map"]]:
            if not os.path.isfile(fileName):
                msg = "{}: no such file". format(fileName)
                raise ProgramError(msg)

    else:
        msg = ("needs only one input file type (--is-bfile, --is-tfile or "
               "--is-file)")
        raise ProgramError(msg)

    # Check that we have at least one of exclude, extract remove or keep
    if args.exclude is None and args.extract is None and \
            args.remove is None and args.keep is None:
        msg = "needs at least one of --exclude, --extract, --remove or --keep"
        raise ProgramError(msg)

    # Check for SNPs
    if args.exclude is not None and args.extract is None:
        if not os.path.isfile(args.exclude):
            msg = "{}: no such file".format(args.exclude)
            raise ProgramError(msg)
    elif args.extract is not None and args.exclude is None:
        if not os.path.isfile(args.extract):
            msg = "{}: no such file".format(args.extract)
            raise ProgramError(msg)
    elif args.exclude is not None and args.extract is not None:
        msg = "use only one of --extract or --exclude"
        raise ProgramError(msg)

    # Check for samples
    if args.remove is not None and args.keep is None:
        if not os.path.isfile(args.remove):
            msg = "{}: no such file".format(args.remove)
            raise ProgramError(msg)
    elif args.keep is not None and args.remove is None:
        if not os.path.isfile(args.keep):
            msg = "{}: no such file".format(args.keep)
            raise ProgramError(msg)
    elif args.remove is not None and args.keep is not None:
        msg = "use only one of --keep or --remove"
        raise ProgramError(msg)

    return True