docs: def kallisto(fastq, out_dir, cb_histogram, cb_cutoff):
      ''' Convert fastqtransformed file to output format compatible with
      kallisto.
      '''
      parser_re = re.compile('(.*):CELL_(?<CB>.*):UMI_(?P<UMI>.*)\\n(.*)\\n\\+\\n(.*)\\n')
      if fastq.endswith('gz'):
          fastq_fh = gzip.GzipFile(fileobj=open(fastq))
      elif fastq == "-":
          fastq_fh = sys.stdin
      else:
          fastq_fh = open(fastq)
  
      cb_depth_set = get_cb_depth_set(cb_histogram, cb_cutoff)
  
      cb_set = set()
      cb_batch = collections.defaultdict(list)
      parsed = 0
      for read in stream_fastq(fastq_fh):
          match = parser_re.search(read).groupdict()
          umi = match['UMI']
          cb = match['CB']
          if cb_depth_set and cb not in cb_depth_set:
              continue
          parsed += 1
          cb_set.add(cb)
          cb_batch[cb].append((read, umi))
          # write in batches to avoid opening up file handles repeatedly
          if not parsed % 10000000:
              for cb, chunk in cb_batch.items():
                  write_kallisto_chunk(out_dir, cb, chunk)
              cb_batch = collections.defaultdict(list)
  
      for cb, chunk in cb_batch.items():
          write_kallisto_chunk(out_dir, cb, chunk)
  
      with open(os.path.join(out_dir, "barcodes.batch"), "w") as out_handle:
          out_handle.write("#id umi-file file-1\n")
          batchformat = "{cb} {cb}.umi {cb}.fq\n"
          for cb in cb_set:
              out_handle.write(batchformat.format(**locals()))