docs: def main():
      """The main function.
  
      These are the steps performed for the data clean up:
  
      1. Prints the version number.
      2. Reads the configuration file (:py:func:`read_config_file`).
      3. Creates a new directory with ``data_clean_up`` as prefix and the date
         and time as suffix.
      4. Check the input file type (``bfile``, ``tfile`` or ``file``).
      5. Creates an intermediate directory with the section as prefix and the
         script name as suffix (inside the previous directory).
      6. Runs the required script in order (according to the configuration file
         section).
  
      .. note::
          The main function is not responsible to check if the required files
          exist. This should be done in the ``run`` functions.
  
      """
      # Getting and checking the options
      args = parse_args()
      check_args(args)
  
      # The directory name
      dirname = "data_clean_up."
      dirname += datetime.datetime.today().strftime("%Y-%m-%d_%H.%M.%S")
      while os.path.isdir(dirname):
          time.sleep(1)
          dirname = "data_clean_up."
          dirname += datetime.datetime.today().strftime("%Y-%m-%d_%H.%M.%S")
  
      # Creating the output directory
      os.mkdir(dirname)
  
      # Configuring the root logger
      add_file_handler_to_root(os.path.join(dirname, "pyGenClean.log"))
  
      logger.info("pyGenClean version {}".format(__version__))
      plink_version = get_plink_version()
      logger.info("Using Plink version {}".format(plink_version))
  
      # Reading the configuration file
      logger.info("Reading configuration file [ {} ]".format(args.conf))
      order, conf = read_config_file(args.conf)
  
      # Executing the data clean up
      current_in = None
      current_in_type = None
      suffixes = None
      if args.tfile is not None:
          current_in = args.tfile
          current_in_type = "tfile"
          suffixes = (".tped", ".tfam")
      elif args.bfile is not None:
          current_in = args.bfile
          current_in_type = "bfile"
          suffixes = (".bed", ".bim", ".fam")
      else:
          current_in = args.file
          current_in_type = "file"
          suffixes = (".ped", ".map")
  
      # Creating the excluded files
      try:
          with open(os.path.join(dirname, "excluded_markers.txt"), "w") as o_f:
              pass
          with open(os.path.join(dirname, "excluded_samples.txt"), "w") as o_f:
              pass
          with open(os.path.join(dirname, "initial_files.txt"), "w") as o_file:
              for s in suffixes:
                  print >>o_file, current_in + s
  
      except IOError:
          msg = "{}: cannot write summary".format(dirname)
          raise ProgramError(msg)
  
      # Counting the number of markers and samples in the datafile
      logger.info("Counting initial number of samples and markers")
      nb_markers, nb_samples = count_markers_samples(current_in,
                                                     current_in_type)
      logger.info("  - {:,d} samples".format(nb_samples))
      logger.info("  - {:,d} markers".format(nb_markers))
  
      # Creating the result summary file containing the initial numbers
      try:
          with open(os.path.join(dirname, "results_summary.txt"), "w") as o_file:
              print >>o_file, "# initial"
              print >>o_file, ("Initial number of markers\t"
                               "{:,d}".format(nb_markers))
              print >>o_file, ("Initial number of samples\t"
                               "{:,d}".format(nb_samples))
              print >>o_file, "---"
      except IOError:
          msg = "{}: cannot write summary".format(dirname)
          raise ProgramError(msg)
  
      latex_summaries = []
      steps = []
      descriptions = []
      long_descriptions = []
      graphic_paths = set()
      for number in order:
          # Getting the script name and its options
          script_name, options = conf[number]
  
          # Getting the output prefix
          output_prefix = os.path.join(dirname,
                                       "{}_{}".format(number, script_name))
  
          # Getting the function to use
          function_to_use = available_functions[script_name]
  
          # Executing the function
          logger.info("Running {} {}".format(number, script_name))
          logger.info("  - Using {} as prefix for input "
                      "files".format(current_in))
          logger.info("  - Results will be in [ {} ]".format(output_prefix))
  
          # Executing the function
          step_results = function_to_use(
              in_prefix=current_in,
              in_type=current_in_type,
              out_prefix=output_prefix,
              base_dir=dirname,
              options=options,
          )
  
          # Updating the input files and input file types
          current_in = step_results.next_file
          current_in_type = step_results.next_file_type
  
          # Saving what's necessary for the LaTeX report
          latex_summaries.append(step_results.latex_summary)
          steps.append(script_name)
          descriptions.append(step_results.description)
          long_descriptions.append(step_results.long_description)
          if step_results.graph_path is not None:
              graphic_paths.update(step_results.graph_path)
  
      # Counting the final number of samples and markers
      logger.info("Counting final number of samples and markers")
      nb_markers, nb_samples = count_markers_samples(current_in,
                                                     current_in_type)
      logger.info("  - {:,d} samples".format(nb_samples))
      logger.info("  - {:,d} markers".format(nb_markers))
  
      # Getting the final suffixes
      suffixes = None
      if current_in_type == "tfile":
          suffixes = ((".tped", nb_markers), (".tfam", nb_samples))
      elif current_in_type == "bfile":
          suffixes = ((".bed", None), (".bim", nb_markers), (".fam", nb_samples))
      else:
          suffixes = ((".ped", nb_samples), (".map", nb_markers))
  
      with open(os.path.join(dirname, "final_files.txt"), "w") as o_file:
          for s, nb in suffixes:
              if nb:
                  print >>o_file, current_in + s + "\t{:,d}".format(nb)
              else:
                  print >>o_file, current_in + s
  
      # Generating the graphics paths file
      graphic_paths_fn = None
      if len(graphic_paths) > 0:
          try:
              graphic_paths_fn = os.path.join(dirname, "graphic_paths.txt")
              with open(graphic_paths_fn, "w") as o_file:
                  for path in sorted(graphic_paths):
                      print >>o_file, path
          except IOError:
              msg = "{}: cannot write summary".format(dirname)
              raise ProgramError(msg)
  
      # We create the automatic report
      logger.info("Generating automatic report")
      report_name = os.path.join(dirname, "automatic_report.tex")
      auto_report.create_report(
          dirname,
          report_name,
          project_name=args.report_number,
          steps=steps,
          descriptions=descriptions,
          graphic_paths_fn=graphic_paths_fn,
          long_descriptions=long_descriptions,
          summaries=latex_summaries,
          background=args.report_background,
          summary_fn=os.path.join(dirname, "results_summary.txt"),
          report_title=args.report_title,
          report_author=args.report_author,
          initial_files=os.path.join(dirname, "initial_files.txt"),
          final_files=os.path.join(dirname, "final_files.txt"),
          final_nb_markers="{:,d}".format(nb_markers),
          final_nb_samples="{:,d}".format(nb_samples),
          plink_version=plink_version,
      )