def test_topotomo_tilts(self): # tests cases from ma2285 experiment on id11, omega offset = -90 T = np.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]]) al = Lattice.from_symbol('Al') p = HklPlane(0, 0, 2, lattice=al) rod = [0.1449, -0.0281, 0.0616] o = Orientation.from_rodrigues(rod) (ut, lt) = o.topotomo_tilts(p, T) self.assertAlmostEqual(180 / np.pi * ut, 2.236, 3) self.assertAlmostEqual(180 / np.pi * lt, 16.615, 3) # use test case from AlLi_sam8_dct_cen_ p = HklPlane(2, 0, 2, lattice=al) rod = [0.0499, -0.3048, 0.1040] o = Orientation.from_rodrigues(rod) (ut, lt) = o.topotomo_tilts(p, T) self.assertAlmostEqual(180 / np.pi * ut, -11.04, 2) self.assertAlmostEqual(180 / np.pi * lt, -0.53, 2) # test case from ma3921 T = Orientation.compute_instrument_transformation_matrix(-1.2, 0.7, 90) Ti7Al = Lattice.hexagonal(0.2931, 0.4694) # nm (h, k, l) = HklPlane.four_to_three_indices(-1, 2, -1, 0) p = HklPlane(h, k, l, Ti7Al) o = Orientation.from_rodrigues([0.7531, 0.3537, 0.0621]) (ut, lt) = o.topotomo_tilts(p, T) self.assertAlmostEqual(180 / np.pi * ut, 11.275, 2) self.assertAlmostEqual(180 / np.pi * lt, -4.437, 2)
def test_scattering_vector(self): Fe_fcc = Lattice.face_centered_cubic(0.287) # FCC iron hkl = HklPlane(2, 0, 0, Fe_fcc) Gc = hkl.scattering_vector() self.assertAlmostEqual(np.linalg.norm(Gc), 1 / hkl.interplanar_spacing()) Al_fcc = Lattice.face_centered_cubic(0.405) hkl = HklPlane(0, 0, 2, lattice=Al_fcc) Gc = hkl.scattering_vector() self.assertAlmostEqual(np.linalg.norm(Gc), 1 / hkl.interplanar_spacing())
def test_HklPlane_normal(self): ZrO2 = Lattice.tetragonal(3.64, 5.27) p = HklPlane(1, 1, 1, ZrO2) n = p.normal() self.assertAlmostEqual(n[0], 0.635, 3) self.assertAlmostEqual(n[1], 0.635, 3) self.assertAlmostEqual(n[2], 0.439, 3)
def __init__(self, args): '''Init a new View window.''' #print(args) # create the 3D scene s3d = Scene3D(display=True, ren_size=(800, 800)) if isinstance(args, list): if len(args) == 1: print( 'Please specify the file representing the 3D object to view' ) sys.exit(1) elif len(args) == 2: file_path = args[1] else: print( 'Please use only one parameter (the path to the file representing the 3D object to view)' ) sys.exit(1) (path, ext) = os.path.splitext(file_path) ext = ext.strip('.') print(ext) if ext in ['stl', 'STL']: actor = load_STL_actor(path, ext) else: print('Unrecognized file extenstion: %s' % ext) sys.exit(1) elif isinstance(args, Grain): actor = grain_3d(args) elif isinstance(args, Orientation): l = Lattice.cubic(1.0) (a, b, c) = l._lengths grid = lattice_grid(l) actor = lattice_edges(grid) actor.SetOrigin(a / 2, b / 2, c / 2) actor.AddPosition(-a / 2, -b / 2, -c / 2) apply_orientation_to_actor(actor, args) elif isinstance(args, Lattice): (a, b, c) = args._lengths actor = lattice_3d(args) actor.SetOrigin(a / 2, b / 2, c / 2) actor.AddPosition(-a / 2, -b / 2, -c / 2) elif isinstance(args, np.ndarray): actor = show_array(args) elif isinstance(args, vtk.vtkActor): actor = args else: raise ValueError('unsupported object type: {0}'.format(type(args))) bounds = actor.GetBounds() size = (bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4]) # bounds[1::2] print(size) axes = axes_actor(length=np.mean(size), fontSize=60) s3d.add(axes) s3d.add(actor) cam = setup_camera(size) cam.SetFocalPoint(0.5 * (bounds[0] + bounds[1]), 0.5 * (bounds[2] + bounds[3]), 0.5 * (bounds[4] + bounds[5])) s3d.set_camera(cam) s3d.render(key_pressed_callback=True)
def test_tetragonal_direction2(self): ZrO2 = Lattice.tetragonal(0.364, 0.527) d = HklDirection(1, 1, 1, ZrO2) target = np.array([1., 1., 1.448]) target /= np.linalg.norm(target) self.assertAlmostEqual(d.direction()[0], target[0], 4) self.assertAlmostEqual(d.direction()[1], target[1], 4) self.assertAlmostEqual(d.direction()[2], target[2], 4)
def test_tetragonal_direction(self): bct = Lattice.body_centered_tetragonal(0.28, 0.40) d111 = HklDirection(1, 1, 1, bct) d110 = HklDirection(1, 1, 0, bct) self.assertAlmostEqual(d111.direction()[0], 0.49746834, 5) self.assertAlmostEqual(d111.direction()[1], 0.49746834, 5) self.assertAlmostEqual(d111.direction()[2], 0.71066905, 5) self.assertAlmostEqual(d110.direction()[0], 0.707106781, 5) self.assertAlmostEqual(d110.direction()[1], 0.707106781, 5) self.assertAlmostEqual(d110.direction()[2], 0.0, 5)
def setUp(self): """testing the laue module:""" self.ni = Lattice.from_symbol('Ni') self.al = Lattice.face_centered_cubic(0.40495) self.g4 = Orientation.from_rodrigues( [0.0499199, -0.30475322, 0.10396082]) self.spots = np.array([[76, 211], [77, 281], [86, 435], [90, 563], [112, 128], [151, 459], [151, 639], [161, 543], [170, 325], [176, 248], [189, 70], [190, 375], [213, 670], [250, 167], [294, 54], [310, 153], [323, 262], [358, 444], [360, 507], [369, 163], [378, 535], [384, 86], [402, 555], [442, 139], [444, 224], [452, 565], [476, 292], [496, 88], [501, 547], [514, 166], [522, 525], [531, 433], [536, 494], [559, 264], [581, 57], [625, 168], [663, 607], [679, 69], [686, 363], [694, 240], [703, 315], [728, 437], [728, 518], [743, 609], [756, 128], [786, 413], [789, 271], [790, 534], [791, 205], [818, 123]])
def test_dct_omega_angles(self): # test with a BCC Titanium lattice lambda_keV = 30 lambda_nm = 1.2398 / lambda_keV a = 0.3306 # lattice parameter in nm Ti_bcc = Lattice.cubic(a) (h, k, l) = (0, 1, 1) hkl = HklPlane(h, k, l, lattice=Ti_bcc) o = Orientation.from_euler((103.517, 42.911, 266.452)) theta = hkl.bragg_angle(lambda_keV, verbose=False) gt = o.orientation_matrix( ) # our B (here called gt) corresponds to g^{-1} in Poulsen 2004 A = h * gt[0, 0] + k * gt[1, 0] + l * gt[2, 0] B = -h * gt[0, 1] - k * gt[1, 1] - l * gt[2, 1] C = -2 * a * np.sin( theta )**2 / lambda_nm # the minus sign comes from the main equation Delta = 4 * (A**2 + B**2 - C**2) self.assertEqual(Delta > 0, True) t1 = (B - 0.5 * np.sqrt(Delta)) / (A + C) t2 = (B + 0.5 * np.sqrt(Delta)) / (A + C) # verifying A cos(w) + B sin(w) = C:' for t in (t1, t2): x = A * (1 - t**2) / (1 + t**2) + B * 2 * t / (1 + t**2) self.assertAlmostEqual(x, C, 2) # verifying (A + C) * t**2 - 2 * B * t + (C - A) = 0' for t in (t1, t2): self.assertAlmostEqual((A + C) * t**2 - 2 * B * t + (C - A), 0.0, 2) (w1, w2) = o.dct_omega_angles(hkl, lambda_keV, verbose=False) self.assertAlmostEqual(w1, 196.709, 2) self.assertAlmostEqual(w2, 28.334, 2) # test with an FCC Aluminium-Lithium lattice a = 0.40495 # lattice parameter in nm Al_fcc = Lattice.face_centered_cubic(a) hkl = HklPlane(-1, 1, 1, Al_fcc) o = Orientation.from_rodrigues([0.0499, -0.3048, 0.1040]) w1, w2 = o.dct_omega_angles(hkl, 40, verbose=False) self.assertAlmostEqual(w1, 109.2, 1) self.assertAlmostEqual(w2, 296.9, 1)
def __init__(self, microstructure=None, lattice=None, axis='Z', hkl='111', proj='stereo', verbose=False): """ Create an empty PoleFigure object associated with an empty Microstructure. :param microstructure: the :py:class:`~pymicro.crystal.microstructure.Microstructure` containing the collection of orientations to plot (None by default). :param lattice: the crystal :py:class:`~pymicro.crystal.lattice.Lattice`. :param str axis: the pole figure axis ('Z' by default), vertical axis in the direct pole figure and direction plotted on the inverse pole figure. .. warning:: Any crystal structure is now supported (you have to set the proper crystal lattice) but it has only really be tested for cubic. :param str hkl: slip plane family ('111' by default) :param str proj: projection type, can be either 'stereo' (default) or 'flat' :param bool verbose: verbose mode (False by default) """ self.proj = proj self.axis = axis self.map_field = None if microstructure: self.microstructure = microstructure else: self.microstructure = Microstructure() if lattice: self.lattice = lattice else: self.lattice = Lattice.cubic(1.0) self.family = None self.poles = [] self.set_hkl_poles(hkl) self.verbose = verbose self.mksize = 12 self.color_by_grain_id = False self.pflegend = False self.x = np.array([1., 0., 0.]) self.y = np.array([0., 1., 0.]) self.z = np.array([0., 0., 1.]) # list all crystal directions self.c001s = np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]], dtype=np.float) self.c011s = np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0], [0, -1, 1], [-1, 0, 1], [-1, 1, 0]], dtype=np.float) / np.sqrt(2) self.c111s = np.array([[1, 1, 1], [-1, -1, 1], [1, -1, 1], [-1, 1, 1]], dtype=np.float) / np.sqrt(3)
def test_Bragg_condition(self): al = Lattice.from_symbol('Al') p = HklPlane(0, 0, 2, lattice=al) lambda_keV = 42 lambda_nm = lambda_keV_to_nm(lambda_keV) rod = [0.1449, -0.0281, 0.0616] o = Orientation.from_rodrigues(rod) (w1, w2) = o.dct_omega_angles(p, lambda_keV, verbose=False) # test the two solution of the rotating crystal for omega in (w1, w2): alpha = o.compute_XG_angle(p, omega, verbose=True) theta_bragg = p.bragg_angle(lambda_keV) self.assertAlmostEqual(alpha, 180 / np.pi * (np.pi / 2 - theta_bragg))
def test_apply_orientation_to_actor(self): o = Orientation.from_rodrigues([0.0885, 0.3889, 0.3268]) Bt = o.orientation_matrix().transpose( ) # to go from crystal to lab coordinate Vl = Bt.Vc l = Lattice.cubic(1.0) (a, b, c) = l._lengths grid = lattice_grid(l) actor = lattice_edges(grid) apply_orientation_to_actor(actor, o) m = actor.GetUserTransform().GetMatrix() for i in range(3): for j in range(3): self.assertEqual(Bt[i, j], m.GetElement(i, j))
def test_angle_with_directions(self): (a, b, c) = (1.022, 0.596, 0.481) olivine = Lattice.orthorhombic(a, b, c) (h1, k1, l1) = (1., 1., 1.) (h2, k2, l2) = (3., 3., 2.) d1 = HklDirection(h1, k1, l1, olivine) d2 = HklDirection(h2, k2, l2, olivine) # compare with formula in orthorhombic lattice, angle must be 6.589 degrees angle = np.arccos( ((h1 * h2 * a**2) + (k1 * k2 * b**2) + (l1 * l2 * c**2)) / (np.sqrt(a**2 * h1**2 + b**2 * k1**2 + c**2 * l1**2) * np.sqrt(a**2 * h2**2 + b**2 * k2**2 + c**2 * l2**2))) self.assertAlmostEqual(d1.angle_with_direction(d2), angle)
def __init__(self, arg): """Init a new View window. :param arg: a descriptor of the object to view, it can be an instance of `Grain`, `Orientation`, `Lattice`, a vtkActor, a 3D numpy array or the path to a STL file. """ # create the 3D scene s3d = Scene3D(display=True, ren_size=(800, 800)) if isinstance(arg, str): (path, ext) = os.path.splitext(arg) ext = ext.strip('.') print(ext) if ext in ['stl', 'STL']: actor = load_STL_actor(path, ext) else: print('Unrecognized file extension: %s' % ext) sys.exit(1) elif isinstance(arg, Grain): actor = grain_3d(arg) elif isinstance(arg, Orientation): l = Lattice.cubic(1.0) (a, b, c) = l._lengths grid = lattice_grid(l) actor = lattice_edges(grid) actor.SetOrigin(a / 2, b / 2, c / 2) actor.AddPosition(-a / 2, -b / 2, -c / 2) apply_orientation_to_actor(actor, arg) elif isinstance(arg, Lattice): (a, b, c) = arg._lengths actor = lattice_3d(arg) actor.SetOrigin(a / 2, b / 2, c / 2) actor.AddPosition(-a / 2, -b / 2, -c / 2) elif isinstance(arg, np.ndarray): if arg.ndim != 3: print('Only 3D arrays can be viewed with this method.') sys.exit(1) actor = show_array(arg) elif isinstance(arg, vtk.vtkActor): actor = arg else: raise ValueError('unsupported object type: {0}'.format(type(arg))) bounds = actor.GetBounds() size = (bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4]) # bounds[1::2] print(size) axes = axes_actor(length=np.mean(size), fontSize=60) s3d.add(axes) s3d.add(actor) cam = setup_camera(size) cam.SetFocalPoint(0.5 * (bounds[0] + bounds[1]), 0.5 * (bounds[2] + bounds[3]), 0.5 * (bounds[4] + bounds[5])) s3d.set_camera(cam) s3d.render(key_pressed_callback=True)
def test_topotomo_tilts(self): al = Lattice.from_symbol('Al') p = HklPlane(0, 0, 2, lattice=al) rod = [0.1449, -0.0281, 0.0616] o = Orientation.from_rodrigues(rod) (ut, lt) = o.topotomo_tilts(p) self.assertAlmostEqual(180 / np.pi * ut, 2.236, 3) self.assertAlmostEqual(180 / np.pi * lt, -16.615, 3) # use test case from AlLi_sam8_dct_cen_ p = HklPlane(2, 0, 2, lattice=al) rod = [0.0499, -0.3048, 0.1040] o = Orientation.from_rodrigues(rod) (ut, lt) = o.topotomo_tilts(p) self.assertAlmostEqual(180 / np.pi * ut, -11.04, 2) self.assertAlmostEqual(180 / np.pi * lt, 0.53, 2)
def test_reciprocal_lattice(self): Mg2Si = Lattice.from_parameters(1.534, 0.405, 0.683, 90., 106., 90., x_aligned_with_a=False) [astar, bstar, cstar] = Mg2Si.reciprocal_lattice() self.assertAlmostEqual(astar[0], 0.678, 3) self.assertAlmostEqual(astar[1], 0., 3) self.assertAlmostEqual(astar[2], 0., 3) self.assertAlmostEqual(bstar[0], 0., 3) self.assertAlmostEqual(bstar[1], 2.469, 3) self.assertAlmostEqual(bstar[2], 0., 3) self.assertAlmostEqual(cstar[0], 0.420, 3) self.assertAlmostEqual(cstar[1], 0., 3) self.assertAlmostEqual(cstar[2], 1.464, 3)
def test_gnomonic_projection_point(self): """Verify that the gnomonic projection of two diffracted points on a detector give access to the angle between the lattice plane normals.""" olivine = Lattice.orthorhombic( 1.022, 0.596, 0.481) # nm Barret & Massalski convention orientation = Orientation.cube() p1 = HklPlane(2, 0, -3, olivine) p2 = HklPlane(3, -1, -3, olivine) detector = RegArrayDetector2d(size=(512, 512), u_dir=[0, -1, 0], v_dir=[0, 0, -1]) detector.pixel_size = 0.200 # mm, 0.1 mm with factor 2 binning detector.ucen = 235 detector.vcen = 297 detector.ref_pos = np.array([131., 0., 0.]) + \ (detector.size[0] / 2 - detector.ucen) * detector.u_dir * detector.pixel_size + \ (detector.size[1] / 2 - detector.vcen) * detector.v_dir * detector.pixel_size # mm angle = 180 / np.pi * np.arccos(np.dot(p1.normal(), p2.normal())) # test the gnomonic projection for normal and not normal X-ray incidence for ksi in [0.0, 1.0]: # deg Xu = np.array( [np.cos(ksi * np.pi / 180), 0., np.sin(ksi * np.pi / 180)]) OC = detector.project_along_direction( Xu ) # C is the intersection of the direct beam with the detector K1 = diffracted_vector(p1, orientation, Xu=Xu) K2 = diffracted_vector(p2, orientation, Xu=Xu) R1 = detector.project_along_direction(K1, origin=[0., 0., 0.]) R2 = detector.project_along_direction(K2, origin=[0., 0., 0.]) OP1 = gnomonic_projection_point(R1, OC=OC)[0] OP2 = gnomonic_projection_point(R2, OC=OC)[0] hkl_normal1 = OP1 / np.linalg.norm(OP1) hkl_normal2 = (OP2 / np.linalg.norm(OP2)) # the projection must give the normal to the diffracting plane for i in range(3): self.assertAlmostEqual(hkl_normal1[i], p1.normal()[i], 6) self.assertAlmostEqual(hkl_normal2[i], p2.normal()[i], 6) angle_gp = 180 / np.pi * np.arccos(np.dot(hkl_normal1, hkl_normal2)) self.assertAlmostEqual(angle, angle_gp, 6)
def test_110_normal_monoclinic(self): """Testing (110) plane normal in monoclinic crystal structure. This test comes from http://www.mse.mtu.edu/~drjohn/my3200/stereo/sg5.html corrected for a few errors in the html page. In this test, the lattice is defined with the c-axis aligned with the Z direction of the Cartesian frame. """ Mg2Si = Lattice.from_parameters(1.534, 0.405, 0.683, 90., 106., 90., x_aligned_with_a=False) a = Mg2Si.matrix[0] b = Mg2Si.matrix[1] c = Mg2Si.matrix[2] self.assertAlmostEqual(a[0], 1.475, 3) self.assertAlmostEqual(a[1], 0., 3) self.assertAlmostEqual(a[2], -0.423, 3) self.assertAlmostEqual(b[0], 0., 3) self.assertAlmostEqual(b[1], 0.405, 3) self.assertAlmostEqual(b[2], 0., 3) self.assertAlmostEqual(c[0], 0., 3) self.assertAlmostEqual(c[1], 0., 3) self.assertAlmostEqual(c[2], 0.683, 3) p = HklPlane(1, 1, 1, Mg2Si) Gc = p.scattering_vector() self.assertAlmostEqual(Gc[0], 1.098, 3) self.assertAlmostEqual(Gc[1], 2.469, 3) self.assertAlmostEqual(Gc[2], 1.464, 3) self.assertAlmostEqual(p.interplanar_spacing(), 0.325, 3) Ghkl = np.dot(Mg2Si.matrix, Gc) self.assertEqual(Ghkl[0], 1.) # h self.assertEqual(Ghkl[1], 1.) # k self.assertEqual(Ghkl[2], 1.) # l
def test_bragg_angle(self): l = Lattice.cubic(0.287) # FCC iron hkl = HklPlane(2, 0, 0, l) # 200 reflection at 8 keV is at 32.7 deg self.assertAlmostEqual(hkl.bragg_angle(8), 0.5704164)
def load(file_path='experiment.txt'): with open(file_path, 'r') as f: dict_exp = json.load(f) sample = Sample() sample.set_name(dict_exp['Sample']['Name']) sample.set_position(dict_exp['Sample']['Position']) if 'Geometry' in dict_exp['Sample']: sample_geo = ObjectGeometry() sample_geo.set_type(dict_exp['Sample']['Geometry']['Type']) sample.set_geometry(sample_geo) if 'Material' in dict_exp['Sample']: a, b, c = dict_exp['Sample']['Material']['Lengths'] alpha, beta, gamma = dict_exp['Sample']['Material']['Angles'] centering = dict_exp['Sample']['Material']['Centering'] symmetry = Symmetry.from_string( dict_exp['Sample']['Material']['Symmetry']) material = Lattice.from_parameters(a, b, c, alpha, beta, gamma, centering=centering, symmetry=symmetry) sample.set_material(material) if 'Microstructure' in dict_exp['Sample']: micro = Microstructure( dict_exp['Sample']['Microstructure']['Name']) for i in range(len( dict_exp['Sample']['Microstructure']['Grains'])): dict_grain = dict_exp['Sample']['Microstructure']['Grains'][i] grain = Grain( dict_grain['Id'], Orientation.from_euler( dict_grain['Orientation']['Euler Angles (degrees)'])) grain.position = np.array(dict_grain['Position']) grain.volume = dict_grain['Volume'] micro.grains.append(grain) sample.set_microstructure(micro) exp = Experiment() exp.set_sample(sample) source = XraySource() source.set_position(dict_exp['Source']['Position']) if 'Min Energy (keV)' in dict_exp['Source']: source.set_min_energy(dict_exp['Source']['Min Energy (keV)']) if 'Max Energy (keV)' in dict_exp['Source']: source.set_max_energy(dict_exp['Source']['Max Energy (keV)']) exp.set_source(source) for i in range(len(dict_exp['Detectors'])): dict_det = dict_exp['Detectors'][i] if dict_det['Class'] == 'Detector2d': det = Detector2d(size=dict_det['Size (pixels)']) det.ref_pos = dict_det['Reference Position (mm)'] if dict_det['Class'] == 'RegArrayDetector2d': det = RegArrayDetector2d(size=dict_det['Size (pixels)']) det.pixel_size = dict_det['Pixel Size (mm)'] det.ref_pos = dict_det['Reference Position (mm)'] if 'Binning' in dict_det: det.set_binning(dict_det['Binning']) det.u_dir = np.array(dict_det['u_dir']) det.v_dir = np.array(dict_det['v_dir']) det.w_dir = np.array(dict_det['w_dir']) exp.add_detector(det) return exp
def test_from_symbol(self): al = Lattice.from_symbol('Al') for i in range(0, 3): self.assertAlmostEqual(al._lengths[i], 0.40495, 4) self.assertEqual(al._angles[i], 90.0)
def setUp(self): print('testing the HklPlane class') self.hex = Lattice.hexagonal(0.2931, 0.4694) # nm
def test_volume(self): l = Lattice.cubic(0.5) self.assertAlmostEqual(l.volume(), 0.125)
s3d = Scene3D(display=False, ren_size=(800, 800), name=base_name) # specify the grain orientation o1 = Orientation.from_euler(numpy.array([45., 0., 0.])) # grain 1 # choose slip plane normals and directions to display in grain n1 = numpy.array([1.0, 1.0, -1.0]) l1 = numpy.array([1.0, 1.0, 2.0]) d1 = '[112]' n2 = numpy.array([1.0, 1.0, 1.0]) l2 = numpy.array([1.0, 1.0, -2.0]) d2 = '[11-2]' nld = [[n1, l1, d1], [n2, l2, d2]] # we use a unit lattice cell to represent the mesh l_xyz = Lattice.face_centered_cubic(1.0) g1 = create_mesh_outline_3d_with_planes(l_xyz, o1, nld) s3d.add(g1) # add axes actor axes = axes_actor(0.5, fontSize=40) s3d.add(axes) # set up camera cam = vtk.vtkCamera() cam.SetViewUp(0, 0, 1) cam.SetPosition(4.0, -1.5, 1.8) cam.SetFocalPoint(0.5, 0.5, 0.6) s3d.set_camera(cam) s3d.render()
def test_cubic(self): a = np.array([[0.5, 0., 0.], [0., 0.5, 0.], [0., 0., 0.5]]) l = Lattice.cubic(0.5) for i in range(0, 3): for j in range(0, 3): self.assertEqual(l.matrix[i][j], a[i][j])
def test_equality(self): l1 = Lattice.cubic(0.5) a = np.array([[0.5, 0., 0.], [0., 0.5, 0.], [0., 0., 0.5]]) l2 = Lattice(a, symmetry=Symmetry.cubic) self.assertEqual(l1, l2)
def set_material(self, material): if material is None: material = Lattice.cubic(1.0) self.material = material
lab_frame = axes_actor(1, fontSize=50) lab_frame.SetCylinderRadius(0.02) s3d.add(lab_frame) crystal_frame = axes_actor(0.6, fontSize=50, axisLabels=None) crystal_frame.SetCylinderRadius(0.05) collection = vtk.vtkPropCollection() crystal_frame.GetActors(collection) for i in range(collection.GetNumberOfItems()): collection.GetItemAsObject(i).GetProperty().SetColor(0.0, 0.0, 0.0) apply_orientation_to_actor(crystal_frame, orientation) s3d.add(crystal_frame) a = 1.0 l = Lattice.face_centered_cubic(a) fcc_lattice = lattice_3d(l, crystal_orientation=orientation) set_opacity(fcc_lattice, 0.3) s3d.add(fcc_lattice) # arrow to show 111 lattice vector Vc = np.array([a, a, a]) Vs = np.dot(g.T, Vc) vector = unit_arrow_3d((0., 0., 0.), Vs, make_unit=False) s3d.add(vector) # add some text actors euler_str = 'Crystal Euler angles = (%.1f, %.1f, %.1f)\n' \ 'Vc=[1, 1, 1]\n' \ 'Vs=[%.3f, %.3f, %.3f]' % (phi1, Phi, phi2, Vs[0], Vs[1], Vs[2]) euler_text = text(euler_str, coords=(0.5, 0.05))
lab_frame = axes_actor(1, fontSize=50) lab_frame.SetCylinderRadius(0.02) s3d.add(lab_frame) crystal_frame = axes_actor(0.6, fontSize=50, axisLabels=None) crystal_frame.SetCylinderRadius(0.04) collection = vtk.vtkPropCollection() crystal_frame.GetActors(collection) for i in range(collection.GetNumberOfItems()): collection.GetItemAsObject(i).GetProperty().SetColor(0.0, 0.0, 0.0) crystal_frame.SetVisibility(0) s3d.add(crystal_frame) a = 0.4045 # nm, value for Al l = Lattice.cubic(a) cubic_lattice = lattice_3d(l, crystal_orientation=orientation, tubeRadius=0.1 * a, sphereRadius=0.2 * a) s3d.add(cubic_lattice) # display the crystal frame progressively crystal_frame_visibility = vtkSetVisibility(5, crystal_frame, gradually=True) crystal_frame_visibility.time_anim_ends = 20 scene.add_animation(crystal_frame_visibility) # apply Euler angles one by one with the Bunge convention (ZXZ) crystal_frame_rotate_phi1 = vtkRotateActorAroundAxis(30, duration=40, axis=[0., 0., 1.], angle=phi1) crystal_frame_rotate_phi1.set_actor(crystal_frame) scene.add_animation(crystal_frame_rotate_phi1) o_phi1 = Orientation.from_euler((phi1, 0., 0.)) x_prime = np.dot(o_phi1.orientation_matrix().T, [1., 0., 0.])
with a small offset so it is displayed nicely. ''' # create the 3D scene base_name = os.path.splitext(__file__)[0] s3d = Scene3D(display=False, ren_size=(800, 400), name=base_name) # create all the different unit lattice cells a = 1.0 b = 1.5 c = 2.0 alpha = 66 beta = 66 gamma = 66 l = Lattice.cubic(a) cubic = lattice_3d(l) apply_translation_to_actor(cubic, (0.5, 0.5, 0.0)) l = Lattice.tetragonal(a, c) tetragonal = lattice_3d(l) apply_translation_to_actor(tetragonal, (2.0, 2.0, 0.0)) l = Lattice.orthorombic(a, b, c) orthorombic = lattice_3d(l) apply_translation_to_actor(orthorombic, (3.5, 3.5, 0.0)) l = Lattice.hexagonal(a, c) hexagonal = lattice_3d(l) apply_translation_to_actor(hexagonal, (5.0, 5.0, 0.0))
def load(file_path='experiment.txt'): with open(file_path, 'r') as f: dict_exp = json.load(f) name = dict_exp['Sample']['Name'] sample = Sample(name=name) sample.data_dir = dict_exp['Sample']['Data Dir'] sample.set_position(dict_exp['Sample']['Position']) if 'Geometry' in dict_exp['Sample']: sample_geo = ObjectGeometry() sample_geo.set_type(dict_exp['Sample']['Geometry']['Type']) sample.set_geometry(sample_geo) if 'Material' in dict_exp['Sample']: a, b, c = dict_exp['Sample']['Material']['Lengths'] alpha, beta, gamma = dict_exp['Sample']['Material']['Angles'] centering = dict_exp['Sample']['Material']['Centering'] symmetry = Symmetry.from_string( dict_exp['Sample']['Material']['Symmetry']) material = Lattice.from_parameters(a, b, c, alpha, beta, gamma, centering=centering, symmetry=symmetry) sample.set_material(material) if 'Microstructure' in dict_exp['Sample']: micro = Microstructure( name=dict_exp['Sample']['Microstructure']['Name'], file_path=os.path.dirname(file_path)) # crystal lattice if 'Lattice' in dict_exp['Sample']['Microstructure']: a, b, c = dict_exp['Sample']['Microstructure']['Lattice'][ 'Lengths'] alpha, beta, gamma = dict_exp['Sample']['Microstructure'][ 'Lattice']['Angles'] centering = dict_exp['Sample']['Microstructure']['Lattice'][ 'Centering'] symmetry = Symmetry.from_string( dict_exp['Sample']['Microstructure']['Lattice'] ['Symmetry']) lattice = Lattice.from_parameters(a, b, c, alpha, beta, gamma, centering=centering, symmetry=symmetry) micro.set_lattice(lattice) grain = micro.grains.row for i in range(len( dict_exp['Sample']['Microstructure']['Grains'])): dict_grain = dict_exp['Sample']['Microstructure']['Grains'][i] grain['idnumber'] = int(dict_grain['Id']) euler = dict_grain['Orientation']['Euler Angles (degrees)'] grain['orientation'] = Orientation.from_euler(euler).rod grain['center'] = np.array(dict_grain['Position']) grain['volume'] = dict_grain['Volume'] # if 'hkl_planes' in dict_grain: # grain.hkl_planes = dict_grain['hkl_planes'] grain.append() micro.grains.flush() sample.set_microstructure(micro) sample.microstructure.autodelete = True # lazy behaviour, we load only the grain_ids path, the actual array is loaded in memory if needed sample.grain_ids_path = dict_exp['Sample']['Grain Ids Path'] exp = Experiment() exp.set_sample(sample) source = XraySource() source.set_position(dict_exp['Source']['Position']) if 'Min Energy (keV)' in dict_exp['Source']: source.set_min_energy(dict_exp['Source']['Min Energy (keV)']) if 'Max Energy (keV)' in dict_exp['Source']: source.set_max_energy(dict_exp['Source']['Max Energy (keV)']) exp.set_source(source) for i in range(len(dict_exp['Detectors'])): dict_det = dict_exp['Detectors'][i] if dict_det['Class'] == 'Detector2d': det = Detector2d(size=dict_det['Size (pixels)']) det.ref_pos = dict_det['Reference Position (mm)'] if dict_det['Class'] == 'RegArrayDetector2d': det = RegArrayDetector2d(size=dict_det['Size (pixels)']) det.pixel_size = dict_det['Pixel Size (mm)'] det.ref_pos = dict_det['Reference Position (mm)'] if 'Min Energy (keV)' in dict_exp['Detectors']: det.tilt = dict_det['Tilts (deg)'] if 'Binning' in dict_det: det.set_binning(dict_det['Binning']) det.u_dir = np.array(dict_det['u_dir']) det.v_dir = np.array(dict_det['v_dir']) det.w_dir = np.array(dict_det['w_dir']) exp.add_detector(det) return exp