Ejemplo n.º 1
0
  def get(self, segids, allow_missing=False):
    """
    Retrieve one or more skeletons from the data layer.

    Example: 
      skel = vol.skeleton.get(5)
      skels = vol.skeleton.get([1, 2, 3])

    Raises SkeletonDecodeError on missing files or decoding errors.

    Required:
      segids: list of integers or integer
    Optional:
      allow_missing: skip over non-existent files otherwise
        raise cloudvolume.exceptions.SkeletonDecodeError

    Returns: 
      if segids is a list, returns list of Skeletons
      else returns a single Skeleton
    """
    list_return = True
    if type(segids) in (int, float):
      list_return = False
      segids = [ int(segids) ]

    compress = self.config.compress 
    if compress is None:
      compress = True

    results = self.cache.download(
      [ self.meta.join(self.meta.skeleton_path, str(segid)) for segid in segids ],
      compress=compress
    )
    missing = [ filename for filename, content in results.items() if content is None ]
    results = { filename: content for filename, content in results.items() if content is not None }

    if not allow_missing and len(missing):
      raise SkeletonDecodeError("File(s) do not exist: {}".format(", ".join(missing)))

    skeletons = []
    for filename, content in results.items():
      segid = int(os.path.basename(filename))
      try:
        skel = Skeleton.from_precomputed(content, segid=segid)
      except Exception as err:
        raise SkeletonDecodeError("segid " + str(segid) + ": " + str(err))
      skel.transform = self.meta.transform
      skeletons.append(skel.physical_space())

    if list_return:
      return skeletons

    if len(skeletons):
      return skeletons[0]

    return None
Ejemplo n.º 2
0
    def get(self, segids):
        """
    Retrieve one or more skeletons from the data layer.

    Example: 
      skel = vol.skeleton.get(5)
      skels = vol.skeleton.get([1, 2, 3])

    Raises SkeletonDecodeError on missing files or decoding errors.

    Required:
      segids: list of integers or integer

    Returns: 
      if segids is a list, returns list of PrecomputedSkeletons
      else returns a single PrecomputedSkeleton
    """
        list_return = True
        if type(segids) in (int, float):
            list_return = False
            segids = [int(segids)]

        compress = self.config.compress
        if compress is None:
            compress = True

        results = self.cache.download(
            [os.path.join(self.path, str(segid)) for segid in segids],
            compress=compress)
        missing = [
            filename for filename, content in results.items()
            if content is None
        ]

        if len(missing):
            raise SkeletonDecodeError("File(s) do not exist: {}".format(
                ", ".join(missing)))

        skeletons = []
        for filename, content in results.items():
            segid = int(os.path.basename(filename))
            try:
                skel = PrecomputedSkeleton.decode(content, segid=segid)
            except Exception as err:
                raise SkeletonDecodeError("segid " + str(segid) + ": " +
                                          err.message)
            skeletons.append(skel)

        if list_return:
            return skeletons

        if len(skeletons):
            return skeletons[0]

        return None
Ejemplo n.º 3
0
    def decode(kls, skelbuf, segid=None):
        """
    Convert a buffer into a PrecomputedSkeleton object.

    Format:
    num vertices (Nv) (uint32)
    num edges (Ne) (uint32)
    XYZ x Nv (float32)
    edge x Ne (2x uint32)
    radii x Nv (optional, float32)
    vertex_type x Nv (optional, req radii, uint8) (SWC definition)

    More documentation: 
    https://github.com/seung-lab/cloud-volume/wiki/Advanced-Topic:-Skeletons-and-Point-Clouds
    """
        if len(skelbuf) < 8:
            raise SkeletonDecodeError(
                "{} bytes is fewer than needed to specify the number of verices and edges."
                .format(len(skelbuf)))

        num_vertices, num_edges = struct.unpack('<II', skelbuf[:8])
        min_format_length = 8 + 12 * num_vertices + 8 * num_edges

        if len(skelbuf) < min_format_length:
            raise SkeletonDecodeError(
                "The input skeleton was {} bytes but the format requires {} bytes."
                .format(len(skelbuf), format_length))

        vstart = 2 * 4  # two uint32s in
        vend = vstart + num_vertices * 3 * 4  # float32s
        vertbuf = skelbuf[vstart:vend]

        estart = vend
        eend = estart + num_edges * 4 * 2  # 2x uint32s

        edgebuf = skelbuf[estart:eend]

        vertices = np.frombuffer(vertbuf, dtype='<f4').reshape(
            (num_vertices, 3))
        edges = np.frombuffer(edgebuf, dtype='<u4').reshape((num_edges, 2))

        if len(skelbuf) == min_format_length:
            return PrecomputedSkeleton(vertices, edges, segid=segid)

        radii_format_length = min_format_length + num_vertices * 4

        if len(skelbuf) < radii_format_length:
            raise SkeletonDecodeError(
                "Input buffer did not have enough float32 radii to correspond to each vertex. # vertices: {}, # radii: {}"
                .format(num_vertices,
                        (radii_format_length - min_format_length) / 4))

        rstart = eend
        rend = rstart + num_vertices * 4  # 4 bytes np.float32
        radiibuf = skelbuf[rstart:rend]
        radii = np.frombuffer(radiibuf, dtype=np.float32)

        if len(skelbuf) == radii_format_length:
            return PrecomputedSkeleton(vertices, edges, radii, segid=segid)

        type_format_length = radii_format_length + num_vertices * 1

        if len(skelbuf) < type_format_length:
            raise SkeletonDecodeError(
                "Input buffer did not have enough uint8 SWC vertex types to correspond to each vertex. # vertices: {}, # types: {}"
                .format(num_vertices,
                        (type_format_length - radii_format_length)))

        tstart = rend
        tend = tstart + num_vertices
        typebuf = skelbuf[tstart:tend]
        vertex_types = np.frombuffer(typebuf, dtype=np.uint8)

        return PrecomputedSkeleton(vertices,
                                   edges,
                                   radii,
                                   vertex_types,
                                   segid=segid)