def rotation_matrix(self, angle): """Return the rotation matrix for ``angle``. For an angle ``phi``, the matrix is given by:: rot(phi) = [[cos(phi), -sin(phi)], [sin(phi), cos(phi)]] Parameters ---------- angle : float Rotation angle given in radians, must be contained in this geometry's `motion_params` Returns ------- rot : `numpy.ndarray`, shape (2, 2) The rotation matrix mapping the standard basis vectors in the fixed ("lab") coordinate system to the basis vectors of the local coordinate system of the detector reference point, expressed in the fixed system """ if angle not in self.motion_params: raise ValueError('`angle` {} not in the valid range {}' ''.format(angle, self.motion_params)) return euler_matrix(angle)
def astra_conebeam_2d_geom_to_vec(geometry): """Create vectors for ASTRA projection geometries from ODL geometry. The 2D vectors are used to create an ASTRA projection geometry for fan beam geometries, see ``'fanflat_vec'`` in the `ASTRA projection geometry documentation`_. Each row of the returned vectors corresponds to a single projection and consists of :: (srcX, srcY, dX, dY, uX, uY) with - ``src``: the ray source position - ``d`` : the center of the detector - ``u`` : the vector from detector pixel 0 to 1 Parameters ---------- geometry : `Geometry` ODL projection geometry from which to create the ASTRA geometry. Returns ------- vectors : `numpy.ndarray` Array of shape ``(num_angles, 6)`` containing the vectors. References ---------- .. _ASTRA projection geometry documentation: http://www.astra-toolbox.com/docs/geom2d.html#projection-geometries """ # Instead of rotating the data by 90 degrees counter-clockwise, # we subtract pi/2 from the geometry angles, thereby rotating the # geometry by 90 degrees clockwise rot_minus_90 = euler_matrix(-np.pi / 2) angles = geometry.angles vectors = np.zeros((angles.size, 6)) # Source position src_pos = geometry.src_position(angles) vectors[:, 0:2] = rot_minus_90.dot(src_pos.T).T # dot along 2nd axis # Center of detector mid_pt = geometry.det_params.mid_pt # Need to cast `mid_pt` to float since otherwise the empty axis is # not removed centers = geometry.det_point_position(angles, float(mid_pt)) vectors[:, 2:4] = rot_minus_90.dot(centers.T).T # Vector from detector pixel 0 to 1 det_axis = rot_minus_90.dot(geometry.det_axis(angles).T).T px_size = geometry.det_partition.cell_sides[0] vectors[:, 4:6] = det_axis * px_size return vectors
def rotation_matrix(self, angles): """Matrix defining the detector rotation at ``angles``. Parameters ---------- angles : `array-like` Angles in radians defining the rotation, must be contained in this geometry's ``motion_params`` Returns ------- rot : `numpy.ndarray`, shape ``(3, 3)`` The rotation matrix mapping the standard basis vectors in the fixed ("lab") coordinate system to the basis vectors of the local coordinate system of the detector reference point, expressed in the fixed system. """ if angles not in self.motion_params: raise ValueError('`angles` {} not in the valid range {}' ''.format(angles, self.motion_params)) return euler_matrix(*angles)