Changeset 747


Ignore:
Timestamp:
08/11/14 17:58:45 (22 months ago)
Author:
mmckerns
Message:

support multi-id logfiles in model_plotter; allow: no model, stop iter, pick id

Location:
mystic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • mystic/mystic/munge.py

    r742 r747  
    3030    elif isinstance(source, Null): 
    3131        return [],[] #XXX: or source.x, source.y (e.g. Null(),Null())? or Error? 
    32     else: #XXX: what about taking a logfile instance? 
     32    else: 
    3333        raise IOError("a history filename or instance is required") 
    3434    try:  # read standard logfile (or monitor) 
     
    4343            except: #KeyError 
    4444                _step, params, cost = logfile_reader(source) 
     45                #FIXME: doesn't work for multi-id logfile; select id? 
    4546        params, cost = raw_to_support(params, cost) 
    4647    except: 
  • mystic/scripts/mystic_model_plotter.py

    r746 r747  
    1010 
    1111generate surface contour plots for model, specified by full import path 
    12 generate model trajectory from logfile, if provided 
     12generate model trajectory from logfile (or solver restart file), if provided 
    1313 
    1414The option "bounds" takes an indicator string, where the bounds should 
     
    4949 
    5050from mystic.munge import read_history 
     51from mystic.munge import logfile_reader, raw_to_support 
     52 
     53#XXX: better if reads single id only? (e.g. same interface as read_history) 
     54def get_history(source, ids=None): 
     55    """get params and cost from the given source 
     56 
     57source is the name of the trajectory logfile (or solver instance) 
     58if provided, ids are the list of 'run ids' to select 
     59    """ 
     60    try: # if it's a logfile, it might be multi-id 
     61        step, param, cost = logfile_reader(source) 
     62    except: # it's not a logfile, so read and return 
     63        param, cost = read_history(source) 
     64        return [param],[cost] 
     65 
     66    # split (i,id) into iteration and id 
     67    multinode = len(step[0]) - 1  #XXX: what if step = []? 
     68    if multinode: id = [i[1] for i in step] 
     69    else: id = [0 for i in step] 
     70 
     71    params = [[] for i in range(max(id) + 1)] 
     72    costs = [[] for i in range(len(params))] 
     73    # populate params for each id with the corresponding (param,cost) 
     74    for i in range(len(id)): 
     75        if ids is None or id[i] in ids: # take only the selected 'id' 
     76            params[id[i]].append(param[i]) 
     77            costs[id[i]].append(cost[i]) 
     78    params = [r for r in params if len(r)] # only keep selected 'ids' 
     79    costs = [r for r in costs if len(r)] # only keep selected 'ids' 
     80 
     81    # convert to support format 
     82    for i in range(len(params)): 
     83        params[i], costs[i] = raw_to_support(params[i], costs[i]) 
     84    return params, costs 
     85 
    5186 
    5287def get_instance(location, *args, **kwds): 
     
    138173 
    139174 
    140 def draw_projection(file, select=0, scale=True, shift=False, style=None, figure=None): 
     175def draw_projection(x, cost, scale=True, shift=False, style=None, figure=None): 
    141176    """draw a solution trajectory (for overlay on a 1D plot) 
    142177 
    143 file is monitor or logfile of solution trajectories 
    144 select is the parameter index (e.g. 0 -> param[0]) selected for plotting 
     178x is the sequence of values for one parameter (i.e. a parameter trajectory) 
     179cost is the sequence of costs (i.e. the solution trajectory) 
    145180if scale is provided, scale the intensity as 'z = log(4*z*scale+1)+2' 
    146181if shift is provided, shift the intensity as 'z = z+shift' (useful for -z's) 
     
    148183if figure is provided, plot to an existing figure 
    149184    """ 
    150     # params are the parameter trajectories 
    151     # cost is the solution trajectory 
    152     params, cost = read_history(file) 
    153     d = {'x':0, 'y':1, 'z':2} #XXX: remove the easter egg? 
    154     if select in d: select = d[select] 
    155     x = params[int(select)] # requires one parameter 
    156  
    157185    if not figure: figure = plt.figure() 
    158186    ax = figure.gca() 
     
    175203 
    176204 
    177 def draw_trajectory(file, select=None, surface=False, scale=True, shift=False, style=None, figure=None): 
     205def draw_trajectory(x, y, cost=None, scale=True, shift=False, style=None, figure=None): 
    178206    """draw a solution trajectory (for overlay on a contour plot) 
    179207 
    180 file is monitor or logfile of solution trajectories 
    181 select is a len-2 list of parameter indicies (e.g. 0,1 -> param[0],param[1]) 
    182 if surface is True, plot the trajectories as a 3D projection 
     208x is a sequence of values for one parameter (i.e. a parameter trajectory) 
     209y is a sequence of values for one parameter (i.e. a parameter trajectory) 
     210cost is the solution trajectory (i.e. costs); if provided, plot a 3D contour 
    183211if scale is provided, scale the intensity as 'z = log(4*z*scale+1)+2' 
    184212if shift is provided, shift the intensity as 'z = z+shift' (useful for -z's) 
     
    186214if figure is provided, plot to an existing figure 
    187215    """ 
    188     # params are the parameter trajectories 
    189     # cost is the solution trajectory 
    190     params, cost = read_history(file) 
    191     if select is None: select = (0,1) 
    192     d = {'x':0, 'y':1, 'z':2} #XXX: remove the easter egg? 
    193     for ind,val in enumerate(select): 
    194         if val in d: select[ind] = d[val] 
    195     params = [params[int(i)] for i in select[:2]] 
    196     #XXX: take 'params,cost=None' instead of 'file,surface=False'? 
    197     x,y = params # requires two parameters 
    198  
    199216    if not figure: figure = plt.figure() 
    200217     
    201     if surface: kwds = {'projection':'3d'} # 3D 
    202     elif surface is None: # 1D 
    203         raise NotImplementedError('need to add an option string parser') 
    204     else: kwds = {}                        # 2D 
     218    if cost: kwds = {'projection':'3d'} # 3D 
     219    else: kwds = {}                     # 2D 
    205220    ax = figure.gca(**kwds) 
    206221 
    207222    if style in [None, False]: 
    208223        style = 'w-o' #if not scale else 'k-o' 
    209     if surface: # is 3D, cost is needed 
     224    if cost: # is 3D, cost is needed 
    210225        import numpy 
    211226        if shift:  
     
    311326 
    312327if __name__ == '__main__': 
    313    #FIXME: for a script, need to:  
    314    # - enable 'skip' plotting points (points or line or both)? 
    315328   #FIXME: should be able to: 
    316329   # - apply a constraint as a region of NaN -- apply when 'xx,yy=x[ij],y[ij]' 
    317330   # - apply a penalty by shifting the surface (plot w/alpha?) -- as above 
    318    # - read logfile with multiple trajectories (i.e. parallel batch) 
    319331   # - build an appropriately-sized default grid (from logfile info) 
     332   # - move all mulit-id param/cost reading into read_history 
    320333   #FIXME: current issues: 
    321334   # - 1D slice and projection work for 2D function, but aren't "pretty" 
    322    # - 1D slice and projection for 1D function needs further testing... 
     335   # - 1D slice and projection for 1D function, is it meaningful and correct? 
    323336   # - should be able to plot from solver.genealogy (multi-monitor?) [1D,2D,3D?] 
    324337   # - should be able to scale 'z-axis' instead of scaling 'z' itself 
    325338   #   (see https://github.com/matplotlib/matplotlib/issues/209) 
     339   # - if trajectory outside contour grid, will increase bounds 
     340   #   (see support_hypercube.py for how to fix bounds) 
    326341 
    327342    #XXX: note that 'argparse' is new as of python2.7 
     
    334349                      metavar="STR",default=",,", 
    335350                      help="string to assign label to axis") 
    336 #   parser.add_option("-n","--nid",action="store",dest="id",\ 
    337 #                     metavar="INT",default=None, 
    338 #                     help="id # of the nth simultaneous points to plot") 
    339 #   parser.add_option("-i","--iters",action="store",dest="iters",\ 
    340 #                     metavar="STR",default=":", 
    341 #                     help="indicator string to select iterations to plot") 
     351    parser.add_option("-n","--nid",action="store",dest="id",\ 
     352                      metavar="INT",default=None, 
     353                      help="id # of the nth simultaneous points to plot") 
     354    parser.add_option("-i","--iter",action="store",dest="stop",\ 
     355                      metavar="INT",default=None, 
     356                      help="the largest iteration to plot") 
    342357    parser.add_option("-r","--reduce",action="store",dest="reducer",\ 
    343358                      metavar="STR",default="None", 
     
    361376    # get the import path for the model 
    362377    model = parsed_args[0]  # e.g. 'mystic.models.rosen' 
     378    if "None" == model: model = None #XXX: 'required'... allow this? 
    363379 
    364380    try: # get the name of the parameter log file 
     
    418434      label = ['','',''] 
    419435 
    420 #   try: # select which 'id' to plot results for 
    421 #     id = (int(parsed_opts.id),) #XXX: allow selecting more than one id ? 
    422 #   except: 
    423 #     id = None # i.e. 'all' **or** use id=0, which should be 'best' energy ? 
    424  
    425 #   try: # select which iterations to plot 
    426 #     iters = parsed_opts.iters.split(',')  # format is ":2, 2:4, 5, 6:" 
    427 #   except: 
    428 #     iters = [':'] 
     436    try: # select which 'id' to plot results for 
     437      ids = (int(parsed_opts.id),) #XXX: allow selecting more than one id ? 
     438    except: 
     439      ids = None # i.e. 'all' 
     440 
     441    try: # select which iteration to stop plotting at 
     442      stop = int(parsed_opts.stop) 
     443    except: 
     444      stop = None 
    429445 
    430446    ################################################# 
     
    480496        model = masked(mask)(model) 
    481497 
    482     # project trajectory on a 1D slice of the model surface #XXX: useful? 
    483 #   fig0 = draw_slice(model, x=x, y=sol[-1], scale=scale, shift=shift) 
    484 #   draw_projection(source, select=0, style=style, scale=scale, shift=shift, figure=fig0) 
    485  
    486     # plot the trajectory on the model surface (2D or 3D) 
    487     if model: # plot the surface 
     498       ## plot the surface in 1D 
     499       #if solver: v=sol[-1] 
     500       #elif source: v=cost[-1] 
     501       #else: v=None 
     502       #fig0 = draw_slice(model, x=x, y=v, scale=scale, shift=shift) 
     503        # plot the surface in 2D or 3D 
    488504        fig = draw_contour(model, x, y, surface=surface, fill=fill, scale=scale, shift=shift) 
    489505    else: 
     506       #fig0 = None 
    490507        fig = None 
    491     if source: # plot the trajectory 
    492         fig = draw_trajectory(source, select=select, surface=surface, style=style, scale=scale, shift=shift, figure=fig) 
     508 
     509    if source: 
     510        # params are the parameter trajectories 
     511        # cost is the solution trajectory 
     512        params, cost = get_history(source, ids) 
     513        if len(cost) > 1: style = style[1:] # 'auto-color' #XXX: or grayscale? 
     514 
     515        for p,c in zip(params, cost): 
     516           ## project trajectory on a 1D slice of model surface #XXX: useful? 
     517           #s = select[0] if len(select) else 0 
     518           #px = p[int(s)] # draw_projection requires one parameter 
     519           ## ignore everything after 'stop' 
     520           #_c = c[:stop] 
     521           #_x = px[:stop] 
     522           #fig0 = draw_projection(_x,_c, style=style, scale=scale, shift=shift, figure=fig0) 
     523 
     524            # plot the trajectory on the model surface (2D or 3D) 
     525            # get two selected params #XXX: what if len(select)<2? or len(p)<2? 
     526            p = [p[int(i)] for i in select[:2]] 
     527            px,py = p # draw_trajectory requires two parameters 
     528            # ignore everything after 'stop' 
     529            _x = px[:stop] 
     530            _y = py[:stop] 
     531            _c = c[:stop] if surface else None 
     532            fig = draw_trajectory(_x,_y,_c, style=style, scale=scale, shift=shift, figure=fig) 
    493533 
    494534    # add labels to the axes 
Note: See TracChangeset for help on using the changeset viewer.