def setup(self, omega_step, grain_ids=None): """Setup the forward simulation. :param float omega_step: the angular integration step (in degrees) use to compute the diffraction comditions. :param list grain_ids: a list of grain ids to restrict the forward simulation (use all grains by default). """ assert self.exp.source.min_energy == self.exp.source.max_energy # monochromatic case lambda_keV = self.exp.source.max_energy self.omegas = np.linspace(0.0, 360.0, num=int(360.0 / omega_step), endpoint=False) self.reflections = [] for omega in self.omegas: self.reflections.append([]) if grain_ids: # make a list of the grains selected for the forward simulation grains = [ self.exp.sample.microstructure.get_grain(gid) for gid in grain_ids ] else: grains = self.exp.sample.microstructure.grains for g in grains: for plane in self.hkl_planes: (h, k, i, l) = HklPlane.three_to_four_indices(*plane.miller_indices()) try: (w1, w2) = g.dct_omega_angles(plane, lambda_keV, verbose=False) except ValueError: if self.verbose: print( 'plane {} does not fulfil the Bragg condition for grain {:d}' .format((h, k, i, l), g.id)) continue # add angles for Friedel pairs w3 = (w1 + 180.) % 360 w4 = (w2 + 180.) % 360 if self.verbose and g.id == self.check: print( 'grain %d, angles for plane %d%d%d: w1=%.3f and w2=%.3f | delta=%.1f' % (g.id, h, k, l, w1, w2, w1 - w2)) print('(%3d, %3d, %3d, %3d) -- %6.2f & %6.2f' % (h, k, i, l, w1, w2)) self.reflections[int(w1 / omega_step)].append( [g.id, (h, k, l)]) self.reflections[int(w2 / omega_step)].append( [g.id, (h, k, l)]) self.reflections[int(w3 / omega_step)].append( [g.id, (-h, -k, -l)]) self.reflections[int(w4 / omega_step)].append( [g.id, (-h, -k, -l)])
def setup(self, omega_step): """Setup the forward simulation.""" assert self.exp.source.min_energy == self.exp.source.max_energy # monochromatic case lambda_keV = self.exp.source.max_energy self.omegas = np.linspace(0.0, 360.0, num=int(360.0 / omega_step), endpoint=False) self.reflections = [] for omega in self.omegas: self.reflections.append([]) for g in self.exp.sample.microstructure.grains: for plane in self.hkl_planes: (h, k, i, l) = HklPlane.three_to_four_indices(*plane.miller_indices()) try: (w1, w2) = g.dct_omega_angles(plane, lambda_keV, verbose=False) except ValueError: if self.verbose: print( 'plane {} does not fulfil the Bragg condition for grain {:d}' .format((h, k, i, l), g.id)) continue # add angles for Friedel pairs w3 = (w1 + 180.) % 360 w4 = (w2 + 180.) % 360 if self.verbose and g.id == self.check: print( 'grain %d, angles for plane %d%d%d: w1=%.3f and w2=%.3f | delta=%.1f' % (g.id, h, k, l, w1, w2, w1 - w2)) print('(%3d, %3d, %3d, %3d) -- %6.2f & %6.2f' % (h, k, i, l, w1, w2)) self.reflections[int(w1 / omega_step)].append( [g.id, (h, k, l)]) self.reflections[int(w2 / omega_step)].append( [g.id, (h, k, l)]) self.reflections[int(w3 / omega_step)].append( [g.id, (-h, -k, -l)]) self.reflections[int(w4 / omega_step)].append( [g.id, (-h, -k, -l)])
def plot_sst(self, ax=None, mk='s', ann=False): """ Create the inverse pole figure in the unit standard triangle. :param ax: a reference to a pyplot ax to draw the poles. :param mk: marker used to plot the poles (square by default). :param bool ann: Annotate the pole with the coordinates of the vector if True (False by default). """ # first draw the boundary of the symmetry domain limited by 3 hkl plane normals, called here A, B and C symmetry = self.lattice._symmetry if symmetry is Symmetry.cubic: sst_poles = [(0, 0, 1), (1, 0, 1), (1, 1, 1)] ax.axis([-0.05, 0.45, -0.05, 0.40]) elif symmetry is Symmetry.hexagonal: sst_poles = [(0, 0, 1), (2, -1, 0), (1, 0, 0)] ax.axis([-0.05, 1.05, -0.05, 0.6]) else: print('unssuported symmetry: %s' % symmetry) A = HklPlane(*sst_poles[0], lattice=self.lattice) B = HklPlane(*sst_poles[1], lattice=self.lattice) C = HklPlane(*sst_poles[2], lattice=self.lattice) self.plot_line_between_crystal_dir(A.normal(), B.normal(), ax=ax, col='k') self.plot_line_between_crystal_dir(B.normal(), C.normal(), ax=ax, col='k') self.plot_line_between_crystal_dir(C.normal(), A.normal(), ax=ax, col='k') # display the 3 crystal axes poles = [A, B, C] v_align = ['top', 'top', 'bottom'] for i in range(3): hkl = poles[i] c_dir = hkl.normal() c = c_dir + self.z c /= c[2] # SP'/SP = r/z with r=1 pole_str = '%d%d%d' % hkl.miller_indices() if symmetry is Symmetry.hexagonal: pole_str = '%d%d%d%d' % HklPlane.three_to_four_indices( *hkl.miller_indices()) ax.annotate(pole_str, (c[0], c[1] - (2 * (i < 2) - 1) * 0.01), xycoords='data', fontsize=12, horizontalalignment='center', verticalalignment=v_align[i]) # now plot the sample axis for grain in self.microstructure.grains: # move to the fundamental zone g = grain.orientation_matrix() # compute axis and apply SST symmetry if self.axis == 'Z': axis = self.z elif self.axis == 'Y': axis = self.y else: axis = self.x axis_rot = self.sst_symmetry(g.dot(axis)) label = '' if self.map_field == 'grain_id': label = 'grain ' + str(grain.id) self.plot_crystal_dir(axis_rot, mk=mk, col=self.get_color_from_field(grain), ax=ax, ann=ann, lab=label) if self.verbose: print('plotting %s in crystal CS: %s' % (self.axis, axis_rot)) ax.axis('off') ax.set_title('%s-axis SST inverse %s projection' % (self.axis, self.proj))