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}")
Example #3
0
    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
Example #4
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