Example #1
0
def test_FiberGroup_unique_coords():
    """
    Test class method Fiber.unique_coords
    """
    for x in range(1000):
        x1 = np.random.randn()
        x2 = np.random.randn()
        y1 = np.random.randn()
        y2 = np.random.randn()
        z1 = np.random.randn()
        z2 = np.random.randn()
        # So the next line isn't too long:
        npta = npt.assert_almost_equal
        # Should work if both fibers have non-unique coords
        npta(mtf.FiberGroup([
            mtf.Fiber([[x1, x1, x2], [y1, y1, y2], [z1, z1, z2]]),
            mtf.Fiber([[x1, x1, x2], [y1, y1, y2], [z1, z1, z2]])
        ]).unique_coords,
             np.array([[x1, x2], [y1, y2], [z1, z2]]),
             decimal=4)

        # And also for extracting across fibers with unique coords
        npta(mtf.FiberGroup(
            [mtf.Fiber([[x1], [y1], [z1]]),
             mtf.Fiber([[x2], [y2], [z2]])]).unique_coords,
             np.array([[x1, x2], [y1, y2], [z1, z2]]),
             decimal=4)

        # And also for extracting across shared coords
        npta(mtf.FiberGroup([
            mtf.Fiber([[x1], [y1], [z1]]),
            mtf.Fiber([[x2, x1], [y2, y1], [z2, z1]])
        ]).unique_coords,
             np.array([[x1, x2], [y1, y2], [z1, z2]]),
             decimal=4)
Example #2
0
def test_FiberGroup_xform():
    """
    Test affine transformation method of FiberGroup
    """

    # This affine rotates vectors 90 degrees around the x axis:
    pi_2 = np.pi / 2
    affine1 = np.matrix([[1, 0, 0, 0], [0, np.cos(pi_2), -np.sin(pi_2), 0],
                         [0, np.sin(pi_2), np.cos(pi_2), 0], [0, 0, 0, 1]])

    y = [0, 0, 1]
    x = [0, 1, 0]
    f1 = mtf.Fiber(x, affine=affine1)
    f2 = mtf.Fiber(y, affine=affine1)
    fg1 = mtf.FiberGroup([f1, f2])
    fg1.xform()

    # The first fiber's coordinates should be like the second one originally:
    npt.assert_almost_equal(fg1.fibers[0].coords, y)

    f3 = mtf.Fiber(x)
    f4 = mtf.Fiber(y)
    fg2 = mtf.FiberGroup([f3, f4], affine=affine1)

    fg2.xform()
    # Same should be true when the affine is associated with the FiberGroup:
    npt.assert_almost_equal(fg2.fibers[0].coords, y)
    # And the transformtation should have mutated the original object:
    npt.assert_almost_equal(f3.coords, y)

    f5 = mtf.Fiber(x)
    f6 = mtf.Fiber(y)
    fg3 = mtf.FiberGroup([f5, f6])
    fg3.xform(affine1)
    # Same should be true when the affine is provided as input:
    npt.assert_almost_equal(fg3.fibers[0].coords, y)
    # And the transformtation should have mutated the original object:
    npt.assert_almost_equal(f5.coords, y)

    # This also attaches the inverse of this affine to the original object, so
    # that you can always find your way back:
    npt.assert_almost_equal(f5.affine, affine1.getI())

    f7 = mtf.Fiber(x)
    f8 = mtf.Fiber(y)
    fg4 = mtf.FiberGroup([f7, f8])
    fg4.xform()
    npt.assert_equal(fg4.affine, None)

    # The affine should 'stick':
    fg4.xform(np.eye(4))
    npt.assert_equal(fg4.affine, np.eye(4))
    # Even to the fibers:
    npt.assert_equal(f8.affine, np.eye(4))
Example #3
0
def fg_from_trk(trk_file, affine=None):
    """
    Read data from a trackvis .trk file and create a FiberGroup object
    according to the information in it.
    """

    # Generate right away, since we're going to do it anyway:
    read_trk = tv.read(trk_file, as_generator=False)
    fibers_trk = read_trk[0]

    # Per default read from the affine from the file header:
    if affine is not None:
        aff = affine
    else:
        hdr = read_trk[1]
        aff = tv.aff_from_hdr(hdr)
        # If the header contains a bogus affine, we revert to np.eye(4), so we
        # don't get into trouble later:
        try:
            np.matrix(aff).getI()
        except np.linalg.LinAlgError:
            e_s = "trk file contains bogus header, reverting to np.eye(4)"
            warnings.warn(e_s)
            aff = np.eye(4)

    fibers = []
    for f in fibers_trk:
        fibers.append(ozf.Fiber(np.array(f[0]).T, affine=aff))

    return ozf.FiberGroup(fibers, affine=aff)
Example #4
0
def test_pdb_from_fg():
    """
    Test writing a fiber-group to file
    """
    coords1 = np.arange(900).reshape(3, 300)
    coords2 = np.arange(900).reshape(3, 300) + 100

    fiber_stats = dict(foo=1, bar=2)
    node_stats = dict(ecc=np.arange(300))

    fg = mtf.FiberGroup([
        mtf.Fiber(coords1, fiber_stats=fiber_stats, node_stats=node_stats),
        mtf.Fiber(coords2, fiber_stats=fiber_stats, node_stats=node_stats)
    ])

    temp_dir = tempfile.gettempdir()

    mio.pdb_from_fg(fg, os.path.join(temp_dir, 'fg.pdb'))

    # Test that the properties are preserved upon reloading:
    fg2 = mio.fg_from_pdb(os.path.join(temp_dir, 'fg.pdb'))

    npt.assert_equal(fg2[0].coords, fg[0].coords)
    npt.assert_equal(fg2[1].coords, fg[1].coords)

    npt.assert_equal(fg2[0].node_stats, fg[0].node_stats)
    npt.assert_equal(fg2[1].node_stats, fg[1].node_stats)

    npt.assert_equal(fg2.fiber_stats, fg.fiber_stats)
Example #5
0
def test_FiberGroup():
    """
    Testing intialization of FiberGroup class.
    """

    arr2d = np.array([[1, 2], [3, 4], [5, 6]])
    arr1d = np.array([5, 6, 7])
    f1 = mtf.Fiber(arr2d, fiber_stats=dict(a=1, b=2))
    f2 = mtf.Fiber(arr1d, fiber_stats=dict(a=1))
    fg1 = mtf.FiberGroup([f1, f2])
    npt.assert_equal(fg1.n_fibers, 2)
    # We have to sort, because it could also come out as ['b', 'a']:
    npt.assert_equal(np.sort(fg1.fiber_stats.keys()), ['a', 'b'])

    # The number of nodes is just the sum of nodes/fiber:
    npt.assert_equal(fg1.n_nodes, f1.n_nodes + f2.n_nodes)
Example #6
0
def fg_from_pdb(file_name, verbose=True):
    """
    Read the definition of a fiber-group from a .pdb file
    Parameters
    ----------
    file_name: str
       Full path to the .pdb file
    Returns
    -------
    A FiberGroup object

    Note
    ----
    This only reads Version 3 PDB. For the full file-format spec, see the
    osmosis.io module top-level docstring

    """
    # Read the file as binary info:
    f_obj = file(file_name, 'r')
    f_read = f_obj.read()
    f_obj.close()
    # This is an updatable index into this read:
    idx = 0

    # First part is an int encoding the offset to the fiber part:
    offset, idx = _unpacker(f_read, idx, 1)

    # Next bit are doubles, encoding the xform (4 by 4 = 16 of them):
    xform, idx = _unpacker(f_read, idx, 16, 'double')
    xform = np.reshape(xform, (4, 4))

    # Next is an int encoding the number of stats:
    numstats, idx = _unpacker(f_read, idx, 1)

    # The stats header is a dict with lists holding the stat per
    stats_header = dict(
        luminance_encoding=[],  # int => bool
        computed_per_point=[],  # int => bool
        viewable=[],  # int => bool
        agg_name=[],  # char array => string
        local_name=[],  # char array => string
        uid=[]  # int
    )

    # Read the stats header:
    counter = 0
    while counter < numstats:
        counter += 1
        for k in ["luminance_encoding", "computed_per_point", "viewable"]:
            this, idx = _unpacker(f_read, idx, 1)
            stats_header[k].append(np.bool(this))

        for k in ["agg_name", "local_name"]:
            this, idx = _unpacker(f_read, idx, 255, 'char')
            stats_header[k].append(_word_maker(this))
        # Must have integer reads be word aligned (?):
        idx += 2
        this, idx = _unpacker(f_read, idx, 1)
        stats_header["uid"].append(this)

    # We skip the whole bit with the algorithms and go straight to the version
    # number, which is one int length before the fibers:
    idx = offset - 4
    version, idx = _unpacker(f_read, idx, 1)
    if int(version) < 2:
        raise ValueError("Can only read PDB version 2 or version 3 files")
    elif verbose:
        print("Loading a PDB version %s file from: %s" %
              (int(version), file_name))

    if int(version) == 2:
        idx = offset

    # How many fibers?
    numpaths, idx = _unpacker(f_read, idx, 1)

    if int(version) == 2:
        pts = []
        if verbose:
            prog_bar = ProgressBar(numpaths[0])
            f_name = inspect.stack()[0][3]

        f_stats = []
        n_stats = []
        for p_idx in range(numpaths):
            f_stats_dict = {}
            n_stats_dict = {}

            # Keep track of where you are right now
            ppos = idx
            path_offset, idx = _unpacker(f_read, idx, 1)
            n_nodes, idx = _unpacker(f_read, idx, 1)
            # As far as I can tell the following two don't matter much:
            algo_type, idx = _unpacker(f_read, idx, 1)
            seed_pt_idx, idx = _unpacker(f_read, idx, 1)
            # Read out the per-path stats:
            for stat_idx in range(numstats):
                per_fiber_stat, idx = _unpacker(f_read, idx, 1, 'double')
                f_stats_dict[stats_header["local_name"][stat_idx]] = \
                    per_fiber_stat
            f_stats.append(f_stats_dict)
            # Skip forward to where the paths themselves are:
            idx = ppos
            # Read the nodes:
            pathways, idx = _unpacker(f_read, idx, n_nodes * 3, 'double')

            pts.append(np.reshape(pathways, (n_nodes, 3)).T)
            for stat_idx in range(numstats):
                if stats_header["computed_per_point"][stat_idx]:
                    name = stats_header["local_name"][stat_idx]
                    n_stats_dict[name], idx = _unpacker(
                        f_read, idx, n_nodes, 'double')

            n_stats.append(n_stats_dict)

        fibers = []

        # Initialize all the fibers:
        for p_idx in range(numpaths):
            this_fstats_dict = f_stats[p_idx]
            f_stat_k = this_fstats_dict.keys()
            f_stat_v = [this_fstats_dict[k] for k in f_stat_k]
            this_nstats_dict = n_stats[p_idx]
            n_stats_k = this_nstats_dict.keys()
            n_stats_v = [this_nstats_dict[k] for k in n_stats_k]
            fibers.append(
                ozf.Fiber(pts[p_idx],
                          xform,
                          fiber_stats=dict(zip(f_stat_k, f_stat_v)),
                          node_stats=dict(zip(n_stats_k, n_stats_v))))

    elif int(version) == 3:
        # The next few bytes encode the number of points in each fiber:
        pts_per_fiber, idx = _unpacker(f_read, idx, numpaths)
        total_pts = np.sum(pts_per_fiber)
        # Next we have the xyz coords of the nodes in all fibers:
        fiber_pts, idx = _unpacker(f_read, idx, total_pts * 3, 'double')

        # We extract the information on a fiber-by-fiber basis
        pts_read = 0
        pts = []

        if verbose:
            prog_bar = ProgressBar(numpaths[0])
            f_name = inspect.stack()[0][3]
        for p_idx in range(numpaths):
            n_nodes = pts_per_fiber[p_idx]
            pts.append(
                np.reshape(fiber_pts[pts_read * 3:(pts_read + n_nodes) * 3],
                           (n_nodes, 3)).T)
            pts_read += n_nodes
            if verbose:
                prog_bar.animate(p_idx, f_name=f_name)

        f_stats_dict = {}
        for stat_idx in range(numstats):
            per_fiber_stat, idx = _unpacker(f_read, idx, numpaths, 'double')
            # This is a fiber-stat only if it's not computed per point:
            if not stats_header["computed_per_point"][stat_idx]:
                f_stats_dict[stats_header["local_name"][stat_idx]] =\
                    per_fiber_stat

        per_point_stat = []
        n_stats_dict = {}
        for stat_idx in range(numstats):
            pts_read = 0
            # If it is computer per point, it's a node-stat:
            if stats_header["computed_per_point"][stat_idx]:
                name = stats_header["local_name"][stat_idx]
                n_stats_dict[name] = []
                per_point_stat, idx = _unpacker(f_read, idx, total_pts,
                                                'double')
                for p_idx in range(numpaths):
                    n_stats_dict[name].append(
                        per_point_stat[pts_read:pts_read +
                                       pts_per_fiber[p_idx]])

                    pts_read += pts_per_fiber[p_idx]
            else:
                per_point_stat.append([])

        fibers = []
        # Initialize all the fibers:
        for p_idx in range(numpaths):
            f_stat_k = f_stats_dict.keys()
            f_stat_v = [f_stats_dict[k][p_idx] for k in f_stat_k]
            n_stats_k = n_stats_dict.keys()
            n_stats_v = [n_stats_dict[k][p_idx] for k in n_stats_k]
            fibers.append(
                ozf.Fiber(pts[p_idx],
                          xform,
                          fiber_stats=dict(zip(f_stat_k, f_stat_v)),
                          node_stats=dict(zip(n_stats_k, n_stats_v))))
    if verbose:
        print("Done reading from file")

    name = os.path.split(file_name)[-1].split('.')[0]
    return ozf.FiberGroup(fibers, name=name, affine=xform)