def get_history(source, ids=None): """get params and cost from the given source source is the name of the trajectory logfile (or solver instance) if provided, ids are the list of 'run ids' to select """ try: # if it's a logfile, it might be multi-id step, param, cost = logfile_reader(source) except: # it's not a logfile, so read and return param, cost = read_history(source) return [param], [cost] # split (i,id) into iteration and id multinode = len(step[0]) - 1 #XXX: what if step = []? if multinode: id = [i[1] for i in step] else: id = [0 for i in step] params = [[] for i in range(max(id) + 1)] costs = [[] for i in range(len(params))] # populate params for each id with the corresponding (param,cost) for i in range(len(id)): if ids is None or id[i] in ids: # take only the selected 'id' params[id[i]].append(param[i]) costs[id[i]].append(cost[i]) params = [r for r in params if len(r)] # only keep selected 'ids' costs = [r for r in costs if len(r)] # only keep selected 'ids' # convert to support format for i in range(len(params)): params[i], costs[i] = raw_to_support(params[i], costs[i]) return params, costs
def get_history(source, ids=None): """get params and cost from the given source source is the name of the trajectory logfile (or solver instance) if provided, ids are the list of 'run ids' to select """ try: # if it's a logfile, it might be multi-id step, param, cost = logfile_reader(source) except: # it's not a logfile, so read and return param, cost = read_history(source) return [param],[cost] # split (i,id) into iteration and id multinode = len(step[0]) - 1 #XXX: what if step = []? if multinode: id = [i[1] for i in step] else: id = [0 for i in step] params = [[] for i in range(max(id) + 1)] costs = [[] for i in range(len(params))] # populate params for each id with the corresponding (param,cost) for i in range(len(id)): if ids is None or id[i] in ids: # take only the selected 'id' params[id[i]].append(param[i]) costs[id[i]].append(cost[i]) params = [r for r in params if len(r)] # only keep selected 'ids' costs = [r for r in costs if len(r)] # only keep selected 'ids' # convert to support format for i in range(len(params)): params[i], costs[i] = raw_to_support(params[i], costs[i]) return params, costs
parser.add_option("-s","--scale",action="store",dest="scale",\ metavar="INT",default=1.0, help="grayscale contrast multiplier for points in plot") parser.add_option("-f","--flat",action="store_true",dest="flatten",\ default=False,help="show selected iterations in a single plot") parsed_opts, parsed_args = parser.parse_args() try: # get the name of the parameter log file file = parsed_args[0] import re file = re.sub('\.py*.$', '', file) #XXX: strip off .py* extension except: raise IOError, "please provide log file name" try: # read standard logfile from mystic.munge import logfile_reader, raw_to_support _step, params, _cost = logfile_reader(file) params, _cost = raw_to_support(params, _cost) except: exec "from %s import params" % file #exec "from %s import meta" % file # would be nice to use meta = ['wx','wx2','x','x2','wy',...] try: # select the bounds bounds = eval(parsed_opts.bounds) # format is "[(60,105),(0,30),(2.1,2.8)]" except: bounds = [(0,1),(0,1),(0,1)] try: # select which params are along which axes xyz = eval(parsed_opts.xyz) # format is "[(0,1),(4,5),(8,9)]" except: xyz = [(0,),(1,),(2,)]
# (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 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]
default=False,help="plot cones, if provided") parser.add_option("-z","--vertical",action="store_true",dest="vertical",\ default=False,help="always plot values on vertical axis") parser.add_option("-f","--flat",action="store_true",dest="flatten",\ default=False,help="show selected iterations in a single plot") parsed_opts, parsed_args = parser.parse_args() try: # get the name of the parameter log file file = parsed_args[0] import re file = re.sub('\.py*.$', '', file) #XXX: strip off .py* extension except: raise IOError, "please provide log file name" try: # read standard logfile from mystic.munge import logfile_reader, raw_to_support _step, params, _cost = logfile_reader(file) params, _cost = raw_to_support(params, _cost) except: exec "from %s import params" % file #exec "from %s import meta" % file # would be nice to use meta = ['wx','wx2','x','x2','wy',...] from mystic.math.discrete import scenario from mystic.math.legacydata import dataset try: # select whether to plot the cones cones = parsed_opts.cones except: cones = False try: # select whether to plot the legacy data legacy = parsed_opts.legacy
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 # 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: 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) cmdargs = filename.split() + shlex.split(cmdargs) #XXX: note that 'argparse' is new as of python2.7 from optparse import OptionParser def _exit(self, **kwds): global __quit __quit = True 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") parsed_opts, parsed_args = parser.parse_args(cmdargs) # 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() 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 = '' if __quit: return try: # get logfile name 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 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] # 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)