Beispiel #1
0
    def circlearound_n2d(self, src, radius, metric="euclidean"):
        shortmetric = metric[0].lower()

        if shortmetric == "e":
            v = self.vertices

            # make sure src is a 1x3 array
            if type(src) is tuple and len(src) == 3:
                src = np.asarray(src)

            if isinstance(src, np.ndarray):
                if src.shape not in ((1, 3), (3,), (3, 1)):
                    raise ValueError("Illegal shape: should have 3 elements")

                src_coord = src if src.shape == (1, 3) else np.reshape(src, (1, 3))
            else:
                src_coord = np.reshape(v[src, :], (1, 3))

            # ensure it is a float
            src_coord = np.asanyarray(src_coord, dtype=np.float)

            # make a mask around center
            voxel2world = self._vg.affine
            world2voxel = np.linalg.inv(voxel2world)

            nrm = np.linalg.norm(voxel2world, 2)

            max_extent = np.ceil(radius / nrm + 1)

            src_ijk = self._vg.xyz2ijk(src_coord)

            # min and max ijk coordinates
            mn = (src_ijk.ravel() - max_extent).astype(np.int_)
            mx = (src_ijk.ravel() + max_extent).astype(np.int_)

            # set boundaries properly
            mn[mn < 0] = 0

            sh = np.asarray(self._vg.shape[:3])
            mx[mx > sh] = sh[mx > sh]

            msk_ijk = np.zeros(self._vg.shape[:3], np.int)
            msk_ijk[mn[0] : mx[0], mn[1] : mx[1], mn[2] : mx[2]] = 1

            msk_lin = msk_ijk.ravel()

            # indices of voxels around the mask
            idxs = np.nonzero(msk_lin)[0]

            d = volgeom.distance(src_coord, v[idxs])[0, :]

            n = d.size
            node2dist = dict((idxs[i], d[i]) for i in np.arange(n) if d[i] <= radius)

            return node2dist

        elif shortmetric == "d":
            return {src: 0.0}
        else:
            raise ValueError("Illegal metric: %s" % metric)
Beispiel #2
0
    def target2nearest_source(self, target, fallback_euclidean_distance=False):
        """Find the voxel nearest to a mask center

        Parameters
        ==========
        target: int
            linear index of a voxel
        fallback_euclidean_distance: bool (default: False)
            Whether to use a euclidean distance metric if target is not in
            any of the masks in this instance

        Returns
        =======
        src: int
            key index for the mask that contains target and is nearest to
            target. If target is not contained in any mask, then None is
            returned if fallback_euclidean_distance is False, and the
            index of the source nearest to target using a Euclidean distance
            metric is returned if fallback_euclidean_distance is True
        """
        targets = []
        if type(target) in (list, tuple):
            for t in target:
                targets.append(t)
        else:
            targets = [target]

        xyz_trg = self.xyz_target(np.asarray(targets))

        src = self.target2sources(targets)
        flat_srcs = []
        for s in src:
            if s:
                for j in s:
                    flat_srcs.append(j)

        if not flat_srcs:
            if fallback_euclidean_distance:
                flat_srcs = self.keys()
            else:
                return None



        xyz_srcs = self.xyz_source(flat_srcs)
        d = volgeom.distance(xyz_srcs, xyz_trg)
        i = np.argmin(d)
        # d is a 2D array, get the row number with the lowest d
        source = flat_srcs[i // xyz_trg.shape[0]]

        return source
Beispiel #3
0
    def target2nearest_source(self, target, fallback_euclidean_distance=False):
        """Find the voxel nearest to a mask center

        Parameters
        ==========
        target: int
            linear index of a voxel
        fallback_euclidean_distance: bool (default: False)
            Whether to use a euclidean distance metric if target is not in
            any of the masks in this instance

        Returns
        =======
        src: int
            key index for the mask that contains target and is nearest to
            target. If target is not contained in any mask, then None is
            returned if fallback_euclidean_distance is False, and the
            index of the source nearest to target using a Euclidean distance
            metric is returned if fallback_euclidean_distance is True
        """
        targets = []
        if type(target) in (list, tuple):
            for t in target:
                targets.append(t)
        else:
            targets = [target]

        xyz_trg = self.xyz_target(np.asarray(targets))

        src = self.target2sources(targets)
        flat_srcs = []
        for s in src:
            if s:
                for j in s:
                    flat_srcs.append(j)

        if not flat_srcs:
            if fallback_euclidean_distance:
                flat_srcs = self.keys()
            else:
                return None



        xyz_srcs = self.xyz_source(flat_srcs)
        d = volgeom.distance(xyz_srcs, xyz_trg)
        i = np.argmin(d)
        # d is a 2D array, get the row number with the lowest d
        source = flat_srcs[i // xyz_trg.shape[0]]

        return source
Beispiel #4
0
    def source2nearest_target(self, source):
        """Find the voxel nearest to a mask center

        Parameters
        ==========
        src: int
            mask index

        Returns
        =======
        target: int
            linear index of the voxel that is contained in the mask associated
            with src and nearest (Euclidean distance) to src.
        """

        trgs = self.__getitem__(source)
        trg_xyz = self.xyz_target(trgs)

        src_xyz = self.xyz_source(source)
        d = volgeom.distance(trg_xyz, src_xyz)
        i = np.argmin(d)

        return trgs[i / src_xyz.shape[0]]
Beispiel #5
0
    def source2nearest_target(self, source):
        """Finds the voxel nearest to a mask center

        Parameters
        ==========
        src: int
            mask index

        Returns
        =======
        target: int
            linear index of the voxel that is contained in the mask associated
            with src and nearest (Euclidian distance) to src.
        """

        trgs = self.__getitem__(source)
        trg_xyz = self.xyz_target(trgs)

        src_xyz = self.xyz_source(source)
        d = volgeom.distance(trg_xyz, src_xyz)
        i = np.argmin(d)

        return trgs[i / src_xyz.shape[0]]
Beispiel #6
0
    def test_volume_mask_dict(self):
        # also tests the outside_node_margin feature
        sh = (10, 10, 10)
        msk = np.zeros(sh)
        for i in xrange(0, sh[0], 2):
            msk[i, :, :] = 1

        vol_affine = np.identity(4)
        vol_affine[0, 0] = vol_affine[1, 1] = vol_affine[2, 2] = 2

        vg = volgeom.VolGeom(sh, vol_affine, mask=msk)

        density = 10

        outer = surf.generate_sphere(density) * 10. + 5
        inner = surf.generate_sphere(density) * 5. + 5

        intermediate = outer * .5 + inner * .5
        xyz = intermediate.vertices

        radius = 50

        outside_node_margins = [None, 0, 100., np.inf, True]
        expected_center_count = [87] * 2 + [intermediate.nvertices] * 3
        for k, outside_node_margin in enumerate(outside_node_margins):

            sel = surf_voxel_selection.run_voxel_selection(
                radius,
                vg,
                inner,
                outer,
                outside_node_margin=outside_node_margin)
            assert_equal(intermediate, sel.source)
            assert_equal(len(sel.keys()), expected_center_count[k])
            assert_true(
                set(sel.aux_keys()).issubset(
                    set(['center_distances', 'grey_matter_position'])))

            msk_lin = msk.ravel()
            sel_msk_lin = sel.get_mask().ravel()
            for i in xrange(vg.nvoxels):
                if msk_lin[i]:
                    src = sel.target2nearest_source(i)
                    assert_false((src is None) ^ (sel_msk_lin[i] == 0))

                    if src is None:
                        continue

                    # index of node nearest to voxel i
                    src_anywhere = sel.target2nearest_source(
                        i, fallback_euclidean_distance=True)

                    # coordinates of node nearest to voxel i
                    xyz_src = xyz[src_anywhere]

                    # coordinates of voxel i
                    xyz_trg = vg.lin2xyz(np.asarray([i]))

                    # distance between node nearest to voxel i, and voxel i
                    # this should be the smallest distancer
                    d = volgeom.distance(np.reshape(xyz_src, (1, 3)), xyz_trg)

                    # distances between all nodes and voxel i
                    ds = volgeom.distance(xyz, xyz_trg)

                    # order of the distances
                    is_ds = np.argsort(ds.ravel())

                    # go over all the nodes
                    # require that the node is in the volume
                    # mask

                    # index of node nearest to voxel i
                    ii = np.argmin(ds)

                    xyz_min = xyz[ii]
                    lin_min = vg.xyz2lin([xyz_min])

                    # linear index of voxel that contains xyz_src
                    lin_src = vg.xyz2lin(np.reshape(xyz_src, (1, 3)))

                    # when using multi-core support,
                    # pickling and unpickling can reduce the precision
                    # a little bit, causing rounding errors
                    eps = 1e-14

                    delta = np.abs(ds[ii] - d)
                    assert_false(delta > eps and ii in sel and i in sel[ii]
                                 and vg.contains_lin(lin_min))
Beispiel #7
0
    def test_volume_mask_dict(self):
        # also tests the outside_node_margin feature
        sh = (10, 10, 10)
        msk = np.zeros(sh)
        for i in xrange(0, sh[0], 2):
            msk[i, :, :] = 1

        vol_affine = np.identity(4)
        vol_affine[0, 0] = vol_affine[1, 1] = vol_affine[2, 2] = 2

        vg = volgeom.VolGeom(sh, vol_affine, mask=msk)

        density = 10

        outer = surf.generate_sphere(density) * 10. + 5
        inner = surf.generate_sphere(density) * 5. + 5

        intermediate = outer * .5 + inner * .5
        xyz = intermediate.vertices

        radius = 50

        outside_node_margins = [None, 0, 100., np.inf, True]
        expected_center_count = [87] * 2 + [intermediate.nvertices] * 3
        for k, outside_node_margin in enumerate(outside_node_margins):

            sel = surf_voxel_selection.run_voxel_selection(radius, vg, inner,
                                outer, outside_node_margin=outside_node_margin)
            assert_equal(intermediate, sel.source)
            assert_equal(len(sel.keys()), expected_center_count[k])
            assert_true(set(sel.aux_keys()).issubset(set(['center_distances',
                                                    'grey_matter_position'])))

            msk_lin = msk.ravel()
            sel_msk_lin = sel.get_mask().ravel()
            for i in xrange(vg.nvoxels):
                if msk_lin[i]:
                    src = sel.target2nearest_source(i)
                    assert_false((src is None) ^ (sel_msk_lin[i] == 0))

                    if src is None:
                        continue

                    # index of node nearest to voxel i
                    src_anywhere = sel.target2nearest_source(i,
                                            fallback_euclidean_distance=True)

                    # coordinates of node nearest to voxel i
                    xyz_src = xyz[src_anywhere]

                    # coordinates of voxel i
                    xyz_trg = vg.lin2xyz(np.asarray([i]))

                    # distance between node nearest to voxel i, and voxel i
                    # this should be the smallest distancer
                    d = volgeom.distance(np.reshape(xyz_src, (1, 3)), xyz_trg)


                    # distances between all nodes and voxel i
                    ds = volgeom.distance(xyz, xyz_trg)

                    # order of the distances
                    is_ds = np.argsort(ds.ravel())

                    # go over all the nodes
                    # require that the node is in the volume
                    # mask

                    # index of node nearest to voxel i
                    ii = np.argmin(ds)

                    xyz_min = xyz[ii]
                    lin_min = vg.xyz2lin([xyz_min])




                    # linear index of voxel that contains xyz_src
                    lin_src = vg.xyz2lin(np.reshape(xyz_src, (1, 3)))

                    # when using multi-core support,
                    # pickling and unpickling can reduce the precision
                    # a little bit, causing rounding errors
                    eps = 1e-14

                    delta = np.abs(ds[ii] - d)
                    assert_false(delta > eps and ii in sel and
                                 i in sel[ii] and
                                 vg.contains_lin(lin_min))
Beispiel #8
0
    def circlearound_n2d(self, src, radius, metric='euclidean'):
        shortmetric = metric[0].lower()

        if shortmetric == 'e':
            v = self.vertices

            # make sure src is a 1x3 array
            if type(src) is tuple and len(src) == 3:
                src = np.asarray(src)

            if isinstance(src, np.ndarray):
                if src.shape not in ((1, 3), (3, ), (3, 1)):
                    raise ValueError("Illegal shape: should have 3 elements")

                src_coord = src if src.shape == (1, 3) else np.reshape(
                    src, (1, 3))
            else:
                src_coord = np.reshape(v[src, :], (1, 3))

            # ensure it is a float
            src_coord = np.asanyarray(src_coord, dtype=np.float)

            # make a mask around center
            voxel2world = self._vg.affine
            world2voxel = np.linalg.inv(voxel2world)

            nrm = np.linalg.norm(voxel2world, 2)

            max_extent = np.ceil(radius / nrm + 1)

            src_ijk = self._vg.xyz2ijk(src_coord)

            # min and max ijk coordinates
            mn = (src_ijk.ravel() - max_extent).astype(np.int_)
            mx = (src_ijk.ravel() + max_extent).astype(np.int_)

            # set boundaries properly
            mn[mn < 0] = 0

            sh = np.asarray(self._vg.shape[:3])
            mx[mx > sh] = sh[mx > sh]

            msk_ijk = np.zeros(self._vg.shape[:3], np.int)
            msk_ijk[mn[0]:mx[0], mn[1]:mx[1], mn[2]:mx[2]] = 1

            msk_lin = msk_ijk.ravel()

            # indices of voxels around the mask
            idxs = np.nonzero(msk_lin)[0]

            d = volgeom.distance(src_coord, v[idxs])[0, :]

            n = d.size
            node2dist = dict(
                (idxs[i], d[i]) for i in np.arange(n) if d[i] <= radius)

            return node2dist

        elif shortmetric == 'd':
            return {src: 0.}
        else:
            raise ValueError("Illegal metric: %s" % metric)