plot_cmc.py 3.44 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
from __future__ import print_function

André Anjos's avatar
André Anjos committed
10 11 12
"""This script computes and plot a cumulative rank characteristics (CMC) curve
from a score file in four or five column format.

13 14
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
15 16
"""

17 18
import os
import sys
André Anjos's avatar
André Anjos committed
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 47 48

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
49

50 51
  from .. import load, plot, recognition_rate

André Anjos's avatar
André Anjos committed
52 53 54 55 56
  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 "(...)"
57
  data = {'4column' : load.cmc_four_column, '5column' : load.cmc_five_column}[args.parser](args.score_file)
André Anjos's avatar
André Anjos committed
58 59

  # compute recognition rate
60
  rr = recognition_rate(data)
André Anjos's avatar
André Anjos committed
61 62 63 64 65 66 67 68 69 70 71 72 73
  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()
74
    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
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
    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:])