docs: def usearch61_denovo_cluster(seq_path,
                               percent_id=0.97,
                               rev=False,
                               save_intermediate_files=True,
                               minlen=64,
                               output_dir='.',
                               remove_usearch_logs=False,
                               verbose=False,
                               wordlength=8,
                               usearch_fast_cluster=False,
                               usearch61_sort_method='abundance',
                               otu_prefix="denovo",
                               usearch61_maxrejects=32,
                               usearch61_maxaccepts=1,
                               sizeorder=False,
                               threads=1.0,
                               HALT_EXEC=False,
                               file_prefix="denovo_"
                               ):
      """ Returns dictionary of cluster IDs:seq IDs
  
      Overall function for de novo clustering with usearch61
  
      seq_path:  fasta filepath to be clustered with usearch61
      percent_id:  percentage id to cluster at
      rev: enable reverse strand matching for clustering
      save_intermediate_files: Saves intermediate files created during clustering
      minlen: minimum sequence length
      output_dir: directory to output log, OTU mapping, and intermediate files
      remove_usearch_logs: Saves usearch log files
      verbose: print current processing step to stdout
      wordlength: word length to use for clustering
      usearch_fast_cluster: Use usearch61 fast cluster option, not as memory
       efficient as the default cluster_smallmem option, requires sorting by
       length, and does not allow reverse strand matching.
      usearch61_sort_method:  Sort sequences by abundance or length by using
       functionality provided by usearch61, or do not sort by using None option.
      otu_prefix: label to place in front of OTU IDs, used to prevent duplicate
       IDs from appearing with reference based OTU picking.
      usearch61_maxrejects: Number of rejects allowed by usearch61
      usearch61_maxaccepts: Number of accepts allowed by usearch61
      sizeorder: used for clustering based upon abundance of seeds
      threads: Specify number of threads used per core per CPU
      HALT_EXEC: application controller option to halt execution.
      """
  
      files_to_remove = []
  
      # Need absolute paths to avoid potential problems with app controller
      if output_dir:
          output_dir = abspath(output_dir) + '/'
      seq_path = abspath(seq_path)
  
      try:
          if verbose and usearch61_sort_method is not None and\
                  not usearch_fast_cluster:
              print "Sorting sequences according to %s..." % usearch61_sort_method
  
          # fast sorting option automatically performs length sorting
          if usearch61_sort_method == 'abundance' and not usearch_fast_cluster:
              intermediate_fasta, dereplicated_uc, app_result =\
                  sort_by_abundance_usearch61(seq_path, output_dir, rev,
                                              minlen, remove_usearch_logs, HALT_EXEC,
                                              output_fna_filepath=join(
                                                  output_dir,
                                                  file_prefix + 'abundance_sorted.fna'),
                                              output_uc_filepath=join(output_dir,
                                                                      file_prefix + 'abundance_sorted.uc'), threads=threads)
              if not save_intermediate_files:
                  files_to_remove.append(intermediate_fasta)
                  files_to_remove.append(dereplicated_uc)
          elif usearch61_sort_method == 'length' and not usearch_fast_cluster:
              intermediate_fasta, app_result =\
                  sort_by_length_usearch61(seq_path, output_dir, minlen,
                                           remove_usearch_logs, HALT_EXEC,
                                           output_fna_filepath=join(output_dir,
                                                                    file_prefix + 'length_sorted.fna'))
              if not save_intermediate_files:
                  files_to_remove.append(intermediate_fasta)
          else:
              intermediate_fasta = seq_path
  
          if verbose:
              print "Clustering sequences de novo..."
  
          if usearch_fast_cluster:
              clusters_fp, app_result = usearch61_fast_cluster(
                  intermediate_fasta,
                  percent_id, minlen, output_dir, remove_usearch_logs, wordlength,
                  usearch61_maxrejects, usearch61_maxaccepts, HALT_EXEC,
                  output_uc_filepath=join(
                      output_dir,
                      file_prefix + 'fast_clustered.uc'), threads=threads)
              if not save_intermediate_files:
                  files_to_remove.append(clusters_fp)
          else:
              clusters_fp, app_result =\
                  usearch61_smallmem_cluster(intermediate_fasta, percent_id,
                                             minlen, rev, output_dir, remove_usearch_logs, wordlength,
                                             usearch61_maxrejects, usearch61_maxaccepts, sizeorder, HALT_EXEC,
                                             output_uc_filepath=join(output_dir,
                                                                     file_prefix + 'smallmem_clustered.uc'))
              if not save_intermediate_files:
                  files_to_remove.append(clusters_fp)
  
      except ApplicationError:
          raise ApplicationError('Error running usearch61. Possible causes are '
                                 'unsupported version (current supported version is usearch ' +
                                 'v6.1.544) is installed or improperly formatted input file was ' +
                                 'provided')
  
      except ApplicationNotFoundError:
          remove_files(files_to_remove)
          raise ApplicationNotFoundError('usearch61 not found, is it properly ' +
                                         'installed?')
  
      if usearch61_sort_method == 'abundance' and not usearch_fast_cluster:
          de_novo_clusters, failures =\
              parse_usearch61_clusters(open(clusters_fp, "U"), otu_prefix)
          dereplicated_clusters =\
              parse_dereplicated_uc(open(dereplicated_uc, "U"))
          clusters = merge_clusters_dereplicated_seqs(de_novo_clusters,
                                                      dereplicated_clusters)
  
      else:
          clusters, failures =\
              parse_usearch61_clusters(open(clusters_fp, "U"), otu_prefix)
  
      if not save_intermediate_files:
          remove_files(files_to_remove)
  
      return clusters