def __init__(self, angles, axes_order, name=None): if len(angles) != len(axes_order): raise InputParameterError( "Number of angles must equal number of axes in axes_order.") self.axes = ['x', 'y', 'z'] unrecognized = set(axes_order).difference(self.axes) if unrecognized: raise ValueError("Unrecognized axis label {0}; " "should be one of {1} ".format( unrecognized, self.axes)) self.axes_order = axes_order self._func_map = {'x': self._xrot, 'y': self._yrot, 'z': self._zrot} super(Rotation3DToGWA, self).__init__(angles, name=name)
def __init__(self, amplitude=amplitude.default, x_mean=x_mean.default, y_mean=y_mean.default, x_stddev=None, y_stddev=None, theta=None, cov_matrix=None, **kwargs): if cov_matrix is None: if x_stddev is None: x_stddev = self.__class__.x_stddev.default if y_stddev is None: y_stddev = self.__class__.y_stddev.default if theta is None: theta = self.__class__.theta.default else: if x_stddev is not None or y_stddev is not None or theta is not None: raise InputParameterError("Cannot specify both cov_matrix and " "x/y_stddev/theta") else: # Compute principle coordinate system transformation cov_matrix = np.array(cov_matrix) if cov_matrix.shape != (2, 2): # TODO: Maybe it should be possible for the covariance matrix # to be some (x, y, ..., z, 2, 2) array to be broadcast with # other parameters of shape (x, y, ..., z) # But that's maybe a special case to work out if/when needed raise ValueError("Covariance matrix must be 2x2") eig_vals, eig_vecs = np.linalg.eig(cov_matrix) x_stddev, y_stddev = np.sqrt(eig_vals) y_vec = eig_vecs[:, 0] theta = np.arctan2(y_vec[1], y_vec[0]) # Ensure stddev makes sense if its bounds are not explicitly set. # stddev must be non-zero and positive. # TODO: Investigate why setting this in Parameter above causes # convolution tests to hang. kwargs.setdefault('bounds', {}) kwargs['bounds'].setdefault('x_stddev', (FLOAT_EPSILON, None)) kwargs['bounds'].setdefault('y_stddev', (FLOAT_EPSILON, None)) super().__init__( amplitude=amplitude, x_mean=x_mean, y_mean=y_mean, x_stddev=x_stddev, y_stddev=y_stddev, theta=theta, **kwargs)
def _compute_matrix(angles, axes_order): if len(angles) != len(axes_order): raise InputParameterError( "Number of angles must equal number of axes in axes_order.") matrices = [] for angle, axis in zip(angles, axes_order): matrix = np.zeros((3, 3), dtype=np.float) if axis == 'x': mat = Rotation3D.rotation_matrix_from_angle(angle) matrix[0, 0] = 1 matrix[1:, 1:] = mat elif axis == 'y': mat = Rotation3D.rotation_matrix_from_angle(-angle) matrix[1, 1] = 1 matrix[0, 0] = mat[0, 0] matrix[0, 2] = mat[0, 1] matrix[2, 0] = mat[1, 0] matrix[2, 2] = mat[1, 1] elif axis == 'z': mat = Rotation3D.rotation_matrix_from_angle(angle) matrix[2, 2] = 1 matrix[:2, :2] = mat else: raise ValueError("Expected axes_order to be a combination \ of characters 'x', 'y' and 'z', got {0}".format( set(axes_order).difference(['x', 'y', 'z']))) matrices.append(matrix) if len(angles) == 1: return matrix elif len(matrices) == 2: return np.dot(matrices[1], matrices[0]) else: prod = np.dot(matrices[1], matrices[0]) for m in matrices[2:]: prod = np.dot(m, prod) return prod