<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read_config_file(filename):
 """Reads the configuration file. :param filename: the name of the file containing the configuration. :type filename: str :returns: A tuple where the first element is a list of sections, and the second element is a map containing the configuration (options and values). The structure of the configuration file is important. Here is an example of a configuration file:: [1] # Computes statistics on duplicated samples script = duplicated_samples [2] # Removes samples according to missingness script = sample_missingness [3] # Removes markers according to missingness script = snp_missingness [4] # Removes samples according to missingness (98%) script = sample_missingness mind = 0.02 [5] # Performs a sex check script = sex_check [6] # Flags markers with MAF=0 script = flag_maf_zero [7] # Flags markers according to Hardy Weinberg script = flag_hw [8] # Subset the dataset (excludes markers and remove samples) script = subset Sections are in square brackets and must be ``integer``. The section number represent the step at which the script will be run (*i.e.* from the smallest number to the biggest). The sections must be continuous. Each section contains the script names (``script`` variable) and options of the script (all other variables) (*e.g.* section 4 runs the ``sample_missingness`` script (:py:func:`run_sample_missingness`) with option ``mind`` sets to 0.02). Here is a list of the available scripts: * ``duplicated_samples`` (:py:func:`run_duplicated_samples`) * ``duplicated_snps`` (:py:func:`run_duplicated_snps`) * ``noCall_hetero_snps`` (:py:func:`run_noCall_hetero_snps`) * ``sample_missingness`` (:py:func:`run_sample_missingness`) * ``snp_missingness`` (:py:func:`run_snp_missingness`) * ``sex_check`` (:py:func:`run_sex_check`) * ``plate_bias`` (:py:func:`run_plate_bias`) * ``contamination`` (:py:func:`run_contamination`) * ``remove_heterozygous_haploid`` (:py:func:`run_remove_heterozygous_haploid`) * ``find_related_samples`` (:py:func:`run_find_related_samples`) * ``check_ethnicity`` (:py:func:`run_check_ethnicity`) * ``flag_maf_zero`` (:py:func:`run_flag_maf_zero`) * ``flag_hw`` (:py:func:`run_flag_hw`) * ``subset`` (:py:func:`run_subset_data`) * ``compare_gold_standard`` (:py:func:`run_compare_gold_standard`) """

    # Creating the config parser
    config = ConfigParser.RawConfigParser(allow_no_value=True)
    config.optionxform = str
    config.read(filename)

    # Checking the section names
    sections = None
    try:
        sections = sorted([int(i) for i in config.sections()])
    except ValueError:
        # Section not integer
        msg = ("{}: sections must be integers: "
               "{}".format(filename, config.sections()))
        raise ProgramError(msg)
    if sections != range(min(sections), max(sections)+1):
        # Missing a section
        msg = "{}: maybe a section is missing: {}".format(filename, sections)
        raise ProgramError(msg)
    sections = [str(i) for i in sections]

    # Reading the configuration for each sections
    configuration = {}
    for section in sections:
        # Getting the script variable (and check it)
        script_name = None
        try:
            script_name = config.get(section, "script")
        except ConfigParser.NoOptionError:
            msg = ("{}: section {}: no variable called 'script'".format(
                filename,
                section,
            ))
            raise ProgramError(msg)
        if script_name not in available_modules:
            msg = ("{}: section {}: script {}: invalid script name".format(
                filename,
                section,
                script_name,
            ))
            raise ProgramError(msg)

        # Getting the variables
        options = []
        for variable_name, variable_value in config.items(section):
            unwanted_options = {"bfile", "tfile", "file", "out"}
            if script_name in {"sample_missingness", "subset"}:
                unwanted_options |= {"ifile", "is-bfile", "is-tfile"}
            if script_name == "subset":
                unwanted_options.add("is-file")
            for unwanted in unwanted_options:
                if variable_name == unwanted:
                    msg = ("{}: section {}: do not use {} as an option for "
                           "{}".format(filename, section, unwanted,
                                       script_name))
                    raise ProgramError(msg)
            if variable_name != "script":
                options.append("--" + variable_name)
                if variable_value is not None:
                    if variable_name in {"indep-pairwise", "sge-nodes",
                                         "ibs-sge-nodes"}:
                        # This is a special option
                        options.extend(variable_value.split(" "))
                    else:
                        options.append(variable_value)

        # Saving the configuration
        configuration[section] = (script_name, options)

    return sections, configuration