def __init__(self, object, highlights={}, extent=(30, 200)): """__init__""" # # Set up logging # self.logger = logging.getLogger('fibertree.graphics.tree_image') # # Record parameters # # Note: We conditionally unwrap Payload objects # self.object = Payload.get(object) self.row_extent = extent[0] self.col_extent = extent[1] level = self.object.getDepth() - 1 self.highlight_manager = HighlightManager(highlights, level=level) # # Cache worker colors # worker_color = {} for n, worker in enumerate(highlights.keys()): worker_color[worker] = ImageUtils.getColor(worker) self.worker_color = worker_color # # Create the tree image # self._create_tree()
def __init__(self, object, *args, highlights={}, style='tree', **kwargs): """__init__""" # # Set up logging # self.logger = logging.getLogger('fibertree.graphics.tensor_image') highlights = HighlightManager.canonicalizeHighlights(highlights) # # Conditionally unwrap Payload objects # object = Payload.get(object) # # Create the subimages # if "tree" in style: im1 = TreeImage(object, *args, highlights=highlights, **kwargs).im if "uncompressed" in style: im2 = UncompressedImage(object, *args, highlights=highlights, **kwargs).im # # Create the final image # # TBD: Allow style to be a list # if style == "tree": self.im = im1 elif style == "uncompressed": self.im = im2 elif style == "tree+uncompressed": color="wheat" im = Image.new('RGB', (max(im1.width, im2.width), im1.height + im2.height), color) diff = im1.width - im2.width if diff > 0: # im1 is bigger im1_xoffset = 0 im2_xoffset = diff//2 else: # im2 is bigger im1_xoffset = -diff//2 im2_xoffset = 0 im.paste(im1, (im1_xoffset, 0)) im.paste(im2, (im2_xoffset, im1.height)) self.im = im else: print(f"TensorImage: Unsupported image style - {style}")
def __init__(self, *tensors): """__init__""" # # Set up logging # self.logger = logging.getLogger('fibertree.graphics.spacetime_canvas') # # Structures to hold infomation about each tracked tensor # self.tensors = [] self.spacetime = [] self.highlights = [] for tensor in tensors: # # Append each tensor being tracked, conditionally # unwraping it if it is a Payload object # self.tensors.append(Payload.get(tensor)) # # Create a "spacetime" tensor to hold the spacetime # information for this tracked tensor # if isinstance(tensor, Tensor): assert tensor.getShape() != [], "No support for 0-D tensors" spacetime = Tensor(rank_ids=["T"] + tensor.getRankIds()) spacetime.setName(tensor.getName()) spacetime.setColor(tensor.getColor()) else: assert tensor.getDepth() == 1, "Only 1-D fibers are supported" spacetime = Tensor(rank_ids=["T", "S"]) # # Append the "spacetime" tensor to hold this tracked # tensor's spacetime information # self.spacetime.append(spacetime) # # Append an empty highlight object to hold the highlighting # information for this tracked tensor # self.highlights.append({}) self.frame_num = 0
def __init__(self, *tensors, style='tree', progress=True): """__init__""" # # Set up logging # self.logger = logging.getLogger('fibertree.graphics.movie_canvas') # # Set image type # self.style = style # # Set tqdm control # self.use_tqdm = progress # # Set up tensor class variables # # Note: We conditionally unwrap Payload objects # self.tensors = [] self.image_list_per_tensor = [] for tensor in tensors: self.tensors.append(Payload.get(tensor)) self.image_list_per_tensor.append([]) # # Font to use for text # self.font = ImageFont.truetype('Pillow/Tests/fonts/DejaVuSans.ttf', 16) # # Add an initial frame with nothing highlighted (it looks good) # self.addFrame()
def _create_tree(self): """create_tree Create an image of a tensor or fiber tree Notes ------ The drawing is made in a coordinate space where the X dimension is measured in the number of non-empty fiber coordinates being displayed and the Y dimension is measured in layers of the tree. Translation to pixels happens in the draw_*() methods. """ object = self.object # # Create the objects for the image # self._image_setup() # # Display either the root of a tensor or a raw fiber # if isinstance(object, Tensor): # # Displaying a tensor # root = object.getRoot() # # Get tensor's name # name = object.getName() # # Get tensor's color # self._color = object.getColor() # # Create rank_id string # # Note: if rank_id is a list, convert to a string # ranks = ", ".join([str(r) for r in object.getRankIds()]) if name: self._draw_rank(0, f"Tensor: {name}[{ranks}]") else: self._draw_rank(0, f"File: {object.yamlfile}") elif isinstance(object, Fiber): # # Displaying a fiber # root = object self._color = "red" else: # # Displaying nothing? # root = None self._color = "red" # # Process appropriately if root has 0 dimensions or more # if not Payload.contains(root, Fiber): # # Draw a 0-D tensor, i.e., a value # hlm = self.highlight_manager hl = hlm.getColorCoord(0) self._draw_coord(0, 0, "R") self._draw_line(0, 1 / 2, 1, 1 / 2) self._draw_value(1, 0, Payload.get(root), hl) region_end = 1 else: # # Draw a non-0-D tensor or a fiber, i.e., the fiber tree # region_end = self._traverse( root, highlight_manager=self.highlight_manager) # # Crop the image # right = 200 + self._offset2x(region_end) lower = 20 + self.max_y self.im = self.im.crop((0, 0, right, lower))
def _traverse(self, fiber, level=0, offset=0, highlight_manager=None): """traverse""" # # Check if this is level0, which may just be a payload # if level == 0: region_start = 0 if not Payload.contains(fiber, Fiber): # # Draw a 0-D tensor, i.e., a value (NOT a fiber) # self._draw_coord(0, 0, "R") self._draw_line(0, 1 / 2, 1, 1 / 2) self._draw_value(1, 0, Payload.get(fiber)) region_end = 1 else: # # Recursively traverse and draw the fibers of a non-0-D tensor # region_end = self._traverse( fiber, level=1, offset=offset, highlight_manager=highlight_manager) region_size = region_end - region_start # # Draw root of tree # fiber_size = 1 fiber_start = region_start + (region_size - fiber_size) / 2 self._draw_coord(0, fiber_start, "R") self._draw_line(0, region_size / 2, 1, region_size / 2) return region_end # # Process the fibers of the tree (level > 0) # # # Print out the rank information (if available) # if offset == 0 and not fiber.getOwner() is None: self._draw_rank(level, "Rank: %s " % fiber.getOwner().getId()) # # Initialize drawing region information # region_start = offset region_end = offset # # Figure out space of region below this fiber # targets = [] coordinate_start = region_start # # Traverse the fiber at this level # for n, (c, p) in enumerate(fiber): # # TBD: Truncate fibers with too many elements # # if n > 10: break if Payload.contains(p, Fiber): # # Configure highlights for this fiber # next_highlight_manager = highlight_manager.addFiber(c) # # Draw the object below this coordinate (in "c") # region_end = self._traverse( Payload.get(p), level=level + 1, offset=region_end, highlight_manager=next_highlight_manager) else: region_end += 1 # # Record (in "targets") the middle of the object below # this coordinate to draw a line to it later, and # calculate where the next object starts ("coordinate_start") # targets.append(coordinate_start + (region_end - coordinate_start) / 2) coordinate_start = region_end # # If the fiber was empty we still occupy a single space # if len(fiber) == 0: region_end += 1 region_size = region_end - region_start # # Set up the highlighting for this level # highlight_subtensor = highlight_manager.highlight_subtensor # # Display fiber for this level # fiber_size = len(fiber) fiber_start = region_start + (region_size - fiber_size) / 2 self._draw_fiber(level, fiber_start, fiber_start + fiber_size, highlight_subtensor) pos = fiber_start for c, p in fiber: # # Gets sets of workers to be colored # color_coord = highlight_manager.getColorCoord(c) color_subtensor = highlight_manager.getColorSubtensor() color_coord_or_subtensor = color_coord | color_subtensor # # Draw the coordinates, lines and maybe values # self._draw_coord(level, pos, c, color_coord_or_subtensor) if len(color_coord - color_subtensor): self._draw_intra_line(level, fiber_start + fiber_size / 2, pos + 0.5, True) # # Draw the line if the next level will actually draw something. # if not Payload.contains(p, Fiber) or len(p.coords) > 0: self._draw_line(level, pos + 0.5, level + 1, targets.pop(0), len(color_coord_or_subtensor) > 0) else: # # Nothing to connect a line to so pop target # targets.pop(0) if not Payload.contains(p, Fiber): # # How could this not be the leaf --- # "and rest_of_highlighting == []" # self._draw_value(level + 1, pos, Payload.get(p), color_coord_or_subtensor) pos += 1 return region_end