code: def parse_kraken_report(kdata, max_rank, min_rank):
      
      # map between NCBI taxonomy IDs and the string rep. of the hierarchy
      taxa = OrderedDict()
      # the master collection of read counts (keyed on NCBI ID)
      counts = OrderedDict()
      # current rank
      r = 0
      max_rank_idx = ranks.index(max_rank)
      min_rank_idx = ranks.index(min_rank)
  
      for entry in kdata:
          erank = entry['rank'].strip()
          # print("erank: "+erank)
  
          if erank in ranks:
              r = ranks.index(erank)
          
          # update running tally of ranks
          tax_lvl = parse_tax_lvl(entry)
  
          # record the reads assigned to this taxon level, and record the taxonomy string with the NCBI ID
          if erank in ranks and min_rank_idx >= ranks.index(entry['rank']) >= max_rank_idx:
              taxon_reads = int(entry["taxon_reads"])
              clade_reads = int(entry["clade_reads"])
              if taxon_reads > 0 or (clade_reads > 0 and entry['rank'] == min_rank):
                  taxa[entry['ncbi_tax']] = tax_fmt(tax_lvl, r)
                  if entry['rank'] == min_rank:
                      counts[entry['ncbi_tax']] = clade_reads
                  else:
                      counts[entry['ncbi_tax']] = taxon_reads
                  # print("  Counting {} reads at {}".format(counts[entry['ncbi_tax']], '; '.join(taxa[entry['ncbi_tax']])))
          
  
          #TODO: handle subspecies
          #if erank == '-' and min_rank == "SS" and last_entry_indent < curr_indent:
          #    pass
      return counts, taxa
docs: Parse a single output file from the kraken-report tool. Return a list
      of counts at each of the acceptable taxonomic levels, and a list of 
      NCBI IDs and a formatted string representing their taxonomic hierarchies.
  
      :type kdata: str
      :param kdata: Contents of the kraken report file.