Changeset 806


Ignore:
Timestamp:
07/17/15 08:25:07 (10 months ago)
Author:
mmckerns
Message:

enable function call for mystic_log_reader

Location:
mystic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • mystic/mystic/scripts.py

    r805 r806  
    66# License: 3-clause BSD.  The full license text is available at: 
    77#  - http://mmckerns.github.io/project/mystic/browser/mystic/LICENSE 
    8 __doc__ = \ 
    9 """ 
     8__doc__ = """ 
    109functional interfaces for mystic's visual analytics scripts 
    1110""" 
    1211 
    13 __all__ = ['model_plotter',] 
    14  
     12__all__ = ['model_plotter','log_reader'] 
    1513 
    1614from mpl_toolkits.mplot3d import axes3d 
     
    2018from mystic.munge import read_history 
    2119from mystic.munge import logfile_reader, raw_to_support 
     20 
     21# globals 
     22__quit = False 
     23 
    2224 
    2325#XXX: better if reads single id only? (e.g. same interface as read_history) 
     
    339341Additional Inputs: 
    340342  filename            name of the convergence logfile (e.g. log.txt) 
    341     """ 
     343""" 
    342344    #FIXME: should be able to: 
    343345    # - apply a constraint as a region of NaN -- apply when 'xx,yy=x[ij],y[ij]' 
     
    354356    #   (see support_hypercube.py for how to fix bounds) 
    355357    import shlex 
     358    global __quit 
     359    __quit = False 
    356360    _model = None 
    357361    _reducer = None 
     
    414418    #XXX: note that 'argparse' is new as of python2.7 
    415419    from optparse import OptionParser 
    416     parser = OptionParser(usage=model_plotter.__doc__) 
     420    def _exit(self, **kwds): 
     421      global __quit 
     422      __quit = True 
     423    OptionParser.exit = _exit 
     424 
     425    parser = OptionParser(usage=model_plotter.__doc__.split('\n\nOptions:')[0]) 
    417426    parser.add_option("-u","--out",action="store",dest="out",\ 
    418427                      metavar="STR",default=None, 
     
    449458    parsed_opts, parsed_args = parser.parse_args(cmdargs) 
    450459 
     460#   import sys 
     461#   if 'mystic_model_plotter.py' not in sys.argv: 
     462    from StringIO import StringIO 
     463    f = StringIO() 
     464    parser.print_help(file=f) 
     465    f.seek(0) 
     466    if 'Options:' not in model_plotter.__doc__: 
     467      model_plotter.__doc__ += '\nOptions:%s' % f.read().split('Options:')[-1] 
     468    f.close() 
     469 
     470    if __quit: return 
     471 
    451472    # get the import path for the model 
    452473    model = parsed_args[0]  # e.g. 'mystic.models.rosen' 
     
    625646 
    626647 
    627 if __name__=='__main__': 
     648def log_reader(filename, **kwds): 
     649    """ 
     650plot parameter convergence from file written with 'LoggingMonitor' 
     651 
     652Available from the command shell as: 
     653  mystic_log_reader.py filename [options] 
     654 
     655or as a function call as: 
     656  mystic.log_reader(filename, **options) 
     657 
     658The option "param" takes an indicator string. The indicator string is built 
     659from comma-separated array slices. For example, params = ":" will plot all 
     660parameters.  Alternatively, params = ":2, 3:" will plot all parameters except 
     661for the third parameter, while params = "0" will only plot the first parameter. 
     662 
     663Required Inputs: 
     664  filename            name of the convergence logfile (e.g log.txt) 
     665""" 
     666    import shlex 
     667    global __quit 
     668    __quit = False 
     669 
     670    # handle the special case where list is provided by sys.argv 
     671    if isinstance(filename, (list,tuple)) and not kwds: 
     672        cmdargs = filename # (above is used by script to parse command line) 
     673    elif isinstance(filename, basestring) and not kwds: 
     674        cmdargs = shlex.split(filename) 
     675    # 'everything else' is essentially the functional interface 
     676    else: 
     677        out = kwds.get('out', None) 
     678        dots = kwds.get('dots', False) 
     679        line = kwds.get('line', False) 
     680        iter = kwds.get('iter', None) 
     681        legend = kwds.get('legend', False) 
     682        nid = kwds.get('nid', None) 
     683        param = kwds.get('param', None) 
     684 
     685        # process "commandline" arguments 
     686        cmdargs = '' 
     687        cmdargs += '' if out is None else '--out={} '.format(out) 
     688        cmdargs += '' if dots == False else '--dots ' 
     689        cmdargs += '' if line == False else '--line ' 
     690        cmdargs += '' if iter is None else '--iter={} '.format(iter) 
     691        cmdargs += '' if legend == False else '--legend ' 
     692        cmdargs += '' if nid is None else '--nid={} '.format(nid) 
     693        cmdargs += '' if param is None else '--param="{}" '.format(param) 
     694        cmdargs = filename.split() + shlex.split(cmdargs) 
     695 
     696    #XXX: note that 'argparse' is new as of python2.7 
     697    from optparse import OptionParser 
     698    def _exit(self, **kwds): 
     699      global __quit 
     700      __quit = True 
     701    OptionParser.exit = _exit 
     702 
     703    parser = OptionParser(usage=log_reader.__doc__.split('\n\nOptions:')[0]) 
     704    parser.add_option("-u","--out",action="store",dest="out",\ 
     705                      metavar="STR",default=None, 
     706                      help="filepath to save generated plot") 
     707    parser.add_option("-d","--dots",action="store_true",dest="dots",\ 
     708                      default=False,help="show data points in plot") 
     709    parser.add_option("-l","--line",action="store_true",dest="line",\ 
     710                      default=False,help="connect data points in plot with a line") 
     711    parser.add_option("-i","--iter",action="store",dest="stop",metavar="INT",\ 
     712                      default=None,help="the largest iteration to plot") 
     713    parser.add_option("-g","--legend",action="store_true",dest="legend",\ 
     714                      default=False,help="show the legend") 
     715    parser.add_option("-n","--nid",action="store",dest="id",\ 
     716                      metavar="INT",default=None, 
     717                      help="id # of the nth simultaneous points to plot") 
     718    parser.add_option("-p","--param",action="store",dest="param",\ 
     719                      metavar="STR",default=":", 
     720                      help="indicator string to select parameters") 
     721    #parser.add_option("-f","--file",action="store",dest="filename",metavar="FILE",\ 
     722    #                  default='log.txt',help="log file name") 
     723    parsed_opts, parsed_args = parser.parse_args(cmdargs) 
     724 
     725#   import sys 
     726#   if 'mystic_log_reader.py' not in sys.argv: 
     727    from StringIO import StringIO 
     728    f = StringIO() 
     729    parser.print_help(file=f) 
     730    f.seek(0) 
     731    if 'Options:' not in log_reader.__doc__: 
     732      log_reader.__doc__ += '\nOptions:%s' % f.read().split('Options:')[-1] 
     733    f.close() 
     734 
     735    style = '-' # default linestyle 
     736    if parsed_opts.dots: 
     737      mark = 'o' 
     738      # when using 'dots', also can turn off 'line' 
     739      if not parsed_opts.line: 
     740        style = 'None' 
     741    else: 
     742      mark = '' 
     743 
     744    if __quit: return 
     745 
     746    try: # get logfile name 
     747      filename = parsed_args[0] 
     748    except: 
     749      raise IOError, "please provide log file name" 
     750 
     751    try: # select which iteration to stop plotting at 
     752      stop = int(parsed_opts.stop) 
     753    except: 
     754      stop = None 
     755 
     756    try: # select which 'id' to plot results for 
     757      runs = (int(parsed_opts.id),) #XXX: allow selecting more than one id ? 
     758    except: 
     759      runs = None # i.e. 'all' **or** use id=0, which should be 'best' energy ? 
     760 
     761    try: # select which parameters to plot 
     762      select = parsed_opts.param.split(',')  # format is ":2, 2:4, 5, 6:" 
     763    except: 
     764      select = [':'] 
     765 
     766    # ensure all terms of select have a ":" 
     767    for i in range(len(select)): 
     768      if isinstance(select[i], int): select[i] = str(select[i]) 
     769      if select[i] == '-1': select[i] = 'len(params)-1:len(params)' 
     770      elif not select[i].count(':'): 
     771        select[i] += ':' + str(int(select[i])+1) 
     772 
     773 
     774    # == Possible results == 
     775    # iter = (i,id) or (i,)  
     776    # split => { (i,) then (i+1,) } or { (i,) then (0,) } 
     777    # y x = { float list } or { list [list1, ...] } 
     778 
     779    # == Use Cases == 
     780    # (i,id) + { (i,) then (i+1,) } + { float list } 
     781    # (i,) + { (i,) then (i+1,) } + { float list } 
     782    # (i,id) + { (i,) then (i+1,) } + { list [list1, ...] } 
     783    # (i,) + { (i,) then (i+1,) } + { list [list1, ...] } 
     784    # (i,id) + { (i,) then (0,) } + { float list } 
     785    # (i,) + { (i,) then (0,) } + { float list } 
     786    # (i,id) + { (i,) then (0,) } + { list [list1, ...] } 
     787    # (i,) + { (i,) then (0,) } + { list [list1, ...] } 
     788    # NOTES: 
     789    #   Legend is different for list versus [list1,...] 
     790    #   Plot should be discontinuous for (i,) then (0,) 
     791 
     792    # parse file contents to get (i,id), cost, and parameters 
     793    from mystic.munge import logfile_reader, read_raw_file 
     794    try: 
     795        step, param, cost = logfile_reader(filename) 
     796    except SyntaxError: 
     797        read_raw_file(filename) 
     798        msg = "incompatible file format, try 'support_convergence.py'" 
     799        raise SyntaxError(msg) 
     800 
     801    # ignore everything after 'stop' 
     802    step = step[:stop] 
     803    cost = cost[:stop] 
     804    param = param[:stop] 
     805 
     806    # split (i,id) into iteration and id 
     807    multinode = len(step[0]) - 1  #XXX: what if step = []? 
     808    iter = [i[0] for i in step] 
     809    if multinode: 
     810      id = [i[1] for i in step] 
     811    else: 
     812      id = [0 for i in step] 
     813 
     814    # build the list of selected parameters 
     815    params = range(len(param[0])) 
     816    selected = [] 
     817    for i in select: 
     818      selected.extend(eval("params[%s]" % i)) 
     819    selected = list(set(selected)) 
     820 
     821    results = [[] for i in range(max(id) + 1)] 
     822 
     823    # populate results for each id with the corresponding (iter,cost,param) 
     824    for i in range(len(id)): 
     825      if runs is None or id[i] in runs: # take only the selected 'id' 
     826        results[id[i]].append((iter[i],cost[i],param[i])) 
     827    # NOTE: for example...  results = [[(0,...)],[(0,...),(1,...)],[],[(0,...)]] 
     828 
     829    # build list of parameter (and cost) convergences for each id 
     830    conv = []; cost_conv = []; iter_conv = [] 
     831    for i in range(len(results)): 
     832      conv.append([])#; cost_conv.append([]); iter_conv.append([]) 
     833      if len(results[i]): 
     834        for k in range(len(results[i][0][2])): 
     835          conv[i].append([results[i][j][2][k] for j in range(len(results[i]))]) 
     836        cost_conv.append([results[i][j][1] for j in range(len(results[i]))]) 
     837        iter_conv.append([results[i][j][0] for j in range(len(results[i]))]) 
     838      else: 
     839        conv[i] = [[] for k in range(len(param[0]))] 
     840        cost_conv.append([]) 
     841        iter_conv.append([]) 
     842 
     843    #print "iter_conv = %s" % iter_conv 
     844    #print "cost_conv = %s" % cost_conv 
     845    #print "conv = %s" % conv 
     846 
     847    import matplotlib.pyplot as plt 
     848 
     849    fig = plt.figure() 
     850 
     851    #FIXME: These may fail when conv[i][j] = [[],[],[]] and cost = []. Verify this. 
     852    ax1 = fig.add_subplot(2,1,1) 
     853    for i in range(len(conv)): 
     854      if runs is None or i in runs: # take only the selected 'id' 
     855        for j in range(len(param[0])): 
     856          if j in selected: # take only the selected 'params' 
     857            tag = "%d,%d" % (j,i) # label is 'parameter,id' 
     858            ax1.plot(iter_conv[i],conv[i][j],label="%s" % tag,marker=mark,linestyle=style) 
     859    if parsed_opts.legend: plt.legend() 
     860 
     861    ax2 = fig.add_subplot(2,1,2) 
     862    for i in range(len(conv)): 
     863      if runs is None or i in runs: # take only the selected 'id' 
     864        tag = "%d" % i # label is 'cost id' 
     865        ax2.plot(iter_conv[i],cost_conv[i],label='cost %s' % tag,marker=mark,linestyle=style) 
     866    if parsed_opts.legend: plt.legend() 
     867 
     868    if not parsed_opts.out: 
     869        plt.show() 
     870    else: 
     871        fig.savefig(parsed_opts.out) 
     872 
     873 
     874# initialize doc 
     875try: log_reader() 
     876except TypeError: 
    628877    pass 
    629  
    630 # End of file 
     878try: model_plotter() 
     879except TypeError: 
     880    pass 
     881 
     882 
     883 
     884if __name__ == '__main__': 
     885    pass 
     886 
     887 
     888# EOF 
  • mystic/scripts/mystic_log_reader.py

    r792 r806  
    66#  - http://mmckerns.github.io/project/mystic/browser/mystic/LICENSE 
    77 
    8 __doc__ = """ 
    9 mystic_log_reader.py [options] filename 
     8from mystic import log_reader 
    109 
    11 plot parameter convergence from file written with 'LoggingMonitor' 
     10__doc__ = log_reader.__doc__ 
    1211 
    13 The option "param" takes an indicator string. The indicator string is built 
    14 from comma-separated array slices. For example, params = ":" will plot all 
    15 parameters.  Alternatively, params = ":2, 3:" will plot all parameters except 
    16 for the third parameter, while params = "0" will only plot the first parameter. 
     12if __name__ == '__main__': 
    1713 
    18 Required Inputs: 
    19   filename            name of the convergence logfile (e.g log.txt) 
    20 """ 
     14    import sys 
    2115 
    22 #XXX: note that 'argparse' is new as of python2.7 
    23 from optparse import OptionParser 
    24 parser = OptionParser(usage=__doc__) 
    25 parser.add_option("-d","--dots",action="store_true",dest="dots",\ 
    26                   default=False,help="show data points in plot") 
    27 parser.add_option("-l","--line",action="store_true",dest="line",\ 
    28                   default=False,help="connect data points in plot with a line") 
    29 parser.add_option("-i","--iter",action="store",dest="stop",metavar="INT",\ 
    30                   default=None,help="the largest iteration to plot") 
    31 parser.add_option("-g","--legend",action="store_true",dest="legend",\ 
    32                   default=False,help="show the legend") 
    33 parser.add_option("-n","--nid",action="store",dest="id",\ 
    34                   metavar="INT",default=None, 
    35                   help="id # of the nth simultaneous points to plot") 
    36 parser.add_option("-p","--param",action="store",dest="param",\ 
    37                   metavar="STR",default=":", 
    38                   help="indicator string to select parameters") 
    39 #parser.add_option("-f","--file",action="store",dest="filename",metavar="FILE",\ 
    40 #                  default='log.txt',help="log file name") 
    41 parsed_opts, parsed_args = parser.parse_args() 
     16    log_reader(sys.argv[1:]) 
    4217 
    4318 
    44 style = '-' # default linestyle 
    45 if parsed_opts.dots: 
    46   mark = 'o' 
    47   # when using 'dots', also can turn off 'line' 
    48   if not parsed_opts.line: 
    49     style = 'None' 
    50 else: 
    51   mark = '' 
    52  
    53 try: # get logfile name 
    54   filename = parsed_args[0] 
    55 except: 
    56   raise IOError, "please provide log file name" 
    57  
    58 try: # select which iteration to stop plotting at 
    59   stop = int(parsed_opts.stop) 
    60 except: 
    61   stop = None 
    62  
    63 try: # select which 'id' to plot results for 
    64   runs = (int(parsed_opts.id),) #XXX: allow selecting more than one id ? 
    65 except: 
    66   runs = None # i.e. 'all' **or** use id=0, which should be 'best' energy ? 
    67  
    68 try: # select which parameters to plot 
    69   select = parsed_opts.param.split(',')  # format is ":2, 2:4, 5, 6:" 
    70 except: 
    71   select = [':'] 
    72  
    73 # ensure all terms of select have a ":" 
    74 for i in range(len(select)): 
    75   if isinstance(select[i], int): select[i] = str(select[i]) 
    76   if select[i] == '-1': select[i] = 'len(params)-1:len(params)' 
    77   elif not select[i].count(':'): 
    78     select[i] += ':' + str(int(select[i])+1) 
    79  
    80  
    81 # == Possible results == 
    82 # iter = (i,id) or (i,)  
    83 # split => { (i,) then (i+1,) } or { (i,) then (0,) } 
    84 # y x = { float list } or { list [list1, ...] } 
    85  
    86 # == Use Cases == 
    87 # (i,id) + { (i,) then (i+1,) } + { float list } 
    88 # (i,) + { (i,) then (i+1,) } + { float list } 
    89 # (i,id) + { (i,) then (i+1,) } + { list [list1, ...] } 
    90 # (i,) + { (i,) then (i+1,) } + { list [list1, ...] } 
    91 # (i,id) + { (i,) then (0,) } + { float list } 
    92 # (i,) + { (i,) then (0,) } + { float list } 
    93 # (i,id) + { (i,) then (0,) } + { list [list1, ...] } 
    94 # (i,) + { (i,) then (0,) } + { list [list1, ...] } 
    95 # NOTES: 
    96 #   Legend is different for list versus [list1,...] 
    97 #   Plot should be discontinuous for (i,) then (0,) 
    98  
    99 # parse file contents to get (i,id), cost, and parameters 
    100 from mystic.munge import logfile_reader, read_raw_file 
    101 try: 
    102     step, param, cost = logfile_reader(filename) 
    103 except SyntaxError: 
    104     read_raw_file(filename) 
    105     msg = "incompatible file format, try 'support_convergence.py'" 
    106     raise SyntaxError(msg) 
    107  
    108 # ignore everything after 'stop' 
    109 step = step[:stop] 
    110 cost = cost[:stop] 
    111 param = param[:stop] 
    112  
    113 # split (i,id) into iteration and id 
    114 multinode = len(step[0]) - 1  #XXX: what if step = []? 
    115 iter = [i[0] for i in step] 
    116 if multinode: 
    117   id = [i[1] for i in step] 
    118 else: 
    119   id = [0 for i in step] 
    120  
    121 # build the list of selected parameters 
    122 params = range(len(param[0])) 
    123 selected = [] 
    124 for i in select: 
    125   selected.extend(eval("params[%s]" % i)) 
    126 selected = list(set(selected)) 
    127  
    128 results = [[] for i in range(max(id) + 1)] 
    129  
    130 # populate results for each id with the corresponding (iter,cost,param) 
    131 for i in range(len(id)): 
    132   if runs is None or id[i] in runs: # take only the selected 'id' 
    133     results[id[i]].append((iter[i],cost[i],param[i])) 
    134 # NOTE: for example...  results = [[(0,...)],[(0,...),(1,...)],[],[(0,...)]] 
    135  
    136 # build list of parameter (and cost) convergences for each id 
    137 conv = []; cost_conv = []; iter_conv = [] 
    138 for i in range(len(results)): 
    139   conv.append([])#; cost_conv.append([]); iter_conv.append([]) 
    140   if len(results[i]): 
    141     for k in range(len(results[i][0][2])): 
    142       conv[i].append([results[i][j][2][k] for j in range(len(results[i]))]) 
    143     cost_conv.append([results[i][j][1] for j in range(len(results[i]))]) 
    144     iter_conv.append([results[i][j][0] for j in range(len(results[i]))]) 
    145   else: 
    146     conv[i] = [[] for k in range(len(param[0]))] 
    147     cost_conv.append([]) 
    148     iter_conv.append([]) 
    149  
    150 #print "iter_conv = %s" % iter_conv 
    151 #print "cost_conv = %s" % cost_conv 
    152 #print "conv = %s" % conv 
    153  
    154 import matplotlib.pyplot as plt 
    155  
    156 fig = plt.figure() 
    157  
    158 #FIXME: These may fail when conv[i][j] = [[],[],[]] and cost = []. Verify this. 
    159 ax1 = fig.add_subplot(2,1,1) 
    160 for i in range(len(conv)): 
    161   if runs is None or i in runs: # take only the selected 'id' 
    162     for j in range(len(param[0])): 
    163       if j in selected: # take only the selected 'params' 
    164         tag = "%d,%d" % (j,i) # label is 'parameter,id' 
    165         ax1.plot(iter_conv[i],conv[i][j],label="%s" % tag,marker=mark,linestyle=style) 
    166 if parsed_opts.legend: plt.legend() 
    167  
    168 ax2 = fig.add_subplot(2,1,2) 
    169 for i in range(len(conv)): 
    170   if runs is None or i in runs: # take only the selected 'id' 
    171     tag = "%d" % i # label is 'cost id' 
    172     ax2.plot(iter_conv[i],cost_conv[i],label='cost %s' % tag,marker=mark,linestyle=style) 
    173 if parsed_opts.legend: plt.legend() 
    174  
    175 plt.show() 
     19# EOF 
Note: See TracChangeset for help on using the changeset viewer.