calc_projection_shell#
- pypulseqpp.calc_projection_shell()[source]#
Return a pole-to-pole base shell and z-axis rotations for each shot.
Consecutive base directions have equal angular separation. Rotated shells share both poles; each nonpolar ring has one spoke per shot.
- Parameters:
n_views (int) – Spokes in the base shell, at least three.
n_shots (int, default=1) – Rotated replays of that shell.
scheme ({'spiral', 'meridian'}, default='spiral') –
'spiral'winds pole to pole across equal-area rings, so the shell alone is already near-uniform.'meridian'is a half great circle in the x-z plane at equal polar steps, which is simpler and oversamples the poles.
- Returns:
directions (numpy.ndarray) – Unit spoke directions of the base shell, shape
(n_views, 3).rotations (numpy.ndarray) – Rotation matrices, shape
(n_shots, 3, 3), each turning the whole shell to where that shot samples.
- Raises:
ValueError – If a count is out of range or
schemeis unknown.
Examples
>>> import numpy as np >>> import pypulseqpp as pp >>> directions, rotations = pp.calc_projection_shell(32, n_shots=13) >>> directions.shape, rotations.shape ((32, 3), (13, 3, 3))
The shell runs pole to pole, so the shot rotations leave its ends alone:
>>> bool(np.allclose(directions[[0, -1]], [[0, 0, 1], [0, 0, -1]])) True
Consecutive views are exactly one step apart, so every turn between them is the same slew:
>>> steps = np.arccos(np.clip(np.sum(directions[:-1] * directions[1:], axis=1), -1, 1)) >>> bool(np.ptp(steps) < 1e-9) True
See also
calc_golden_anglesin-plane spoke angles, one per shot, for 2D radial.