elif fig == "canon": c = plot_figure_canon(subfig, style,color) def get_canon_blocks(OPHS, SCS, partial, icumax, full, hooks, mp_jump): # Returns a list of lists {BCSS} of the canonical snake blocks # for the canonical path figure, and a list {RSrest} with the rasters # of {OPHS} not used in the snakes. # # The parameter {OPHS} should be a list of all the filling raster elements. # each element oriented from left to right. # # The parameter {SCS} should be a list of lists of indices. The raster # element {jrs} (from 0, left to right) on scanline {isc}, as returned by # {raster.separate_by_scanline}. # # The returned snake blocks are separated according to the canonical bands # defined by the cut-lines of {get_canon_cut_lines}, up to the cut-line {icumax}. # Each element {BCSS[ibd]} of the result is a list of the blocks that # appear in one of those bands. The returned blocks will use all the rasters # up to the cut-line {icumax}. The rasters of {OPHS} above that cut-line # are returned in {RSrest}. # # Each block will be constructed from a canonical sub-river -- a # subset of of raster paths in {OPHS} that lie on adjacent scan-lines, # with exactly one contact between conscutive rasters, and span the # band in quation. The rasters will be connected by the link paths # attached to those rasters, if any. # # If {full} is true, the choices of each block will be all the snake # paths that can be built from those rasters (either 2 or 4, snake # paths, depending on the number of scan-lines that it spans) # # If {full} is false, each block will have only one choice -- the one # that starts with the bottom-most raster, oriented from left to right. # # If {partial} is true, shows the set of cut-lines for a hypothetical # state during the HotPath algorithm. If {partial} is false, # shows the actual final solution. # # If {hooks} is false or the block has a single raster, # the links from the input rasters are copied to the block choices # when applicable. Otherwise the links are incorporated # in the block choices. See {make_snake_block_from_rasters}. # # No new {Contact} objects are created, but the attachments between # the existing contacts and paths of {OPHS} that are used in blocks, # as given by {path.get_contacst} and {contact.get_side_paths}, are # broken and the contacts are attached to the choices of the blocks # instead. # # The procedure also sets group index (as returned by # {path.get_group}) of all original raster paths in {OPHS} to the # sequential index of the block in which they were used; or to {None} # if they were not used in any block. # !!! Should use {raster_regroup.split_by_group} !!! # {SNIXSSS} is a list of list of list of pairs. If # {SNIXSSS[ibd][isn][irs]} is {(isc,jrs)}, it means that raster {irs} # (from bottom) of snake {isn} (from left) on band {ibd} (from bottom) # is raster {jrs} of scanline {isc}. if partial: SNIXSSS = ( # band (0,3): ( ( (0,0), (1,0), (2,0), ), ( (0,1), (1,1), (2,1), ), ), # Band (3,4): ( ( (3,0), ), ( (3,1), ), ( (3,2), ), ( (3,3), ), ), # Band (4,7): ( ( (4,0), (5,0), (6,0), ), ( (4,1), (5,1), (6,1), ), ( (4,2), (5,2), (6,2), ), ( (4,3), (5,3), (6,3), ), ), # Band (7,9): ( ( (7,0), (8,0), ), ( (7,1), (8,1), ), ( (7,2), (8,2), ), ), # Band (9,12): ( ( (9,0), (10,0), (11,0), ), ( (9,1), (10,1), (11,1), ), ( (9,2), (10,2), (11,2), ), ( (9,3), (10,3), (11,3), ), ), # Band (12,13): ( ( (12,0), ), ( (12,1), ), ( (12,2), ), ( (12,3), ), ), # Band (13,15): ( ( (13,0), (14,0), ), ( (13,1), (14,1), ), ( (13,2), (14,2), ), ( (13,3), (14,3), ), ), # Band (15,16): ( ( (15,0), ), ( (15,1), ), ), # Band (16,18): ( ( (16,0), (17,0), ), ), ) else: SNIXSSS = ( # band (0,3): ( ( (0,0), (1,0), (2,0), ), ( (0,1), (1,1), (2,1), ), ), # Band (3,4): ( ( (3,0), ), ( (3,1), ), ( (3,2), ), ( (3,3), ), ), # Band (4,7): ( ( (4,0), (5,0), (6,0), ), ( (4,1), (5,1), (6,1), ), ( (4,2), (5,2), (6,2), ), ( (4,3), (5,3), (6,3), ), ), # Band (7,9): ( ( (7,0), (8,0), ), ( (7,1), (8,1), ), ( (7,2), (8,2), ), ), # Band (9,10): ( ( (9,0), ), ( (9,1), ), ( (9,2), ), ( (9,3), ), ), # Band (10,13): ( ( (10,0), (11,0), (12,0), ), ( (10,1), (11,1), (12,1), ), ( (10,2), (11,2), (12,2), ), ( (10,3), (11,3), (12,3), ), ), # Band (13,15): ( ( (13,0), (14,0), ), ( (13,1), (14,1), ), ( (13,2), (14,2), ), ( (13,3), (14,3), ), ), # Band (15,16): ( ( (15,0), ), ( (15,1), ), ), # Band (16,18): ( ( (16,0), (17,0), ), ), ) # Clear the goup index of all raster paths in {OPHS}: for oph in OPHS: path.set_group(oph, None) nbc = 0 # Number of snake blocks created. BCSS = [] # List of lists of canonical snake blocks. RSrest = [] for SNIXSSk in SNIXSSS: # SNIXSSk is a list of lists of rasters (represented as index pairs) in the band with index {k}, # separated by snake. Create snake blocks of that band: BCSk = [] # List of canonical snake blocks in band. for SNIXSkj in SNIXSSk: # SNIXSkj is a list of index pairs of the rasters in one canonical snake block of that band. # Create the list of blocks {BCSk} OPBSj = collect_and_tag_snake_rasters(SNIXSkj, SCS, OPHS, icumax, nbc, RSrest) bckj = make_snake_block_from_rasters(OPBSj, full, hooks, nbc, mp_jump) if bckj != None: BCSk.append(bckj) nbc += 1 if len(BCSk) != 0: BCSS.append(BCSk) sys.stderr.write("got %d bands of blocks and %d leftover rasters\n" % (len(BCSS), len(RSrest))) for ibd in range(len(BCSS)): SNB = BCSS[ibd] sys.stderr.write(" band %d has %d blocks\n" % (ibd,len(SNB))); return BCSS, RSrest # ---------------------------------------------------------------------- def get_canon_cut_lines(OPHS, CTS, partial, icumax): # Returns a list {LNS} of cut-lines to plot on the HotFill figures. # Each element of {LNS} is a pair {(icu, t)} where {icu} is the index of the scan-line just above # the cut-line and {t} is a code (2 for essential, 1 for non-essential, 0 for not relevant). LNS = get_essential_cut_lines(OPHS, CTS) if partial: LNS += ( (4,1), (12,1), ) else: LNS += ( (4,1), (10,1), ) # Remove excess cut lines: LNS = [ (icu, t) for icu, t in LNS if icu <= icumax ] return LNS # ---------------------------------------------------------------------- def plot_figure_canon(subfig, style,color): # Plots the figure with canonical paths and canonical bandpath. # # subfig "paths" = state during Hotpath. # subfig "solution" = actual solution found by Hotpath. # # Returns the canvas {c} with the figure. assert subfig == "paths" or subfig == "solution", ("invalid subfig %s" % subfig) # Get the contours, fillers, links, contacts, and graph of the "turkey" part: mp_cont, mp_fill, mp_link, mp_jump = make_move_parms(); OCRS,OPHS,OLKS,CTS,VGS,EGS = paper_example_B.make_turkey(mp_cont, mp_fill,mp_link,mp_jump) Bfig, cuxlo, cuxhi = get_turkey_figure_bbox(OCRS, OPHS, OLKS, style) autoscale = True c = make_figure_canvas(Bfig, autoscale, style,color) # Separate the rasters by scan-line: xdir = (1,0) ydir = (0,1) ystep, yphase = raster.get_spacing_and_phase(OPHS, xdir, ydir) SCS = raster.separate_by_scanline(OPHS, xdir, ydir, ystep, yphase) nsc = len(SCS) # Build a list of list of blocks {BCSS} with one choice each, the canonical snake, # up to some cut-line {icumax} below the top one, separated into bands: dp = None full = False hooks = False if subfig == "paths": icumax = 12 partial = True else: icumax = nsc partial = False BCSS, RSrest = get_canon_blocks(OPHS, SCS, partial, icumax, full, hooks, mp_jump) plot_contours(c, OCRS, dp, style, color['ghost']) # Plot the relevant cut-lines that separate the chosen bands: LNS = get_canon_cut_lines(OPHS, CTS, partial, icumax); trim = True plot_cut_lines(c, LNS, cuxlo,cuxhi,trim, ystep,yphase, dp, style,color) # Concatenate the canonical snake paths in {BCSS} into a {(k,i)} canonical path # {cph} and a {(i,j)} canonical band-path {bph} (or {NOne}): nbd = len(BCSS) CPS = [] # List of canonical snake paths that make up {cph} BPS = [] # List of canonical snake paths that make up {bph} for ibd in range(nbd): for bc in BCSS[ibd]: # Blocks in band {ibd} assert block.nchoices(bc) == 1 # Since {full} was false. och = block.choice(bc, 0) if subfig == "paths" and ibd == nbd-1: BPS.append(och) else: CPS.append(och) use_links = True cph = path.concat(CPS, use_links, mp_jump) # Plot the canonical path and the canonical sub-path: rwdf = style['rwd_fill'] ccph = color['fill'] # Color for the canonical {(k,i)} path. deco = False plot_paths(c, [cph,], dp, [ccph,], rwdf,deco, style,color) plot_path_endpoints(c, [cph,], dp, style,color) if subfig == "paths": bph = path.concat(BPS, use_links, mp_jump) cbph = color['hifi'] # Color for the canonical {(i,j)} band-path. deco = False plot_paths(c, [bph,], dp, [cbph,], rwdf,deco, style,color) plot_path_endpoints(c, [bph,], dp, style,color) # Plot the unused rasters: crest = color['ghost'] deco = False for oph in RSrest: plot_paths(c, [oph,], dp, [crest,], rwdf,deco, style,color) if subfig == "solution": # Find the coldest contact and its cooling time: ncold = 1 # Number of coldest contacts to show. CTScold = contact.coldest(cph, CTS, ncold) contact.show_times(sys.stderr, [cph,], CTScold) # Plot coldest contact(s). interbc = False shadow = True trim = False plot_contacts(c, CTScold, dp, interbc, shadow,trim, style,color) # Plot the path endpoint labels: pfsize = style['fullfsize'] tdA = (-1.8, -1.6) tdB = (-1.8, -0.4) plot_path_endpoint_labels(c, cph, "A", tdA, "B", tdB, dp, pfsize, style,color) if subfig == "paths": tdC = (-2.0, -0.1) tdD = (+0.7, -1.0) plot_path_endpoint_labels(c, bph, "C", tdC, "D", tdD, dp, pfsize, style,color) # ??? Should plot the contacts between {cph} and {bph} ??? return c # ---------------------------------------------------------------------- def plot_figure_blocks(subfig, style,color): ... # {subfig} == "canstacks", plots the rasters classified into stacks with essential and some non-essential cut-lines. # {subfig} == "canblocks", plots those stacks turned into blocks, as would be created from the output of {HotPath} ... if subfig == "canstacks" or subfig == "canblocks": # Get the canonical blocks, in all the bands up to the top. # Also set the groups of the rasters in {OPHS} to the block index: full = True # Generate blocks with all possible choices. hooks = False icumax = nsc # Go all the way to the top. partial = False BCSS, RSrest = get_hotfill_blocks(OPHS, SCS, partial, icumax, full, hooks, mp_jump) assert len(RSrest) == 0 # Make a flat list {BCS} of all blocks: BCS = [ bc for BCSi in BCSS for bc in BCSi ] # No selected block: IBCHS = [] ... subfig == "canstacks" or subfig == "canblocks" or def plot_figure_blocks_whole(c, subfig, OCRS, OPHS, CTS, BCS, BCHS, dp, cuxlo,cuxhi, nsc,ystep,yphase, style,color): ... if subfig == "canstacks" or subfig == "canblocks": # Plot the cut-lines used to define the canonical stacks or blocks: partial = False icumax = nsc # Go all the way to the top. LNS = get_canon_cut_lines(OPHS, CTS, partial, icumax) trim = False plot_cut_lines(c, LNS, cuxlo,cuxhi,trim, ystep,yphase, dp, style,color) ... subfig == "canblocks" or ... if subfig == "canstacks": # Plot the rasters, colored by stacks: Ylum = color['Ytrace'] CLRS = hacks.trace_colors(nbc, Ylum) rwdf = style['rwd_fill'] deco = False for oph in OPHS: igr = path.get_group(oph) assert igr != None and igr >= 0 and igr < nbc, ("invalid raster group index %s" % str(igr)) clr = CLRS[igr] plot_paths(c, [oph,], dp, [clr,], rwdf,deco, style,color) ... def plot_jumps(c, JMPS, dp, style,color): # Plots the jump moves in the list {JMPS} with the standard style and color. rwdf = style['rwd_fill'] # Not used, really clr = color['jump'] wd_axes = style['wd_axes'] axes = True dots = True arrows = True matter = False move.plot_standard(c, JMPS, dp, 3, [clr,], rwdf, wd_axes, axes, dots, arrows, matter) return # ----------------------------------------------------------------------