def test_is_group(self): for grp in groups: print(grp) ops = crystallography.symmetry_rotations(grp) self.assertTrue(self.includes_identity(ops)) self.assertTrue(self.closed(ops)) self.assertTrue(self.has_inverse(ops))
def project_ipf(q, lattice, direction, sample_symmetry = crystallography.symmetry_rotations("222"), x = [1,0,0], y = [0,1,0]): """ Project a single sample direction onto a crystal Parameters: q: lattice orientation lattice: lattice object describing the crystal system direction: sample direction Keyword Args: sample_symmetry: sample symmetry operators x: x direction (crystallographic) of the projection y: y direction (crystallographic) of the projection """ xv = lattice.miller2cart_direction(x).normalize() yv = lattice.miller2cart_direction(y).normalize() if not np.isclose(xv.dot(yv),0.0): raise ValueError("Lattice directions are not orthogonal!") zv = xv.cross(yv) trans = rotations.Orientation(np.vstack((xv.data,yv.data,zv.data))) d = tensors.Vector(direction).normalize() pts = [] for srot in sample_symmetry: # Sample directions spt = srot.apply(d) # Crystal coordinates cpt = q.apply(spt) # Lattice symmetry for op in lattice.symmetry.ops: cppt = op.apply(cpt) # Into the right coordinates fpt = trans.apply(cppt) pts.append(fpt.data) # By convention just keep the points in the upper hemisphere pts = np.array(pts) pts = pts[pts[:,2]>0] return pts
def test_definition(self): for grp in groups: print(grp) self.compare(ktw_rotational_groups(grp), crystallography.symmetry_rotations(grp))
def pole_figure_discrete(orientations, pole, lattice, projection = "stereographic", sample_symmetry = crystallography.symmetry_rotations("222"), x = tensors.Vector([1.0,0,0]), y = tensors.Vector([0,1.0,0]), axis_labels = ["X", "Y"]): """ Plot a standard pole figure given a collection of discrete points. Parameters: orientations: list of orientations pole: pole as a integer list lattice: crystal lattice class, including crystal symmetry Keyword Args: projection: which projection to use sample_symmetry: what sample symmetry to apply to the pole figure, defaults to orthorhombic x: x direction for plot, defaults to [1,0,0] y: y direction for plot, defaults to [0,1,0] axis_labels: axis labels to include on the figure """ # Get the rotation from the standard coordinates to the given x and y srot = rotations.Orientation(x,y) # Get all equivalent poles p = lattice.miller2cart_direction(pole) eq_poles = lattice.equivalent_vectors(p) eq_poles = [pp.normalize() for pp in eq_poles] # Apply sample symmetric eq_poles = [op.apply(p) for p in eq_poles for op in sample_symmetry] # Get the points on the sphere pts = [srot.apply(o.inverse().apply(pp)) for pp in eq_poles for o in orientations] # Get rid of those that are in the lower hemisphere pts = [p for p in pts if p[2] > 0.0] # Project if projection == "stereographic": pop = project_stereographic lim = limit_stereographic elif projection == "lambert": pop = project_lambert_equal_area lim = limit_lambert_equal_area else: raise ValueError("Unknown projection %s" % projection) cart = np.array([pop(v) for v in pts]) # Convert to polar polar = np.array([cart2pol(cp) for cp in cart]) # Plot ax = plt.subplot(111, projection='polar') ax.scatter(polar[:,0], polar[:,1], c='k', s=10.0) # Make the graph nice plt.ylim([0,lim]) ax.grid(False) ax.get_yaxis().set_visible(False) if len(axis_labels) == 2: plt.xticks([0,np.pi/2], axis_labels) else: ax.get_xaxis().set_visible(False) ax.xaxis.set_minor_locator(plt.NullLocator())
def inverse_pole_figure_discrete(orientations, direction, lattice, reduce_figure = False, color = False, sample_symmetry = crystallography.symmetry_rotations("222"), x = [1,0,0], y = [0,1,0], axis_labels = None, nline = 100): """ Plot an inverse pole figure given a collection of discrete points. Parameters: orientations: list of orientations direction: sample direction lattice: crystal lattice class, including crystal symmetry Keyword Args: reduce_figure: reduce to some fundamental region. Options include False -- don't do it "cubic" -- cubic convention [v1,v2,v3] -- list of crystallographic points defining the triangle color: color points based on the provided triangle sample_symmetry: what sample symmetry to apply to the pole figure, defaults to orthorhombic x: crystallographic x direction for plot, defaults to [1,0,0] y: crystallographic y direction for plot, defaults to [0,1,0] axis_labels: axis labels to include on the figure nline: number of discrete points to use in plotting lines on the triangle """ pts = np.vstack(tuple(project_ipf(q, lattice, direction, sample_symmetry = sample_symmetry, x = x, y = y) for q in orientations)) if reduce_figure: if reduce_figure == "cubic": vs = (np.array([0,0,1.0]), np.array([1.0,0,1]), np.array([1.0,1,1])) elif len(reduce_figure) == 3: vs = reduce_figure else: raise ValueError("Unknown reduction type %s!" % reduce_figure) pts = reduce_points_triangle(pts, v0 = vs[0], v1=vs[1], v2=vs[2]) pop = project_stereographic lim = limit_stereographic cpoints = np.array([pop(v) for v in pts]) # Make the graph nice if reduce_figure: ax = plt.subplot(111) if color: rgb = ipf_color(pts, v0 = vs[0], v1 = vs[1], v2=vs[2]) ax.scatter(cpoints[:,0], cpoints[:,1], c=rgb, s = 10.0) else: ax.scatter(cpoints[:,0], cpoints[:,1], c='k', s = 10.0) ax.axis('off') if axis_labels: plt.text(0.1,0.11,axis_labels[0], transform = plt.gcf().transFigure) plt.text(0.86,0.11,axis_labels[1], transform = plt.gcf().transFigure) plt.text(0.74,0.88,axis_labels[2], transform = plt.gcf().transFigure) for i,j in ((0,1),(1,2),(2,0)): v1 = vs[i] v2 = vs[j] fs = np.linspace(0,1,nline) pts = np.array([pop((f*v1+(1-f)*v2)/la.norm(f*v1+(1-f)*v2)) for f in fs]) plt.plot(pts[:,0], pts[:,1], color = 'k') else: polar = np.array([cart2pol(v) for v in cpoints]) ax = plt.subplot(111, projection='polar') ax.scatter(polar[:,0], polar[:,1], c='k', s=10.0) plt.ylim([0,lim]) ax.grid(False) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.xaxis.set_minor_locator(plt.NullLocator())