def rot90_director(data, axis="+x", out=None): """ Rotate a director field by 90 degrees around the specified axis. Parameters ---------- data: array_like Array specifying director field with ndim = 4. axis: str Axis around which to perform rotation. Can be in the form of '[s][n]X' where the optional parameter 's' can be "+" or "-" decribing the sign of rotation. [n] is an integer describing number of rotations to perform, and 'X' is one of 'x', 'y' 'z', and defines rotation axis. out : ndarray, optional Output array. Returns ------- y : ndarray A rotated director field See Also -------- data.rotate_director : a general rotation for arbitrary angle. """ nz, ny, nx, nv = data.shape axis_name = axis[-1] try: k = int(axis[:-1]) except ValueError: k = int(axis[:-1] + "1") angle = np.pi / 2 * k if axis_name == "x": r = rotation_matrix_x(angle) axes = (1, 0) elif axis_name == "y": r = rotation_matrix_y(angle) axes = (0, 2) elif axis_name == "z": r = rotation_matrix_z(angle) axes = (2, 1) else: raise ValueError("Unknown axis type {}".format(axis_name)) data_rot = np.rot90(data, k=k, axes=axes) #first rotate data points return rotate_vector(r, data_rot, out) #rotate vector in each voxel
def rotate_director(rmat, data, method="linear", fill_value=(0., 0., 0.), norm=True, out=None): """ Rotate a director field around the center of the compute box by a specified rotation matrix. This rotation is lossy, as datapoints are interpolated. The shape of the output remains the same. Parameters ---------- rmat : array_like A 3x3 rotation matrix. data: array_like Array specifying director field with ndim = 4 method : str Interpolation method "linear" or "nearest" fill_value : numbers, optional If provided, the values (length 3 vector) to use for points outside of the interpolation domain. Defaults to (0.,0.,0.). norm : bool, Whether to normalize the length of the director to 1. after rotation (interpolation) is performed. Because of interpolation error, the length of the director changes slightly, and this options adds a constant length constraint to reduce the error. out : ndarray, optional Output array. Returns ------- y : ndarray A rotated director field See Also -------- data.rot90_director : a lossless rotation by 90 degrees. """ from scipy.interpolate import RegularGridInterpolator verbose_level = DTMMConfig.verbose if verbose_level > 0: print("Rotating director.") out = np.empty_like(data) nz, ny, nx, nv = data.shape shape = (nz, ny, nx) az, ay, ax = [np.arange(-l / 2. + .5, l / 2. + .5) for l in shape] fillx, filly, fillz = fill_value xdir = RegularGridInterpolator((az, ay, ax), data[..., 0], fill_value=fillx, bounds_error=False, method=method) ydir = RegularGridInterpolator((az, ay, ax), data[..., 1], fill_value=filly, bounds_error=False, method=method) zdir = RegularGridInterpolator((az, ay, ax), data[..., 2], fill_value=fillz, bounds_error=False, method=method) zz, yy, xx = np.meshgrid(az, ay, ax, indexing="ij", copy=False, sparse=True) out[..., 0] = xx out[..., 1] = yy out[..., 2] = zz out = rotate_vector(rmat.T, out, out) #rotate coordinates #out2 = out.copy() #out2[...,0] = out[...,2] #out2[...,2] = out[...,0] out2 = out[..., ::-1] #reverse direction instead of copying #interpolate new director field xnew = xdir(out2) ynew = ydir(out2) znew = zdir(out2) out[..., 0] = xnew out[..., 1] = ynew out[..., 2] = znew rotate_vector(rmat, out, out) #rotate vector in each voxel if norm == True: s = director2order(out) mask = (s == 0.) s[mask] = 1. return np.divide(out, s[..., None], out) return
size_x = pitch_x * 1 size_z = pitch_z * 2 tilt = np.arctan(pitch_z / pitch_x) twist = np.arange( 0, 2 * np.pi * size_z / pitch_z, 2 * np.pi / pitch_z)[:, None] + np.arange( 0, 2 * np.pi * size_x / pitch_x, 2 * np.pi / pitch_x)[None, :] director = np.empty(shape=twist.shape + (3, )) director[..., 0] = np.cos(twist) #x component director[..., 1] = np.sin(twist) #y component director[..., 2] = 0 # z component r = rotation.rotation_matrix_y(tilt) director = rotation.rotate_vector(r, director) epsa = data.director2angles(director) #: box dimensions NLAYERS, HEIGHT, WIDTH = twist.shape[0], twist.shape[1], 1 d = np.ones(shape=(NLAYERS, )) epsv = np.empty(shape=(NLAYERS, HEIGHT, 3), dtype=dtmm.conf.CDTYPE) epsv[..., 0] = no**2 epsv[..., 1] = no**2 epsv[..., 2] = ne**2 beta, phi, intensity = 0, 0, 1