コード例 #1
0
ファイル: test_bodies.py プロジェクト: flmiot/syris-1
 def test_static_composite(self):
     ps = 1 * q.um
     traj = Trajectory([(0, 0, 0)] * q.m)
     mb_0 = MetaBall(traj, 10 * q.um)
     mb_1 = MetaBall(traj, 10 * q.um)
     comp = CompositeBody(traj, bodies=[mb_0, mb_1])
     self.assertEqual(np.inf * q.s, comp.get_next_time(0 * q.s, ps))
コード例 #2
0
ファイル: test_bodies.py プロジェクト: erickzhou/syris
    def setUp(self):
        syris.init(device_index=0)
        self.pixel_size = 1 * q.um

        control_points = get_linear_points(geom.X, start=(1, 1, 1))
        traj = Trajectory(control_points, velocity=1 * q.mm / q.s)
        self.metaball = MetaBall(traj, 1 * q.mm)
        self.metaball_2 = MetaBall(Trajectory(get_linear_points(geom.Z)), 2 * q.mm)
        self.composite = CompositeBody(traj, bodies=[self.metaball, self.metaball_2])
コード例 #3
0
ファイル: test_bodies.py プロジェクト: flmiot/syris-1
    def test_get_next_time(self):
        n = 100
        ps = 100 * q.mm
        psm = ps.simplified.magnitude
        p = np.linspace(0, np.pi, n)
        sin = np.sin(p) * 1e-3
        cos = np.cos(p) * 1e-3
        zeros = np.zeros(n)

        traj_m_0 = Trajectory(zip(p * 1e-3, zeros, zeros) * q.m,
                              velocity=1 * q.mm / q.s)
        traj_m_1 = Trajectory([(0, 0, 0)] * q.m)
        ball_0 = MetaBall(traj_m_0, .5 * q.m)
        ball_1 = MetaBall(traj_m_1, .5 * q.m)
        traj = Trajectory(zip(cos, sin, zeros) * q.m, velocity=1 * q.mm / q.s)
        comp = CompositeBody(traj, bodies=[ball_0, ball_1])
        dt = comp.get_maximum_dt(ps)

        # Normal trajectories
        # Test the beginning, middle and end because of time complexity
        for t_0 in [0 * q.s, comp.time / 2, comp.time - 10 * dt]:
            t_1 = comp.get_next_time(t_0, ps)

            d = comp.get_distance(t_0, t_1).simplified.magnitude
            np.testing.assert_almost_equal(psm, d)

        # Trajectories which sum up to no movement
        traj_m = Trajectory(zip(zeros, -p, zeros) * q.m,
                            velocity=1 * q.mm / q.s)
        ball = MetaBall(traj_m, .5 * q.m)
        traj = Trajectory(zip(p, zeros, zeros) * q.m, velocity=1 * q.mm / q.s)
        comp = CompositeBody(traj, bodies=[ball])

        self.assertEqual(np.inf * q.s, comp.get_next_time(0 * q.s, ps))
コード例 #4
0
ファイル: test_bodies.py プロジェクト: erickzhou/syris
    def test_composite_furthest_point(self):
        mb_0 = MetaBall(Trajectory([(0, 0, 0)] * q.m), 1 * q.m)
        mb_1 = MetaBall(Trajectory([(0, 0, 0)] * q.m), 2 * q.m)
        composite = CompositeBody(Trajectory([(0, 0, 0)] * q.m), bodies=[mb_0, mb_1])

        # Metaball's furthest point is twice the radius
        self.assertAlmostEqual(4 * q.m, composite.furthest_point)
コード例 #5
0
ファイル: test_bodies.py プロジェクト: flmiot/syris-1
    def test_composite_bounding_box(self):
        mb_0 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 0.5 * q.mm)
        mb_1 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 1.5 * q.mm)
        composite = CompositeBody(Trajectory([(0, 0, 0)] * q.mm, ),
                                  bodies=[mb_0, mb_1])

        transformed_0 = self._get_moved_bounding_box(mb_0, 90 * q.deg)
        transformed_1 = self._get_moved_bounding_box(mb_1, -90 * q.deg)

        def get_concatenated(t_0, t_1, index):
            return np.concatenate((zip(*t_0)[index], zip(*t_1)[index])) * \
                t_0[0].units

        x_points = get_concatenated(transformed_0, transformed_1, 0)
        y_points = get_concatenated(transformed_0, transformed_1, 1)
        z_points = get_concatenated(transformed_0, transformed_1, 2)

        x_min_max = min(x_points), max(x_points)
        y_min_max = min(y_points), max(y_points)
        z_min_max = min(z_points), max(z_points)

        ground_truth = np.array(
            list(itertools.product(x_min_max, y_min_max, z_min_max))) * q.m

        np.testing.assert_almost_equal(ground_truth,
                                       composite.bounding_box.points)
コード例 #6
0
ファイル: composite_body.py プロジェクト: ufo-kit/syris
def make_complex_trajectory_sequence(args):
    edge = 20
    x = np.linspace(0, args.n / 2 - args.n / 4 - edge - 5, num=10)
    y = z = np.zeros(x.shape)
    # Move along x axis
    traj_x = Trajectory(zip(x, y, z) * args.ps, velocity=args.ps / q.s, pixel_size=args.ps)
    # Move along y axis
    traj_y = Trajectory(zip(y, x, z) * args.ps, velocity=args.ps / q.s, pixel_size=args.ps)
    # Move along both x and y axes
    traj_xy = Trajectory(zip(x, x, z) * args.ps, velocity=args.ps / q.s, pixel_size=args.ps)
    # Circular trajectory of the composite body rotates around the image center and with radius
    # n / 4 pixels.
    circle = args.n / 2 * args.ps + make_circle().magnitude * args.n / 4 * args.ps
    traj_circle = Trajectory(circle, velocity=args.ps / q.s, pixel_size=args.ps)
    # Make the trajectory of the circle the same duration as the simple linear one.
    traj_circle = Trajectory(circle, velocity=traj_circle.length / traj_xy.length * args.ps / q.s)
    # three cubes in the same height and depth, shifted only along the x axis.
    traj_stationary = Trajectory([(0, 0, 0)] * args.ps)
    traj_stationary_1 = Trajectory([(-2 * edge, 0, 0)] * args.ps)
    traj_stationary_2 = Trajectory([(2 * edge, 0, 0)] * args.ps)

    cube = make_cube() / q.m * edge * args.ps
    # The cubes are elongated along y axis.
    cube[::2, :] /= 3

    mesh = Mesh(cube, traj_x, orientation=geom.Y_AX)
    mesh_2 = Mesh(cube, traj_y, orientation=geom.Y_AX)
    mesh_3 = Mesh(cube, traj_xy, orientation=geom.Y_AX)
    mesh_stationary = Mesh(cube, traj_stationary, orientation=geom.Y_AX)
    mesh_stationary_1 = Mesh(cube, traj_stationary_1, orientation=geom.Y_AX)
    mesh_stationary_2 = Mesh(cube, traj_stationary_2, orientation=geom.Y_AX)
    bodies = [mesh, mesh_2, mesh_3, mesh_stationary, mesh_stationary_1, mesh_stationary_2]
    composite = CompositeBody(traj_circle, bodies=bodies, orientation=geom.Y_AX)
    composite.bind_trajectory(args.ps)

    total_time = composite.time
    if args.t is None:
        times = np.linspace(0, 1, 100)
    else:
        if args.t < 0 or args.t > 1:
            raise ValueError('--t must be in the range [0, 1]')
        times = [args.t]

    im = None
    for index, i in enumerate(times):
        t = i * total_time
        composite.clear_transformation()
        composite.move(t)
        p = composite.project(args.shape, args.ps).get()
        if im is None:
            im = show(p, title='Projection')
        else:
            im.set_data(p)
            plt.draw()

    plt.show()
コード例 #7
0
def make_trajectory_sequence(args):
    # Make a small circle (1 / 10 of the pixel size), so that the composite body only rotates and
    # does not translate. Put this circle in the middle of the image.
    circle = args.n / 2 * args.ps + make_circle(
        n=1024).magnitude * args.ps / 10
    traj = Trajectory(circle, velocity=args.ps / q.s, pixel_size=args.ps)
    metaballs = _make_metaballs(args)
    composite = CompositeBody(traj, bodies=metaballs)

    im = None
    d_angle = 10 * q.deg
    fmt = 'Projection at rotation {:>9}'
    # Rotate around 360 deg
    for i, t in enumerate(
            np.linspace(0, traj.time.simplified.magnitude, 37) * q.s):
        # Reset transformation matrices
        composite.clear_transformation()
        # Move to the desired position, i.e. around the circle and then each metaball moves relative
        # to the composite body.
        composite.move(t)
        p = composite.project(args.shape, args.ps).get()
        if im is None:
            im = show(p, title=fmt.format(i * d_angle))
        else:
            im.axes.set_title(fmt.format(i * d_angle))
            im.set_data(p)
        plt.draw()

    plt.show()
コード例 #8
0
def make_manual_sequence(args):
    metaballs = _make_metaballs(args)
    traj = Trajectory([(args.n / 2., args.n / 2., 0)] * args.ps,
                      pixel_size=args.ps)
    composite = CompositeBody(traj, bodies=metaballs)
    # Move the sub-bodies relative to the composite body and also move the composite body to the
    # center of the image.
    composite.move(0 * q.s)

    im = None
    d_angle = 10 * q.deg
    fmt = 'Projection at rotation {:>9}'
    # Rotate around 360 deg
    for i in range(int((360 * q.deg / d_angle).magnitude) + 1):
        p = composite.project(args.shape, args.ps).get()
        if im is None:
            im = show(p, title=fmt.format(i * d_angle))
        else:
            im.axes.set_title(fmt.format(i * d_angle))
            im.set_data(p)
        plt.draw()
        # Rotation takes care of the relative rotation of the sub-bodies around the composite body.
        composite.rotate(d_angle, geom.Z_AX)

    plt.show()
コード例 #9
0
ファイル: composite_body.py プロジェクト: ufo-kit/syris
def make_trajectory_sequence(args):
    # Make a small circle (1 / 10 of the pixel size), so that the composite body only rotates and
    # does not translate. Put this circle in the middle of the image.
    circle = args.n / 2 * args.ps + make_circle(n=1024).magnitude * args.ps / 10
    traj = Trajectory(circle, velocity=args.ps / q.s, pixel_size=args.ps)
    metaballs = _make_metaballs(args)
    composite = CompositeBody(traj, bodies=metaballs)

    im = None
    d_angle = 10 * q.deg
    fmt = 'Projection at rotation {:>9}'
    # Rotate around 360 deg
    for i, t in enumerate(np.linspace(0, traj.time.simplified.magnitude, 37) * q.s):
        # Reset transformation matrices
        composite.clear_transformation()
        # Move to the desired position, i.e. around the circle and then each metaball moves relative
        # to the composite body.
        composite.move(t)
        p = composite.project(args.shape, args.ps).get()
        if im is None:
            im = show(p, title=fmt.format(i * d_angle))
        else:
            im.axes.set_title(fmt.format(i * d_angle))
            im.set_data(p)
        plt.draw()

    plt.show()
コード例 #10
0
ファイル: test_bodies.py プロジェクト: flmiot/syris-1
    def test_get_distance(self):
        n = 100
        ps = 100 * q.mm
        p = np.linspace(0, np.pi, n)
        sin = np.sin(p)
        cos = np.cos(p)
        zeros = np.zeros(n)

        # Simple body
        # -----------
        traj = Trajectory(zip(cos, sin, zeros) * q.m, velocity=1 * q.m / q.s)
        ball = MetaBall(traj, .5 * q.m)
        ball.bind_trajectory(ps)
        dist = ball.get_distance(0 * q.s, ball.trajectory.time)
        # Maximum along the x axis where the body travels 2 m by translation and rotates by 180
        # degrees compared to position at t0, so the rotational displacement is 2 * furthest point,
        # in this case 2 m, so altogether 4 m
        self.assertAlmostEqual(dist.simplified.magnitude, 4)

        # Composite body
        # --------------
        traj_m = Trajectory([(0, 0, 0)] * q.m)
        ball = MetaBall(traj_m, .5 * q.m)
        comp = CompositeBody(traj, bodies=[ball])
        comp.bind_trajectory(ps)

        d = comp.get_distance(0 * q.s, comp.time).simplified.magnitude
        # 2 by translation and 180 degrees means 2 * furthest
        gt = 2 * ball.furthest_point.simplified.magnitude + 2
        self.assertAlmostEqual(gt, d, places=4)

        d = comp.get_distance(0 * q.s, comp.time / 2).simplified.magnitude
        # 1 by translation by either x or y and sqrt(2) * furthest by rotation
        gt = 1 + comp.furthest_point.simplified.magnitude * np.sqrt(2)
        self.assertAlmostEqual(gt, d, places=4)
コード例 #11
0
ファイル: tomography_4D.py プロジェクト: ufo-kit/syris
def main():
    syris.init()
    args = parse_args()
    n = 256
    shape = (n, n)
    ps = 1 * q.um
    num_projections = None
    cube_edge = n / 4 * ps
    fmt = os.path.join(args.output, 'projection_{:04}.tif')

    x = np.linspace(n / 4 + n / 8, 3 * n / 4 + n / 8, num=10)
    y = z = np.zeros(x.shape)
    cube_0 = make_cube_body(n, ps, cube_edge)
    cube_1 = make_cube_body(n, ps, cube_edge, phase_shift=np.pi * q.rad)
    # Vertical motion component has such velocity that the cubes are displaced by their edge length
    # 1 pixel for making sure we have one "complete" sinogram
    velocity = (cube_edge - ps) / cube_0.trajectory.time
    traj_y = geom.Trajectory(zip(y, x, z) * ps, pixel_size=ps, velocity=velocity)
    composite = CompositeBody(traj_y, bodies=[cube_0, cube_1])
    # Total time is the rotation time because we want one tomographic data set
    total_time = cube_0.trajectory.time

    dt = composite.get_next_time(0 * q.s, ps)
    if num_projections is None:
        num_projections = int(np.ceil((total_time / dt).simplified.magnitude))

    print '              num_projs:', num_projections
    print '          rotation time:', cube_0.trajectory.time
    print '   vertical motion time:', traj_y.time
    print '        simulation time:', total_time

    for i in range(num_projections):
        t = total_time / num_projections * i
        composite.move(t)
        projection = composite.project(shape, ps).get()
        tifffile.imsave(fmt.format(i), projection)

    show(projection)
    plt.show()
コード例 #12
0
def main():
    args = parse_args()
    syris.init(device_index=0)
    n = 512
    shape = (n, n)
    ps = 1 * q.um

    x = np.linspace(0, n, num=10)
    y = z = np.zeros(x.shape)
    traj_x = Trajectory(zip(x, y, z) * ps, velocity=ps / q.s)
    traj_y = Trajectory(zip(y, x, z) * ps, velocity=ps / q.s)
    traj_xy = Trajectory(zip(n - x, x, z) * ps, velocity=ps / q.s)
    mb = MetaBall(traj_x, n * ps / 16)
    cube = make_cube() / q.m * 16 * ps
    mesh = Mesh(cube, traj_xy)
    composite = CompositeBody(traj_y, bodies=[mb, mesh])
    composite.bind_trajectory(ps)
    t = args.t * n * q.s

    composite.move(t)
    p = composite.project(shape, ps).get()
    show(p, title='Projection')

    plt.show()
コード例 #13
0
def main():
    syris.init()
    args = parse_args()
    n = 256
    shape = (n, n)
    ps = 1 * q.um
    num_projections = None
    cube_edge = n / 4 * ps
    fmt = os.path.join(args.output, "projection_{:04}.tif")

    x = np.linspace(n // 4 + n // 8, 3 * n // 4 + n // 8, num=10)
    y = z = np.zeros(x.shape)
    cube_0 = make_cube_body(n, ps, cube_edge)
    cube_1 = make_cube_body(n, ps, cube_edge, phase_shift=np.pi * q.rad)
    # Vertical motion component has such velocity that the cubes are displaced by their edge length
    # 1 pixel for making sure we have one "complete" sinogram
    velocity = (cube_edge - ps) / cube_0.trajectory.time
    traj_y = geom.Trajectory(list(zip(y, x, z)) * ps,
                             pixel_size=ps,
                             velocity=velocity)
    composite = CompositeBody(traj_y, bodies=[cube_0, cube_1])
    # Total time is the rotation time because we want one tomographic data set
    total_time = cube_0.trajectory.time

    dt = composite.get_next_time(0 * q.s, ps)
    if num_projections is None:
        num_projections = int(np.ceil((total_time / dt).simplified.magnitude))

    print("              num_projs:", num_projections)
    print("          rotation time:", cube_0.trajectory.time)
    print("   vertical motion time:", traj_y.time)
    print("        simulation time:", total_time)

    for i in range(num_projections):
        t = total_time / num_projections * i
        composite.move(t)
        projection = composite.project(shape, ps).get()
        imageio.imwrite(fmt.format(i), projection)

    show(projection)
    plt.show()
コード例 #14
0
ファイル: composite_body.py プロジェクト: ufo-kit/syris
def make_manual_sequence(args):
    metaballs = _make_metaballs(args)
    traj = Trajectory([(args.n / 2., args.n / 2., 0)] * args.ps, pixel_size=args.ps)
    composite = CompositeBody(traj, bodies=metaballs)
    # Move the sub-bodies relative to the composite body and also move the composite body to the
    # center of the image.
    composite.move(0 * q.s)

    im = None
    d_angle = 10 * q.deg
    fmt = 'Projection at rotation {:>9}'
    # Rotate around 360 deg
    for i in range(int((360 * q.deg / d_angle).magnitude) + 1):
        p = composite.project(args.shape, args.ps).get()
        if im is None:
            im = show(p, title=fmt.format(i * d_angle))
        else:
            im.axes.set_title(fmt.format(i * d_angle))
            im.set_data(p)
        plt.draw()
        # Rotation takes care of the relative rotation of the sub-bodies around the composite body.
        composite.rotate(d_angle, geom.Z_AX)

    plt.show()
コード例 #15
0
undu.trajectory.bind(detector.pixel_size)
#bm = make_topotomo(dE=dE, trajectory=source_trajectory, pixel_size=detector.pixel_size)
#bm.trajectory.bind(detector.pixel_size)

## == GAUSIAN FILTER (MONOCHROMATOR APPROX) ==
fwhm = dE_mono * energy * q.eV
sigma = smath.fwnm_to_sigma(fwhm, n=2)
fltr = GaussianFilter(energies, energy * q.eV, sigma)

# == SAMPLE ===
meshes = read_collada(OBJ_PATH, [(n / 2, n / 2, 0)] * detector.pixel_size,
                      iterations=1)

tr = Trajectory([(0 / 2, 0 / 2, 0)] * detector.pixel_size)

cb = CompositeBody(tr, bodies=meshes)
cb.bind_trajectory(detector.pixel_size)

airm = get_material('air_dry.mat')
cu = get_material('cu.mat')
air_gap = MaterialFilter(3 * q.m, airm)
abs_fltr = MaterialFilter(100 * q.um, cu)
# === MAKE EXPERIMENT ===
ex = Tomography([undu, fltr, abs_fltr, air_gap, cb], cb, undu, detector,
                [53.455, 0, 0, 32.477, 0.15] * q.m, energies)

# == CONDUCT EXPERIMENT
if OUTPUT is not None and not os.path.exists(OUTPUT):
    os.makedirs(OUTPUT, mode=0o755)

t_0 = 0 * q.s
コード例 #16
0
ファイル: test_bodies.py プロジェクト: flmiot/syris-1
class TestBodies(SyrisTest):
    def setUp(self):
        syris.init(device_index=0)
        self.pixel_size = 1 * q.um

        control_points = get_linear_points(geom.X, start=(1, 1, 1))
        traj = Trajectory(control_points, velocity=1 * q.mm / q.s)
        self.metaball = MetaBall(traj, 1 * q.mm)
        self.metaball_2 = MetaBall(Trajectory(get_linear_points(geom.Z)),
                                   2 * q.mm)
        self.composite = CompositeBody(traj,
                                       bodies=[self.metaball, self.metaball_2])

    def _get_moved_bounding_box(self, body, angle):
        body.translate((1, 0, 0) * q.mm)
        body.rotate(angle, np.array((0, 0, 1)))
        body.translate((1, 0, 0) * q.mm)

        base = -2 * body.radius.magnitude, 2 * body.radius.magnitude
        transformed = []
        for point in list(itertools.product(base, base, base)):
            transformed.append(
                geom.transform_vector(body.transform_matrix, point *
                                      body.radius.units).simplified.magnitude)

        return transformed * q.m

    def test_metaball(self):
        self.assertEqual(self.metaball.radius, 1 * q.mm)
        np.testing.assert_almost_equal(self.metaball.center,
                                       np.array([1, 1, 1]) * q.mm)

    def test_metaball_bounding_box(self):
        """Bounding box moves along with its body."""
        mb = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 0.5 * q.mm)
        transformed = self._get_moved_bounding_box(mb, 90 * q.deg)

        np.testing.assert_almost_equal(transformed, mb.bounding_box.points)

    def test_composite_subbodies(self):
        m_1 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 1 * q.mm)
        m_2 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 2 * q.mm)
        m_3 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 3 * q.mm)
        m_4 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 4 * q.mm)
        m_5 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 5 * q.mm)
        m_6 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 6 * q.mm)
        m_7 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 7 * q.mm)

        c_1 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm), bodies=[m_1, m_2])
        c_2 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm), bodies=[m_3])
        c_3 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm), bodies=[c_1, c_2])
        c_4 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm), bodies=[m_4, m_5])
        c_5 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm),
                            bodies=[c_3, c_4, m_6, m_7])

        # Empty composit body
        CompositeBody(Trajectory([(0, 0, 0)] * q.mm))

        # Empty composite body.
        c_empty = CompositeBody(Trajectory([(0, 0, 0)] * q.mm))
        self.assertEqual(c_empty.direct_primitive_bodies, [])

        # Test direct subbodies
        self.assertEqual(c_5.direct_primitive_bodies, [m_6, m_7])
        self.assertEqual(c_3.direct_primitive_bodies, [])

        # Add self.
        with self.assertRaises(ValueError) as ctx:
            c_5.add(c_5)
        self.assertEqual("Cannot add self", ctx.exception.message)

        # Add already contained primitive body.
        with self.assertRaises(ValueError) as ctx:
            c_5.add(m_1)
        self.assertTrue(ctx.exception.message.endswith("already contained"))

        # Add already contained composite body.
        with self.assertRaises(ValueError) as ctx:
            c_5.add(c_2)
        self.assertTrue(ctx.exception.message.endswith("already contained"))

        # Test all subbodies.
        self.assertEqual(set(c_3.all_bodies),
                         set([m_1, m_2, m_3, c_1, c_2, c_3]))
        self.assertEqual(set(c_1.all_bodies), set([c_1, m_1, m_2]))
        self.assertEqual(c_empty.all_bodies, (c_empty, ))

    def test_composite_bounding_box(self):
        mb_0 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 0.5 * q.mm)
        mb_1 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 1.5 * q.mm)
        composite = CompositeBody(Trajectory([(0, 0, 0)] * q.mm, ),
                                  bodies=[mb_0, mb_1])

        transformed_0 = self._get_moved_bounding_box(mb_0, 90 * q.deg)
        transformed_1 = self._get_moved_bounding_box(mb_1, -90 * q.deg)

        def get_concatenated(t_0, t_1, index):
            return np.concatenate((zip(*t_0)[index], zip(*t_1)[index])) * \
                t_0[0].units

        x_points = get_concatenated(transformed_0, transformed_1, 0)
        y_points = get_concatenated(transformed_0, transformed_1, 1)
        z_points = get_concatenated(transformed_0, transformed_1, 2)

        x_min_max = min(x_points), max(x_points)
        y_min_max = min(y_points), max(y_points)
        z_min_max = min(z_points), max(z_points)

        ground_truth = np.array(
            list(itertools.product(x_min_max, y_min_max, z_min_max))) * q.m

        np.testing.assert_almost_equal(ground_truth,
                                       composite.bounding_box.points)

    def test_composite_furthest_point(self):
        mb_0 = MetaBall(Trajectory([(0, 0, 0)] * q.m), 1 * q.m)
        mb_1 = MetaBall(Trajectory([(0, 0, 0)] * q.m), 2 * q.m)
        composite = CompositeBody(Trajectory([(0, 0, 0)] * q.m),
                                  bodies=[mb_0, mb_1])

        # Metaball's furthest point is twice the radius
        self.assertAlmostEqual(4 * q.m, composite.furthest_point)

    def test_save_transformation_matrix(self):
        old = self.composite.transform_matrix
        self.composite.bind_trajectory(self.pixel_size)
        self.composite.save_transformation_matrices()

        self.composite.move(1 * q.s)
        self.composite.restore_transformation_matrices()

        np.testing.assert_equal(old, self.composite.transform_matrix)

    def test_get_distance(self):
        n = 100
        ps = 100 * q.mm
        p = np.linspace(0, np.pi, n)
        sin = np.sin(p)
        cos = np.cos(p)
        zeros = np.zeros(n)

        # Simple body
        # -----------
        traj = Trajectory(zip(cos, sin, zeros) * q.m, velocity=1 * q.m / q.s)
        ball = MetaBall(traj, .5 * q.m)
        ball.bind_trajectory(ps)
        dist = ball.get_distance(0 * q.s, ball.trajectory.time)
        # Maximum along the x axis where the body travels 2 m by translation and rotates by 180
        # degrees compared to position at t0, so the rotational displacement is 2 * furthest point,
        # in this case 2 m, so altogether 4 m
        self.assertAlmostEqual(dist.simplified.magnitude, 4)

        # Composite body
        # --------------
        traj_m = Trajectory([(0, 0, 0)] * q.m)
        ball = MetaBall(traj_m, .5 * q.m)
        comp = CompositeBody(traj, bodies=[ball])
        comp.bind_trajectory(ps)

        d = comp.get_distance(0 * q.s, comp.time).simplified.magnitude
        # 2 by translation and 180 degrees means 2 * furthest
        gt = 2 * ball.furthest_point.simplified.magnitude + 2
        self.assertAlmostEqual(gt, d, places=4)

        d = comp.get_distance(0 * q.s, comp.time / 2).simplified.magnitude
        # 1 by translation by either x or y and sqrt(2) * furthest by rotation
        gt = 1 + comp.furthest_point.simplified.magnitude * np.sqrt(2)
        self.assertAlmostEqual(gt, d, places=4)

    @slow
    def test_get_next_time(self):
        n = 100
        ps = 100 * q.mm
        psm = ps.simplified.magnitude
        p = np.linspace(0, np.pi, n)
        sin = np.sin(p) * 1e-3
        cos = np.cos(p) * 1e-3
        zeros = np.zeros(n)

        traj_m_0 = Trajectory(zip(p * 1e-3, zeros, zeros) * q.m,
                              velocity=1 * q.mm / q.s)
        traj_m_1 = Trajectory([(0, 0, 0)] * q.m)
        ball_0 = MetaBall(traj_m_0, .5 * q.m)
        ball_1 = MetaBall(traj_m_1, .5 * q.m)
        traj = Trajectory(zip(cos, sin, zeros) * q.m, velocity=1 * q.mm / q.s)
        comp = CompositeBody(traj, bodies=[ball_0, ball_1])
        dt = comp.get_maximum_dt(ps)

        # Normal trajectories
        # Test the beginning, middle and end because of time complexity
        for t_0 in [0 * q.s, comp.time / 2, comp.time - 10 * dt]:
            t_1 = comp.get_next_time(t_0, ps)

            d = comp.get_distance(t_0, t_1).simplified.magnitude
            np.testing.assert_almost_equal(psm, d)

        # Trajectories which sum up to no movement
        traj_m = Trajectory(zip(zeros, -p, zeros) * q.m,
                            velocity=1 * q.mm / q.s)
        ball = MetaBall(traj_m, .5 * q.m)
        traj = Trajectory(zip(p, zeros, zeros) * q.m, velocity=1 * q.mm / q.s)
        comp = CompositeBody(traj, bodies=[ball])

        self.assertEqual(np.inf * q.s, comp.get_next_time(0 * q.s, ps))

    def test_static_composite(self):
        ps = 1 * q.um
        traj = Trajectory([(0, 0, 0)] * q.m)
        mb_0 = MetaBall(traj, 10 * q.um)
        mb_1 = MetaBall(traj, 10 * q.um)
        comp = CompositeBody(traj, bodies=[mb_0, mb_1])
        self.assertEqual(np.inf * q.s, comp.get_next_time(0 * q.s, ps))

    @opencl
    @slow
    def test_project_composite(self):
        n = 64
        shape = (n, n)
        ps = 1 * q.um
        x = np.linspace(0, n, num=10)
        y = z = np.zeros(x.shape)
        traj_x = Trajectory(zip(x, y, z) * ps, velocity=ps / q.s)
        traj_y = Trajectory(zip(y, x, z) * ps, velocity=ps / q.s)
        traj_xy = Trajectory(zip(n - x, x, z) * ps, velocity=ps / q.s)
        mb = MetaBall(traj_x, n * ps / 16)
        cube = make_cube() / q.m * 16 * ps / 4
        mesh = Mesh(cube, traj_xy)
        composite = CompositeBody(traj_y, bodies=[mb, mesh])
        composite.bind_trajectory(ps)

        composite.move(n / 2 * q.s)
        p = composite.project(shape, ps).get()
        composite.clear_transformation()

        # Compute
        composite.move(n / 2 * q.s)
        p_separate = (mb.project(shape, ps) + mesh.project(shape, ps)).get()

        np.testing.assert_almost_equal(p, p_separate)

    def _run_parallel_or_opposite(self, sgn, gt):
        n = 64
        ps = 1 * q.um
        y = np.linspace(0, sgn * n, num=10)
        x = z = np.zeros(y.shape)
        traj = Trajectory(zip(x, y, z) * ps, velocity=ps / q.s, pixel_size=ps)
        mb = MetaBall(traj, n * ps / 16, orientation=geom.Y_AX)

        mb.move(0 * q.s)
        np.testing.assert_almost_equal(gt, mb.transform_matrix)

    def test_opposite_trajectory(self):
        """Body's orientation is exactly opposite of the trajectory direction."""
        gt = geom.rotate(180 * q.deg, geom.Z_AX)
        self._run_parallel_or_opposite(-1, gt)

    def test_parallel_trajectory(self):
        """Body's orientation is exactly same as the trajectory direction."""
        gt = np.identity(4)
        self._run_parallel_or_opposite(1, gt)
コード例 #17
0
ファイル: test_bodies.py プロジェクト: flmiot/syris-1
    def test_project_composite(self):
        n = 64
        shape = (n, n)
        ps = 1 * q.um
        x = np.linspace(0, n, num=10)
        y = z = np.zeros(x.shape)
        traj_x = Trajectory(zip(x, y, z) * ps, velocity=ps / q.s)
        traj_y = Trajectory(zip(y, x, z) * ps, velocity=ps / q.s)
        traj_xy = Trajectory(zip(n - x, x, z) * ps, velocity=ps / q.s)
        mb = MetaBall(traj_x, n * ps / 16)
        cube = make_cube() / q.m * 16 * ps / 4
        mesh = Mesh(cube, traj_xy)
        composite = CompositeBody(traj_y, bodies=[mb, mesh])
        composite.bind_trajectory(ps)

        composite.move(n / 2 * q.s)
        p = composite.project(shape, ps).get()
        composite.clear_transformation()

        # Compute
        composite.move(n / 2 * q.s)
        p_separate = (mb.project(shape, ps) + mesh.project(shape, ps)).get()

        np.testing.assert_almost_equal(p, p_separate)
コード例 #18
0
def make_complex_trajectory_sequence(args):
    edge = 20
    x = np.linspace(0, args.n / 2 - args.n / 4 - edge - 5, num=10)
    y = z = np.zeros(x.shape)
    # Move along x axis
    traj_x = Trajectory(zip(x, y, z) * args.ps,
                        velocity=args.ps / q.s,
                        pixel_size=args.ps)
    # Move along y axis
    traj_y = Trajectory(zip(y, x, z) * args.ps,
                        velocity=args.ps / q.s,
                        pixel_size=args.ps)
    # Move along both x and y axes
    traj_xy = Trajectory(zip(x, x, z) * args.ps,
                         velocity=args.ps / q.s,
                         pixel_size=args.ps)
    # Circular trajectory of the composite body rotates around the image center and with radius
    # n / 4 pixels.
    circle = args.n / 2 * args.ps + make_circle(
    ).magnitude * args.n / 4 * args.ps
    traj_circle = Trajectory(circle,
                             velocity=args.ps / q.s,
                             pixel_size=args.ps)
    # Make the trajectory of the circle the same duration as the simple linear one.
    traj_circle = Trajectory(circle,
                             velocity=traj_circle.length / traj_xy.length *
                             args.ps / q.s)
    # three cubes in the same height and depth, shifted only along the x axis.
    traj_stationary = Trajectory([(0, 0, 0)] * args.ps)
    traj_stationary_1 = Trajectory([(-2 * edge, 0, 0)] * args.ps)
    traj_stationary_2 = Trajectory([(2 * edge, 0, 0)] * args.ps)

    cube = make_cube() / q.m * edge * args.ps
    # The cubes are elongated along y axis.
    cube[::2, :] /= 3

    mesh = Mesh(cube, traj_x, orientation=geom.Y_AX)
    mesh_2 = Mesh(cube, traj_y, orientation=geom.Y_AX)
    mesh_3 = Mesh(cube, traj_xy, orientation=geom.Y_AX)
    mesh_stationary = Mesh(cube, traj_stationary, orientation=geom.Y_AX)
    mesh_stationary_1 = Mesh(cube, traj_stationary_1, orientation=geom.Y_AX)
    mesh_stationary_2 = Mesh(cube, traj_stationary_2, orientation=geom.Y_AX)
    bodies = [
        mesh, mesh_2, mesh_3, mesh_stationary, mesh_stationary_1,
        mesh_stationary_2
    ]
    composite = CompositeBody(traj_circle,
                              bodies=bodies,
                              orientation=geom.Y_AX)
    composite.bind_trajectory(args.ps)

    total_time = composite.time
    if args.t is None:
        times = np.linspace(0, 1, 100)
    else:
        if args.t < 0 or args.t > 1:
            raise ValueError('--t must be in the range [0, 1]')
        times = [args.t]

    im = None
    for index, i in enumerate(times):
        t = i * total_time
        composite.clear_transformation()
        composite.move(t)
        p = composite.project(args.shape, args.ps).get()
        if im is None:
            im = show(p, title='Projection')
        else:
            im.set_data(p)
            plt.draw()

    plt.show()
コード例 #19
0
ファイル: test_bodies.py プロジェクト: flmiot/syris-1
    def test_composite_subbodies(self):
        m_1 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 1 * q.mm)
        m_2 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 2 * q.mm)
        m_3 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 3 * q.mm)
        m_4 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 4 * q.mm)
        m_5 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 5 * q.mm)
        m_6 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 6 * q.mm)
        m_7 = MetaBall(Trajectory([(0, 0, 0)] * q.mm), 7 * q.mm)

        c_1 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm), bodies=[m_1, m_2])
        c_2 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm), bodies=[m_3])
        c_3 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm), bodies=[c_1, c_2])
        c_4 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm), bodies=[m_4, m_5])
        c_5 = CompositeBody(Trajectory([(0, 0, 0)] * q.mm),
                            bodies=[c_3, c_4, m_6, m_7])

        # Empty composit body
        CompositeBody(Trajectory([(0, 0, 0)] * q.mm))

        # Empty composite body.
        c_empty = CompositeBody(Trajectory([(0, 0, 0)] * q.mm))
        self.assertEqual(c_empty.direct_primitive_bodies, [])

        # Test direct subbodies
        self.assertEqual(c_5.direct_primitive_bodies, [m_6, m_7])
        self.assertEqual(c_3.direct_primitive_bodies, [])

        # Add self.
        with self.assertRaises(ValueError) as ctx:
            c_5.add(c_5)
        self.assertEqual("Cannot add self", ctx.exception.message)

        # Add already contained primitive body.
        with self.assertRaises(ValueError) as ctx:
            c_5.add(m_1)
        self.assertTrue(ctx.exception.message.endswith("already contained"))

        # Add already contained composite body.
        with self.assertRaises(ValueError) as ctx:
            c_5.add(c_2)
        self.assertTrue(ctx.exception.message.endswith("already contained"))

        # Test all subbodies.
        self.assertEqual(set(c_3.all_bodies),
                         set([m_1, m_2, m_3, c_1, c_2, c_3]))
        self.assertEqual(set(c_1.all_bodies), set([c_1, m_1, m_2]))
        self.assertEqual(c_empty.all_bodies, (c_empty, ))