Ejemplo n.º 1
0
# (i,id) + { (i,) then (i+1,) } + { list [list1, ...] }
# (i,) + { (i,) then (i+1,) } + { list [list1, ...] }
# (i,id) + { (i,) then (0,) } + { float list }
# (i,) + { (i,) then (0,) } + { float list }
# (i,id) + { (i,) then (0,) } + { list [list1, ...] }
# (i,) + { (i,) then (0,) } + { list [list1, ...] }
# NOTES:
#   Legend is different for list versus [list1,...]
#   Plot should be discontinuous for (i,) then (0,)

# parse file contents to get (i,id), cost, and parameters
from mystic.munge import logfile_reader, read_raw_file
try:
    step, param, cost = logfile_reader(filename)
except SyntaxError:
    read_raw_file(filename)
    msg = "incompatible file format, try 'support_convergence.py'"
    raise SyntaxError(msg)

# ignore everything after 'stop'
step = step[:stop]
cost = cost[:stop]
param = param[:stop]

# split (i,id) into iteration and id
multinode = len(step[0]) - 1  #XXX: what if step = []?
iter = [i[0] for i in step]
if multinode:
  id = [i[1] for i in step]
else:
  id = [0 for i in step]
Ejemplo n.º 2
0
def log_reader(filename, **kwds):
    """
plot parameter convergence from file written with 'LoggingMonitor'

Available from the command shell as:
  mystic_log_reader.py filename [options]

or as a function call as:
  mystic.log_reader(filename, **options)

The option "param" takes an indicator string. The indicator string is built
from comma-separated array slices. For example, params = ":" will plot all
parameters.  Alternatively, params = ":2, 3:" will plot all parameters except
for the third parameter, while params = "0" will only plot the first parameter.

Required Inputs:
  filename            name of the convergence logfile (e.g log.txt)
"""
    import shlex
    global __quit
    __quit = False

    instance = None
    # handle the special case where list is provided by sys.argv
    if isinstance(filename, (list, tuple)) and not kwds:
        cmdargs = filename  # (above is used by script to parse command line)
    elif isinstance(filename, basestring) and not kwds:
        cmdargs = shlex.split(filename)
    # 'everything else' is essentially the functional interface
    else:
        cmdargs = kwds.get('kwds', '')
        if not cmdargs:
            out = kwds.get('out', None)
            dots = kwds.get('dots', False)
            line = kwds.get('line', False)
            iter = kwds.get('iter', None)
            legend = kwds.get('legend', False)
            nid = kwds.get('nid', None)
            param = kwds.get('param', None)

            # process "commandline" arguments
            cmdargs = ''
            cmdargs += '' if out is None else '--out={} '.format(out)
            cmdargs += '' if dots == False else '--dots '
            cmdargs += '' if line == False else '--line '
            cmdargs += '' if iter is None else '--iter={} '.format(iter)
            cmdargs += '' if legend == False else '--legend '
            cmdargs += '' if nid is None else '--nid={} '.format(nid)
            cmdargs += '' if param is None else '--param="{}" '.format(param)
        else:
            cmdargs = ' ' + cmdargs
        if isinstance(filename, basestring):
            cmdargs = filename.split() + shlex.split(cmdargs)
        else:  # special case of passing in monitor instance
            instance = filename
            cmdargs = shlex.split(cmdargs)

    #XXX: note that 'argparse' is new as of python2.7
    from optparse import OptionParser

    def _exit(self, errno=None, msg=None):
        global __quit
        __quit = True
        if errno or msg:
            msg = msg.split(': error: ')[-1].strip()
            raise IOError(msg)

    OptionParser.exit = _exit

    parser = OptionParser(usage=log_reader.__doc__.split('\n\nOptions:')[0])
    parser.add_option("-u","--out",action="store",dest="out",\
                      metavar="STR",default=None,
                      help="filepath to save generated plot")
    parser.add_option("-d","--dots",action="store_true",dest="dots",\
                      default=False,help="show data points in plot")
    parser.add_option("-l","--line",action="store_true",dest="line",\
                      default=False,help="connect data points in plot with a line")
    parser.add_option("-i","--iter",action="store",dest="stop",metavar="INT",\
                      default=None,help="the largest iteration to plot")
    parser.add_option("-g","--legend",action="store_true",dest="legend",\
                      default=False,help="show the legend")
    parser.add_option("-n","--nid",action="store",dest="id",\
                      metavar="INT",default=None,
                      help="id # of the nth simultaneous points to plot")
    parser.add_option("-p","--param",action="store",dest="param",\
                      metavar="STR",default=":",
                      help="indicator string to select parameters")
    #parser.add_option("-f","--file",action="store",dest="filename",metavar="FILE",\
    #                  default='log.txt',help="log file name")

    #   import sys
    #   if 'mystic_log_reader.py' not in sys.argv:
    from StringIO import StringIO
    f = StringIO()
    parser.print_help(file=f)
    f.seek(0)
    if 'Options:' not in log_reader.__doc__:
        log_reader.__doc__ += '\nOptions:%s' % f.read().split('Options:')[-1]
    f.close()

    try:
        parsed_opts, parsed_args = parser.parse_args(cmdargs)
    except UnboundLocalError:
        pass
    if __quit: return

    style = '-'  # default linestyle
    if parsed_opts.dots:
        mark = 'o'
        # when using 'dots', also can turn off 'line'
        if not parsed_opts.line:
            style = 'None'
    else:
        mark = ''

    try:  # get logfile name
        if instance:
            filename = instance
        else:
            filename = parsed_args[0]
    except:
        raise IOError("please provide log file name")

    try:  # select which iteration to stop plotting at
        stop = int(parsed_opts.stop)
    except:
        stop = None

    try:  # select which 'id' to plot results for
        runs = (int(parsed_opts.id),
                )  #XXX: allow selecting more than one id ?
    except:
        runs = None  # i.e. 'all' **or** use id=0, which should be 'best' energy ?

    try:  # select which parameters to plot
        select = parsed_opts.param.split(',')  # format is ":2, 2:4, 5, 6:"
    except:
        select = [':']

    # ensure all terms of select have a ":"
    for i in range(len(select)):
        if isinstance(select[i], int): select[i] = str(select[i])
        if select[i] == '-1': select[i] = 'len(params)-1:len(params)'
        elif not select[i].count(':'):
            select[i] += ':' + str(int(select[i]) + 1)

    # == Possible results ==
    # iter = (i,id) or (i,)
    # split => { (i,) then (i+1,) } or { (i,) then (0,) }
    # y x = { float list } or { list [list1, ...] }

    # == Use Cases ==
    # (i,id) + { (i,) then (i+1,) } + { float list }
    # (i,) + { (i,) then (i+1,) } + { float list }
    # (i,id) + { (i,) then (i+1,) } + { list [list1, ...] }
    # (i,) + { (i,) then (i+1,) } + { list [list1, ...] }
    # (i,id) + { (i,) then (0,) } + { float list }
    # (i,) + { (i,) then (0,) } + { float list }
    # (i,id) + { (i,) then (0,) } + { list [list1, ...] }
    # (i,) + { (i,) then (0,) } + { list [list1, ...] }
    # NOTES:
    #   Legend is different for list versus [list1,...]
    #   Plot should be discontinuous for (i,) then (0,)

    # parse file contents to get (i,id), cost, and parameters
    try:
        instance = instance if instance else filename
        from mystic.munge import read_trajectories
        step, param, cost = read_trajectories(instance)
    except SyntaxError:
        from mystic.munge import read_raw_file
        read_raw_file(filename)
        msg = "incompatible file format, try 'support_convergence.py'"
        raise SyntaxError(msg)

    # ignore everything after 'stop'
    step = step[:stop]
    cost = cost[:stop]
    param = param[:stop]

    # split (i,id) into iteration and id
    multinode = len(step[0]) - 1  #XXX: what if step = []?
    iter = [i[0] for i in step]
    if multinode:
        id = [i[1] for i in step]
    else:
        id = [0 for i in step]

    # build the list of selected parameters
    params = range(len(param[0]))
    selected = []
    for i in select:
        selected.extend(eval("params[%s]" % i))
    selected = list(set(selected))

    results = [[] for i in range(max(id) + 1)]

    # populate results for each id with the corresponding (iter,cost,param)
    for i in range(len(id)):
        if runs is None or id[i] in runs:  # take only the selected 'id'
            results[id[i]].append((iter[i], cost[i], param[i]))
    # NOTE: for example...  results = [[(0,...)],[(0,...),(1,...)],[],[(0,...)]]

    # build list of parameter (and cost) convergences for each id
    conv = []
    cost_conv = []
    iter_conv = []
    for i in range(len(results)):
        conv.append([])  #; cost_conv.append([]); iter_conv.append([])
        if len(results[i]):
            for k in range(len(results[i][0][2])):
                conv[i].append(
                    [results[i][j][2][k] for j in range(len(results[i]))])
            cost_conv.append(
                [results[i][j][1] for j in range(len(results[i]))])
            iter_conv.append(
                [results[i][j][0] for j in range(len(results[i]))])
        else:
            conv[i] = [[] for k in range(len(param[0]))]
            cost_conv.append([])
            iter_conv.append([])

    #print "iter_conv = %s" % iter_conv
    #print "cost_conv = %s" % cost_conv
    #print "conv = %s" % conv

    import matplotlib.pyplot as plt
    fig = plt.figure()

    #FIXME: These may fail when conv[i][j] = [[],[],[]] and cost = []. Verify this.
    ax1 = fig.add_subplot(2, 1, 1)
    for i in range(len(conv)):
        if runs is None or i in runs:  # take only the selected 'id'
            for j in range(len(param[0])):
                if j in selected:  # take only the selected 'params'
                    tag = "%d,%d" % (j, i)  # label is 'parameter,id'
                    ax1.plot(iter_conv[i],
                             conv[i][j],
                             label="%s" % tag,
                             marker=mark,
                             linestyle=style)
    if parsed_opts.legend: plt.legend()

    ax2 = fig.add_subplot(2, 1, 2)
    for i in range(len(conv)):
        if runs is None or i in runs:  # take only the selected 'id'
            tag = "%d" % i  # label is 'cost id'
            ax2.plot(iter_conv[i],
                     cost_conv[i],
                     label='cost %s' % tag,
                     marker=mark,
                     linestyle=style)
    if parsed_opts.legend: plt.legend()

    if not parsed_opts.out:
        plt.show()
    else:
        fig.savefig(parsed_opts.out)
Ejemplo n.º 3
0
def log_reader(filename, **kwds):
    """
plot parameter convergence from file written with 'LoggingMonitor'

Available from the command shell as:
  mystic_log_reader.py filename [options]

or as a function call as:
  mystic.log_reader(filename, **options)

The option "param" takes an indicator string. The indicator string is built
from comma-separated array slices. For example, params = ":" will plot all
parameters.  Alternatively, params = ":2, 3:" will plot all parameters except
for the third parameter, while params = "0" will only plot the first parameter.

Required Inputs:
  filename            name of the convergence logfile (e.g log.txt)
"""
    import shlex
    try:
        basestring
        from StringIO import StringIO
    except NameError:
        basestring = str
        from io import StringIO
    global __quit
    __quit = False

    instance = None
    # handle the special case where list is provided by sys.argv
    if isinstance(filename, (list,tuple)) and not kwds:
        cmdargs = filename # (above is used by script to parse command line)
    elif isinstance(filename, basestring) and not kwds:
        cmdargs = shlex.split(filename)
    # 'everything else' is essentially the functional interface
    else:
        cmdargs = kwds.get('kwds', '')
        if not cmdargs:
            out = kwds.get('out', None)
            dots = kwds.get('dots', False)
            line = kwds.get('line', False)
            iter = kwds.get('iter', None)
            legend = kwds.get('legend', False)
            nid = kwds.get('nid', None)
            param = kwds.get('param', None)

            # process "commandline" arguments
            cmdargs = ''
            cmdargs += '' if out is None else '--out={} '.format(out)
            cmdargs += '' if dots == False else '--dots '
            cmdargs += '' if line == False else '--line '
            cmdargs += '' if iter is None else '--iter={} '.format(iter)
            cmdargs += '' if legend == False else '--legend '
            cmdargs += '' if nid is None else '--nid={} '.format(nid)
            cmdargs += '' if param is None else '--param="{}" '.format(param)
        else:
            cmdargs = ' ' + cmdargs
        if isinstance(filename, basestring):
            cmdargs = filename.split() + shlex.split(cmdargs)
        else: # special case of passing in monitor instance
            instance = filename
            cmdargs = shlex.split(cmdargs)

    #XXX: note that 'argparse' is new as of python2.7
    from optparse import OptionParser
    def _exit(self, errno=None, msg=None):
      global __quit
      __quit = True
      if errno or msg:
        msg = msg.split(': error: ')[-1].strip()
        raise IOError(msg)
    OptionParser.exit = _exit

    parser = OptionParser(usage=log_reader.__doc__.split('\n\nOptions:')[0])
    parser.add_option("-u","--out",action="store",dest="out",\
                      metavar="STR",default=None,
                      help="filepath to save generated plot")
    parser.add_option("-d","--dots",action="store_true",dest="dots",\
                      default=False,help="show data points in plot")
    parser.add_option("-l","--line",action="store_true",dest="line",\
                      default=False,help="connect data points in plot with a line")
    parser.add_option("-i","--iter",action="store",dest="stop",metavar="INT",\
                      default=None,help="the largest iteration to plot")
    parser.add_option("-g","--legend",action="store_true",dest="legend",\
                      default=False,help="show the legend")
    parser.add_option("-n","--nid",action="store",dest="id",\
                      metavar="INT",default=None,
                      help="id # of the nth simultaneous points to plot")
    parser.add_option("-p","--param",action="store",dest="param",\
                      metavar="STR",default=":",
                      help="indicator string to select parameters")
    #parser.add_option("-f","--file",action="store",dest="filename",metavar="FILE",\
    #                  default='log.txt',help="log file name")

#   import sys
#   if 'mystic_log_reader.py' not in sys.argv:
    if PY3:
      f = StringIO()
      parser.print_help(file=f)
      f.seek(0)
      if 'Options:' not in log_reader.__doc__:
        log_reader.__doc__ += '\nOptions:%s' % f.read().split('Options:')[-1]
      f.close()
    else:
      if 'Options:' not in log_reader.__doc__:
        log_reader.__doc__ += '\nOptions:%s' % parser.format_help().split('Options:')[-1]

    try:
      parsed_opts, parsed_args = parser.parse_args(cmdargs)
    except UnboundLocalError:
      pass
    if __quit: return

    style = '-' # default linestyle
    if parsed_opts.dots:
      mark = 'o'
      # when using 'dots', also can turn off 'line'
      if not parsed_opts.line:
        style = 'None'
    else:
      mark = ''

    try: # get logfile name
      if instance:
        filename = instance
      else:
        filename = parsed_args[0]
    except:
      raise IOError("please provide log file name")

    try: # select which iteration to stop plotting at
      stop = int(parsed_opts.stop)
    except:
      stop = None

    try: # select which 'id' to plot results for
      runs = (int(parsed_opts.id),) #XXX: allow selecting more than one id ?
    except:
      runs = None # i.e. 'all' **or** use id=0, which should be 'best' energy ?

    try: # select which parameters to plot
      select = parsed_opts.param.split(',')  # format is ":2, 2:4, 5, 6:"
    except:
      select = [':']

    # ensure all terms of select have a ":"
    for i in range(len(select)):
      if isinstance(select[i], int): select[i] = str(select[i])
      if select[i] == '-1': select[i] = 'len(params)-1:len(params)'
      elif not select[i].count(':'):
        select[i] += ':' + str(int(select[i])+1)


    # == Possible results ==
    # iter = (i,id) or (i,) 
    # split => { (i,) then (i+1,) } or { (i,) then (0,) }
    # y x = { float list } or { list [list1, ...] }

    # == Use Cases ==
    # (i,id) + { (i,) then (i+1,) } + { float list }
    # (i,) + { (i,) then (i+1,) } + { float list }
    # (i,id) + { (i,) then (i+1,) } + { list [list1, ...] }
    # (i,) + { (i,) then (i+1,) } + { list [list1, ...] }
    # (i,id) + { (i,) then (0,) } + { float list }
    # (i,) + { (i,) then (0,) } + { float list }
    # (i,id) + { (i,) then (0,) } + { list [list1, ...] }
    # (i,) + { (i,) then (0,) } + { list [list1, ...] }
    # NOTES:
    #   Legend is different for list versus [list1,...]
    #   Plot should be discontinuous for (i,) then (0,)

    # parse file contents to get (i,id), cost, and parameters
    try:
        instance = instance if instance else filename
        from mystic.munge import read_trajectories
        step, param, cost = read_trajectories(instance)
    except SyntaxError:
        from mystic.munge import read_raw_file
        read_raw_file(filename)
        msg = "incompatible file format, try 'support_convergence.py'"
        raise SyntaxError(msg)

    # ignore everything after 'stop'
    step = step[:stop]
    cost = cost[:stop]
    param = param[:stop]

    # split (i,id) into iteration and id
    multinode = len(step[0]) - 1  #XXX: what if step = []?
    iter = [i[0] for i in step]
    if multinode:
      id = [i[1] for i in step]
    else:
      id = [0 for i in step]

    # build the list of selected parameters
    params = list(range(len(param[0])))
    selected = []
    locals = dict(params=params)
    for i in select:
      selected.extend(eval("params[%s]" % i, locals))
    selected = list(set(selected))

    results = [[] for i in range(max(id) + 1)]

    # populate results for each id with the corresponding (iter,cost,param)
    for i in range(len(id)):
      if runs is None or id[i] in runs: # take only the selected 'id'
        results[id[i]].append((iter[i],cost[i],param[i]))
    # NOTE: for example...  results = [[(0,...)],[(0,...),(1,...)],[],[(0,...)]]

    # build list of parameter (and cost) convergences for each id
    conv = []; cost_conv = []; iter_conv = []
    for i in range(len(results)):
      conv.append([])#; cost_conv.append([]); iter_conv.append([])
      if len(results[i]):
        for k in range(len(results[i][0][2])):
          conv[i].append([results[i][j][2][k] for j in range(len(results[i]))])
        cost_conv.append([results[i][j][1] for j in range(len(results[i]))])
        iter_conv.append([results[i][j][0] for j in range(len(results[i]))])
      else:
        conv[i] = [[] for k in range(len(param[0]))]
        cost_conv.append([])
        iter_conv.append([])

    #print("iter_conv = %s" % iter_conv)
    #print("cost_conv = %s" % cost_conv)
    #print("conv = %s" % conv)

    import matplotlib.pyplot as plt
    fig = plt.figure()

    #FIXME: These may fail when conv[i][j] = [[],[],[]] and cost = []. Verify this.
    ax1 = fig.add_subplot(2,1,1)
    for i in range(len(conv)):
      if runs is None or i in runs: # take only the selected 'id'
        for j in range(len(param[0])):
          if j in selected: # take only the selected 'params'
            tag = "%d,%d" % (j,i) # label is 'parameter,id'
            ax1.plot(iter_conv[i],conv[i][j],label="%s" % tag,marker=mark,linestyle=style)
    if parsed_opts.legend: plt.legend()

    ax2 = fig.add_subplot(2,1,2)
    for i in range(len(conv)):
      if runs is None or i in runs: # take only the selected 'id'
        tag = "%d" % i # label is 'cost id'
        ax2.plot(iter_conv[i],cost_conv[i],label='cost %s' % tag,marker=mark,linestyle=style)
    if parsed_opts.legend: plt.legend()

    if not parsed_opts.out:
        plt.show()
    else:
        fig.savefig(parsed_opts.out)