plot_cmc.py 3.4 KB
Newer Older
André Anjos's avatar
André Anjos committed
1 2 3 4 5
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Manuel Guenther <manuel.guenther@idiap.ch>
# Tue Jan  8 13:36:12 CET 2013
#
André Anjos's avatar
André Anjos committed
6
# Copyright (C) 2011-2014 Idiap Research Institute, Martigny, Switzerland
André Anjos's avatar
André Anjos committed
7 8 9 10

"""This script computes and plot a cumulative rank characteristics (CMC) curve
from a score file in four or five column format.

11 12
Note: The score file has to contain the exact probe file names as the 3rd
(4column) or 4th (5column) column.
André Anjos's avatar
André Anjos committed
13 14
"""

15 16
import os
import sys
André Anjos's avatar
André Anjos committed
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

def parse_command_line(command_line_options):
  """Parse the program options"""

  usage = 'usage: %s [arguments]' % os.path.basename(sys.argv[0])

  import argparse
  parser = argparse.ArgumentParser(usage=usage, description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter)

  # This option is not normally shown to the user...
  parser.add_argument('--self-test', action = 'store_true', help = argparse.SUPPRESS)
  parser.add_argument('-s', '--score-file', required = True, help = 'The score file in 4 or 5 column format to test.')
  parser.add_argument('-o', '--output-pdf-file', default = 'cmc.pdf', help = 'The PDF file to write.')
  parser.add_argument('-l', '--log-x-scale', action='store_true', help = 'Plot logarithmic Rank axis.')
  parser.add_argument('-x', '--no-plot', action = 'store_true', help = 'Do not print a PDF file, but only report the results.')
  parser.add_argument('-p', '--parser', default = '4column', choices = ('4column', '5column'), help = 'The type of the score file.')

  args = parser.parse_args(command_line_options)

  if args.self_test:
    # then we go into test mode, all input is preset
    import tempfile
    temp_dir = tempfile.mkdtemp(prefix="bobtest_")
    args.output_pdf_file = os.path.join(temp_dir, "cmc.pdf")
    print("temporary using file", args.output_pdf_file)

  return args

def main(command_line_options = None):
  """Computes and plots the CMC curve."""
André Anjos's avatar
André Anjos committed
47

48 49
  from .. import load, plot, recognition_rate

André Anjos's avatar
André Anjos committed
50 51 52 53 54
  args = parse_command_line(command_line_options)

  # read data
  if not os.path.isfile(args.score_file): raise IOError("The given score file does not exist")
  # pythonic way: create inline dictionary "{...}", index with desired value "[...]", execute function "(...)"
55
  data = {'4column' : load.cmc_four_column, '5column' : load.cmc_five_column}[args.parser](args.score_file)
André Anjos's avatar
André Anjos committed
56 57

  # compute recognition rate
58
  rr = recognition_rate(data)
André Anjos's avatar
André Anjos committed
59 60 61 62 63 64 65 66 67 68 69 70 71
  print("Recognition rate for score file", args.score_file, "is %3.2f%%" % (rr * 100))

  if not args.no_plot:
    # compute CMC
    import matplotlib
    if not hasattr(matplotlib, 'backends'): matplotlib.use('pdf')
    import matplotlib.pyplot as mpl
    from matplotlib.backends.backend_pdf import PdfPages

    pp = PdfPages(args.output_pdf_file)

    # CMC
    fig = mpl.figure()
72
    max_rank = plot.cmc(data, color=(0,0,1), linestyle='--', dashes=(6,2), logx = args.log_x_scale)
André Anjos's avatar
André Anjos committed
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
    mpl.title("CMC Curve")
    if args.log_x_scale:
      mpl.xlabel('Rank (log)')
    else:
      mpl.xlabel('Rank')
    mpl.ylabel('Recognition Rate in %')
    mpl.grid(True, color=(0.3,0.3,0.3))
    mpl.ylim(ymax=101)
    # convert log-scale ticks to normal numbers
    ticks = [int(t) for t in mpl.xticks()[0]]
    mpl.xticks(ticks, ticks)
    mpl.xlim([0.9, max_rank + 0.1])

    pp.savefig(fig)
    pp.close()

  if args.self_test: #remove output file + tmp directory
    import shutil
    shutil.rmtree(os.path.dirname(args.output_pdf_file))

  return 0

if __name__ == '__main__':
  main(sys.argv[1:])