def setUp(self): default_syris_init() lens = Lens(3.0, f_number=1.4, focal_length=100.0 * q.mm) camera = Camera(1 * q.um, 0.1, 10, 1.0, 12, (64, 64)) detector = Detector(None, lens, camera) ps = detector.pixel_size t = np.linspace(0, 1, 10) * q.mm x = t y = np.zeros(len(t)) z = np.zeros(len(t)) points = list(zip(x, y, z)) * q.mm mb_0 = MetaBall( Trajectory(points, pixel_size=ps, furthest_point=1 * q.um, velocity=1 * q.mm / q.s), 1 * q.um, ) mb_1 = MetaBall( Trajectory(points, pixel_size=ps, furthest_point=1 * q.um, velocity=2 * q.mm / q.s), 1 * q.um, ) self.experiment = Experiment([mb_0, mb_1], None, detector, 0 * q.m, None)
def test_get_next_time(self): """Very small rotation circle but large object extent.""" def pr(v, decimals=2): return np.round(v, decimals) points = make_circle(n=128) * 1e-3 x, y, z = list(zip(*points)) furthest = 1 * q.mm ps = 10 * q.um tr = Trajectory(points, ps, furthest, velocity=1 * q.mm / q.s) t_0 = 0 * q.s t_1 = 0 * q.s max_diff = 0 * q.m while t_1 != np.inf * q.s: t_1 = tr.get_next_time(t_0) p_0 = tr.get_point(t_0) p_1 = tr.get_point(t_1) d_0 = tr.get_direction(t_0, norm=True) d_1 = tr.get_direction(t_1, norm=True) dp = np.abs(p_1 - p_0) dd = np.abs(d_1 - d_0) * furthest total = dp + dd ds = max(total) if ds > max_diff: max_diff = ds t_0 = t_1 max_diff = max_diff.rescale(q.um).magnitude ps = ps.rescale(q.um).magnitude np.testing.assert_almost_equal(ps, max_diff, decimal=2)
def test_stationary(self): traj = Trajectory(self.control_points) self.assertTrue(traj.stationary) traj = Trajectory(self.control_points, time_dist=self.time_dist) self.assertFalse(traj.stationary) traj = Trajectory(self.control_points, velocity=1 * q.mm / q.s) self.assertFalse(traj.stationary)
def test_get_point(self): # Stationary trajectory traj = Trajectory(self.control_points, pixel_size=1 * q.m, furthest_point=1 * q.m) np.testing.assert_equal(traj.get_point(1 * q.s), traj.control_points[0]) tck = interp.splprep(zip(*self.control_points), s=0)[0] def evaluate_point(t): if t > 1: t = 1 return interp.splev(t, tck) * q.m # Create velocity profile which goes until the trajectory end. # We need to scale the sine amplitude in order to # max(sin(x)) = trajectory.length times = np.linspace(0, 2 * np.pi, self.n) * q.s # Normalize for not going below zero. dist = (self.traj.length + self.traj.length * np.sin(times.magnitude)) * q.m traj = Trajectory(self.control_points, pixel_size=1 * q.m, furthest_point=1 * q.m, time_dist=zip(times, dist)) for i in range(len(times)): np.testing.assert_almost_equal(traj.get_point(times[i]), evaluate_point(dist[i] / traj.length), decimal=4)
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)
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_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_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_get_next_time(self): """Very small rotation circle but large object extent.""" def pr(v, decimals=2): return np.round(v, decimals) points = make_circle(n=128) * 1e-3 x, y, z = zip(*points) furthest = 1 * q.mm ps = 10 * q.um tr = Trajectory(points, ps, furthest, velocity=1 * q.mm / q.s) t_0 = 0 * q.s t_1 = 0 * q.s max_diff = 0 * q.m while t_1 != np.inf * q.s: t_1 = tr.get_next_time(t_0) p_0 = tr.get_point(t_0) p_1 = tr.get_point(t_1) d_0 = tr.get_direction(t_0, norm=True) d_1 = tr.get_direction(t_1, norm=True) dp = np.abs(p_1 - p_0) dd = np.abs(d_1 - d_0) * furthest total = dp + dd ds = max(total) if ds > max_diff: max_diff = ds t_0 = t_1 max_diff = max_diff.rescale(q.um).magnitude ps = ps.rescale(q.um).magnitude np.testing.assert_almost_equal(ps, max_diff, decimal=2)
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 test_init(self): def test_stationary(traj): self.assertEqual(traj.length, 0 * q.m) self.assertEqual(traj.time, 0 * q.s) # Stationary trajectory. traj = Trajectory([(0, 0, 0)] * q.m) test_stationary(traj) times = np.linspace(0, 2 * np.pi, self.n) dist = np.sin(times) # Length is zero but velocities given. traj = Trajectory([(0, 0, 0)] * q.m, list(zip(times, dist))) test_stationary(traj) # Length is non-zero but no velocities given. traj = Trajectory(self.control_points) test_stationary(traj) # Constant velocity. velocity = 10 * q.m / q.s traj = Trajectory(self.control_points, velocity=velocity) self.assertAlmostEqual(traj.length / velocity, traj.time) # Constant velocity and times and distances self.assertRaises( ValueError, Trajectory, self.control_points, time_dist=list(zip(times, dist)), velocity=10 * q.mm / q.s, ) # Invalid velocity profile (negative distance). self.assertRaises( ValueError, Trajectory, self.control_points, 1 * q.m, 1 * q.m, list(zip(times * q.s, dist * q.m)), ) # Time not monotonic. time_dist = [(1 * q.s, 1 * q.m), (1 * q.s, 1 * q.m)] self.assertRaises(ValueError, Trajectory, self.control_points, 1 * q.m, 1 * q.m, time_dist) time_dist = [(1 * q.s, 1 * q.m), (0 * q.s, 1 * q.m)] self.assertRaises(ValueError, Trajectory, self.control_points, 1 * q.m, 1 * q.m, time_dist) # Negative time. time_dist = [(-1 * q.s, 1 * q.m), (1 * q.s, 1 * q.m)] self.assertRaises(ValueError, Trajectory, self.control_points, 1 * q.m, 1 * q.m, time_dist)
def test_bind(self): traj = Trajectory(self.control_points, time_dist=self.time_dist) self.assertFalse(traj.bound) traj.bind(pixel_size=1 * q.m, furthest_point=1 * q.um) self.assertTrue(traj.bound) # Trajectory with no furthest point must work too traj.bind(pixel_size=1 * q.m) self.assertTrue(traj.bound) # Binding stationary trajectory must be possible traj = Trajectory([(0, 0, 0)] * q.m) traj.bind(pixel_size=100 * q.mm) self.assertTrue(traj.bound)
def test_transfer(self): shape = 10 # No trajectory self.source.transfer(shape, self.ps, self.energies[0], t=0 * q.s) # Width may be larger self.source.transfer((shape, 2 * shape), self.ps, self.energies[0], t=0 * q.s) # With trajectory n = 16 x = z = np.zeros(n) y = np.linspace(0, 1, n) * q.mm tr = Trajectory(zip(x, y, z) * q.mm, pixel_size=10 * q.um, furthest_point=0*q.m, velocity=1 * q.mm / q.s) source = BendingMagnet(2.5 * q.GeV, 150 * q.mA, 1.5 * q.T, 30 * q.m, self.dE, np.array([0.2, 0.8]) * q.mm, self.ps, trajectory=tr) im_0 = source.transfer(shape, self.ps, self.energies[0], t=0 * q.s).get() im_1 = source.transfer(shape, self.ps, self.energies[0], t=tr.time / 2).get() # There must be a difference between two different times and given trajectory self.assertGreater(np.abs(im_1 - im_0).max(), 0) # Test exponent u = source.transfer(shape, self.ps, self.energies[0], exponent=False).get() u_exp = source.transfer(shape, self.ps, self.energies[0], exponent=True).get() np.testing.assert_almost_equal(u, np.exp(u_exp))
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()
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()
def make_topotomo(dE=None, trajectory=None, pixel_size=None, ring_current=200 * q.mA): """Make the TopoTomo bending magnet source located at ANKA, KIT. Use *dE* for energy spacing (1 keV if not specified), *trajectory* for simulating beam fluctuations. If it is None a (1024, 1024) window is used with the beam center in the middle and no fluctuations. *pixel_size* specifies the pixel spacing between the window points, if not specified 1 um is used. *ring_current* is the storage ring electric current. """ if not pixel_size: pixel_size = 1 * q.um if not trajectory: trajectory = Trajectory([(512, 512, 0)] * pixel_size) if not dE: dE = 1 * q.keV return BendingMagnet( 2.5 * q.GeV, ring_current, 1.5 * q.T, 30 * q.m, dE, (142, 503) * q.um, pixel_size, trajectory, )
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))
def main(): args = parse_args() syris.init() n = 1024 d = args.propagation_distance * q.m shape = (n, n) ps = 1 * q.um energy = 20 * q.keV tr = Trajectory([(n / 2, n / 2, 0)] * ps, pixel_size=ps) sample = make_sphere(n, n / 30 * ps, pixel_size=ps, material=get_material('air_5_30_kev.mat')) bm = make_topotomo(pixel_size=ps, trajectory=tr) print 'Source size FWHM (height x width): {}'.format(bm.size.rescale(q.um)) u = bm.transfer(shape, ps, energy, t=0 * q.s) u = sample.transfer(shape, ps, energy) intensity = propagate([sample], shape, [energy], d, ps).get() incoh = bm.apply_blur(intensity, d, ps).get() region = (n / 4, n / 4, n / 2, n / 2) intensity = ip.crop(intensity, region).get() incoh = ip.crop(incoh, region).get() show(intensity, title='Coherent') show(incoh, title='Applied source blur') plt.show()
def process(args, device_index): import syris from syris.geometry import Trajectory from syris.bodies.mesh import Mesh, read_blender_obj syris.init(device_index=device_index, logfile=args.logfile, double_precision=args.double_precision) path, ext = os.path.splitext(args.input) if ext == ".obj": tri = read_blender_obj(args.input) else: tri = np.load(args.input) tri = tri * q.um tr = Trajectory([(0, 0, 0)] * q.um) mesh = Mesh(tri, tr, center=None, iterations=args.supersampling_projection) if args.n: n = args.n fov = n * args.pixel_size else: fov = max([ends[1] - ends[0] for ends in mesh.extrema[:-1]]) * 1.1 n = int(np.ceil((fov / args.pixel_size).simplified.magnitude)) shape = (n, n) if args.make_gt: LOG.info("--- Args info ---") log_attributes(args) return make_ground_truth(args, shape, mesh) else: num_projs = int( np.pi * n) if args.num_projections is None else args.num_projections angles = np.linspace(0, args.rotation_angle, num_projs, endpoint=False) * q.deg if device_index == 0: LOG.info("n: {}, ps: {}, FOV: {}".format(n, args.pixel_size, fov)) LOG.info("Total rotation angle: {} deg".format( args.rotation_angle)) LOG.info("Number of projections: {}".format(num_projs)) LOG.info("--- Mesh info ---") log_attributes(mesh) LOG.info("--- Args info ---") log_attributes(args) return scan( shape, args.pixel_size, args.rotation_axis, mesh, angles, args.prefix, lamino_angle=args.lamino_angle, index=device_index, num_devices=args.num_devices, ss=args.supersampling, )
def test_get_maximum_dt(self): """Test that we don't move by more than the pixel size between two consecutive times.""" # Stationary trajectory traj = Trajectory([(0, 0, 0)] * q.m, pixel_size=1 * q.m, furthest_point=1 * q.m) self.assertEqual(traj.get_maximum_dt(), None) # Moving trajectory tr, dtck, ps, times = create_maxima_testing_data() max_dt = tr.get_maximum_dt(distance=ps).simplified.magnitude # Make sure we are actually making too large steps with the original interpolation assert max_dt < np.max(np.gradient(tr.times.simplified.magnitude)) times = np.arange(times[0].simplified.magnitude, times[-1].simplified.magnitude, max_dt) u = interp.splev(times, tr.time_tck) / tr.length.simplified.magnitude du = np.gradient(u) distance = np.max(np.abs(np.array(interp.splev(u, dtck, der=1)) * du)) * 1e3 np.testing.assert_almost_equal(ps.rescale(q.mm).magnitude, distance, decimal=1)
def create_maxima_testing_data(): n = 128 points = make_circle(n=n) * 1e3 ps = 10 * q.mm furthest = 1 * q.m tr = Trajectory(points, ps, furthest, velocity=1 * q.m / q.s) duration = tr.time.simplified.magnitude t = np.linspace(0, 2 * duration, n) * q.s # Sine-like velocity profile s = 0.5 * tr.length * (np.sin(t.magnitude / duration * 2 * np.pi) + 1) time_dist = list(zip(t, s)) # Use small num_points to make sure we move more than 1 px tr = Trajectory(points, ps, furthest, time_dist=time_dist, num_points=n) distances = tr.get_distances() dtck = interp.splprep(distances, u=tr.parameter, s=0, k=1)[0] return tr, dtck, ps, t
def create_maxima_testing_data(): n = 128 points = make_circle(n=n) * 1e3 ps = 10 * q.mm furthest = 1 * q.m tr = Trajectory(points, ps, furthest, velocity=1 * q.m / q.s) duration = tr.time.simplified.magnitude t = np.linspace(0, 2 * duration, n) * q.s # Sine-like velocity profile s = 0.5 * tr.length * (np.sin(t.magnitude / duration * 2 * np.pi) + 1) time_dist = zip(t, s) # Use small num_points to make sure we move more than 1 px tr = Trajectory(points, ps, furthest, time_dist=time_dist, num_points=n) distances = tr.get_distances() dtck = interp.splprep(distances, u=tr.parameter, s=0, k=1)[0] return tr, dtck, ps, t
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_get_distances(self): """Compare analytically computed distances with the ones obtained from trajectory.""" points = make_circle(n=128) x, y, z = zip(*points) furthest = 3 * q.mm ps = 10 * q.um tr = Trajectory(points, ps, furthest, velocity=1 * q.mm / q.s) d_points = np.abs(tr.points[:, 0][:, np.newaxis] - tr.points) t = np.linspace(0, 2 * np.pi, tr.points.shape[1]) x, y, z = zip(*make_circle(n=tr.points.shape[1])) dx = -np.sin(t) dy = np.cos(t) dz = z derivatives = np.array(zip(dx, dy, dz)).T.copy() d_derivatives = get_rotation_displacement(derivatives[:, 0], derivatives, furthest) distances = (d_points + d_derivatives).simplified.magnitude np.testing.assert_almost_equal(distances, tr.get_distances())
def setUp(self): # Double precision needed for spherical phase profile default_syris_init() self.ps = 1 * q.um self.n = 128 self.size = (100, 100) * q.um self.sample_dist = 30 * q.m self.dE = 1 * q.keV self.energies = np.arange(1, 39, self.dE.magnitude) * q.keV self.trajectory = Trajectory([(self.n / 2, self.n / 2, 0)] * self.ps)
def test_get_distances(self): """Compare analytically computed distances with the ones obtained from trajectory.""" points = make_circle(n=128) x, y, z = list(zip(*points)) furthest = 3 * q.mm ps = 10 * q.um tr = Trajectory(points, ps, furthest, velocity=1 * q.mm / q.s) d_points = np.abs(tr.points[:, 0][:, np.newaxis] - tr.points) t = np.linspace(0, 2 * np.pi, tr.points.shape[1]) x, y, z = list(zip(*make_circle(n=tr.points.shape[1]))) dx = -np.sin(t) dy = np.cos(t) dz = z derivatives = np.array(list(zip(dx, dy, dz))).T.copy() d_derivatives = get_rotation_displacement(derivatives[:, 0], derivatives, furthest) distances = (d_points + d_derivatives).simplified.magnitude np.testing.assert_almost_equal(distances, tr.get_distances())
def test_length(self): u = np.linspace(0, 2 * np.pi, 100) x = np.sin(u) y = np.cos(u) z = np.zeros(len(u)) traj = Trajectory(zip(x, y, z) * q.m, velocity=1 * q.m / q.s, pixel_size=1 * q.m, furthest_point=1 * q.m) self.assertAlmostEqual(traj.length, 2 * np.pi * q.m, places=5)
def setUp(self): # Double precision needed for spherical phase profile syris.init(double_precision=True, device_index=0) self.dE = 0.1 * q.keV self.energies = np.arange(14.8, 15, self.dE.magnitude) * q.keV self.trajectory = Trajectory([(0, 0, 0)] * q.m) self.ps = 10 * q.um self.source = BendingMagnet(2.5 * q.GeV, 150 * q.mA, 1.5 * q.T, 30 * q.m, self.dE, np.array([0.2, 0.8]) * q.mm, self.ps, self.trajectory)
def test_get_point(self): # Stationary trajectory traj = Trajectory(self.control_points, pixel_size=1 * q.m, furthest_point=1 * q.m) np.testing.assert_equal(traj.get_point(1 * q.s), traj.control_points[0]) tck = interp.splprep(list(zip(*self.control_points)), s=0)[0] def evaluate_point(t): if t > 1: t = 1 return interp.splev(t, tck) * q.m # Create velocity profile which goes until the trajectory end. # We need to scale the sine amplitude in order to # max(sin(x)) = trajectory.length times = np.linspace(0, 2 * np.pi, self.n) * q.s # Normalize for not going below zero. dist = (self.traj.length + self.traj.length * np.sin(times.magnitude)) * q.m traj = Trajectory( self.control_points, pixel_size=1 * q.m, furthest_point=1 * q.m, time_dist=list(zip(times, dist)), ) for i in range(len(times)): np.testing.assert_almost_equal(traj.get_point(times[i]), evaluate_point(dist[i] / traj.length), decimal=4)
def main(): args = parse_args() syris.init(device_index=0) shape = (args.n, args.n) pixel_size = 1 * q.um if args.method == "random": # Random metaballs creation metaballs, objects_all = create_metaballs_random( args.n, pixel_size, args.num, args.min_radius, args.max_radius, distance_from_center=args.distance_from_center, ) elif args.method == "file": # 1e6 because packing converts to meters values = np.fromfile(args.input, dtype=np.float32) * 1e6 metaballs, objects_all = create_metaballs( values.reshape(len(values) // 4, 4), pixel_size) else: distance = args.distance or args.n / 4 positions = [ (args.n / 2 - distance, args.n / 2, 0, args.n / 6), (args.n / 2 + distance, args.n / 2, 0, args.n / 6), ] metaballs, objects_all = create_metaballs(positions, pixel_size) if args.output: with open(args.output, mode="wb") as out_file: out_file.write(objects_all) z_min, z_max = get_z_range(metaballs) print("z min, max:", z_min.rescale(q.um), z_max.rescale(q.um), args.n * pixel_size + z_min) if args.algorithm == "fast": traj = Trajectory([(0, 0, 0)] * q.m) comp = MetaBalls(traj, metaballs) thickness = comp.project(shape, pixel_size).get() else: print("Z steps:", int(((z_max - z_min) / pixel_size).simplified.magnitude + 0.5)) thickness = project_metaballs_naive(metaballs, shape, make_tuple(pixel_size)).get() if args.output_thickness: imageio.imwrite(args.output_thickness, thickness) show(thickness) plt.show()
def setUp(self): self.n = 100 x = np.linspace(0, 2 * np.pi, self.n) # + 1 not to go below zero. y = 1 + np.sin(x) z = np.zeros(self.n) self.time_dist = zip(x * q.s, y * q.m) self.control_points = zip(x, y, z) * q.m self.traj = Trajectory(self.control_points, pixel_size=1 * q.mm, furthest_point=1 * q.mm, time_dist=self.time_dist)
def main(): args = parse_args() syris.init() n = 1024 shape = (n, n) ps = 1 * q.um tr = Trajectory([(n / 2, n / 2, 0)] * ps, pixel_size=ps) energy_center = args.energy_center * q.keV fwhm = args.energy_resolution * energy_center sigma = smath.fwnm_to_sigma(fwhm, n=2) # Make sure we resolve the curve nicely energies = np.arange(max(1 * q.keV, energy_center - 2 * fwhm), energy_center + 2 * fwhm, fwhm / 25) * q.keV dE = energies[1] - energies[0] print 'Energy from, to, step, number:', energies[0], energies[-1], dE, len( energies) bm = make_topotomo(dE=dE, pixel_size=ps, trajectory=tr) spectrum_energies = np.arange(1, 50, 1) * q.keV native_spectrum = get_spectrum(bm, spectrum_energies, ps) fltr = GaussianFilter(energies, energy_center, sigma) gauss = get_gauss(energies.magnitude, energy_center.magnitude, sigma.magnitude) filtered_spectrum = get_spectrum(bm, energies, ps) * gauss intensity = propagate([bm, fltr], shape, energies, 0 * q.m, ps).get() show(intensity, title='Intensity for energy range {} - {}'.format( energies[0], energies[-1])) plt.figure() plt.plot(spectrum_energies.magnitude, native_spectrum) plt.title('Source Spectrum') plt.xlabel('Energy [keV]') plt.ylabel('Intensity') plt.figure() plt.plot(energies.magnitude, gauss) plt.title('Gaussian Filter') plt.xlabel('Energy [keV]') plt.ylabel('Transmitted intensity') plt.figure() plt.plot(energies.magnitude, filtered_spectrum) plt.title('Filtered Spectrum') plt.xlabel('Energy [keV]') plt.ylabel('Intensity') plt.show()
def test_get_maximum_dt(self): """Test that we don't move by more than the pixel size between two consecutive times.""" # Stationary trajectory traj = Trajectory([(0, 0, 0)] * q.m, pixel_size=1 * q.m, furthest_point=1 * q.m) self.assertEqual(traj.get_maximum_dt(), None) # Moving trajectory tr, dtck, ps, times = create_maxima_testing_data() max_dt = tr.get_maximum_dt(distance=ps).simplified.magnitude # Make sure we are actually making too large steps with the original interpolation assert max_dt < np.max(np.gradient(tr.times.simplified.magnitude)) times = np.arange(times[0].simplified.magnitude, times[-1].simplified.magnitude, max_dt) u = interp.splev(times, tr.time_tck) / tr.length.simplified.magnitude du = np.gradient(u) distance = np.max(np.abs( np.array(interp.splev(u, dtck, der=1)) * du)) * 1e3 np.testing.assert_almost_equal(ps.rescale(q.mm).magnitude, distance, decimal=1)
def create_metaballs(params, pixel_size): x, y, z, r = list(zip(*params)) objects = b"" metaballs = [] for i in range(len(params)): c_points = [(x[i], y[i], z[i])] * q.um trajectory = Trajectory(c_points, pixel_size=pixel_size) metaball = MetaBall(trajectory, r[i] * q.um) metaball.move(0 * q.s) metaballs.append(metaball) objects += metaball.pack() return metaballs, objects
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()