Пример #1
0
 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())
Пример #2
0
def dct_projection(orientations, data, dif_grains, omega, lambda_keV, detector, lattice, include_direct_beam=True,
                   att=5, verbose=True):
    '''Work in progress, will replace function in the microstructure module.'''
    full_proj = np.zeros(detector.size, dtype=np.float)
    lambda_nm = lambda_keV_to_nm(lambda_keV)
    omegar = omega * np.pi / 180
    R = np.array([[np.cos(omegar), -np.sin(omegar), 0], [np.sin(omegar), np.cos(omegar), 0], [0, 0, 1]])

    if include_direct_beam:
        # add the direct beam part by computing the radiograph of the sample without the diffracting grains
        data_abs = np.where(data > 0, 1, 0)
        for (gid, (h, k, l)) in dif_grains:
            mask_dif = (data == gid)
            data_abs[mask_dif] = 0  # remove this grain from the absorption
        proj = radiograph(data_abs, omega)
        add_to_image(full_proj, proj[::-1, ::-1] / att, np.array(full_proj.shape) // 2)

    # add diffraction spots
    X = np.array([1., 0., 0.]) / lambda_nm
    for (gid, (h, k, l)) in dif_grains:
        grain_data = np.where(data == gid, 1, 0)
        if np.sum(grain_data) < 1:
            print('skipping grain %d' % gid)
            continue
        local_com = np.array(ndimage.measurements.center_of_mass(grain_data, data))
        print('local center of mass (voxel): {0}'.format(local_com))
        g_center_mm = detector.pixel_size * (local_com - 0.5 * np.array(data.shape))
        print('center of mass (voxel): {0}'.format(local_com - 0.5 * np.array(data.shape)))
        print('center of mass (mm): {0}'.format(g_center_mm))
        # compute scattering vector
        gt = orientations[gid].orientation_matrix().transpose()
        # gt = micro.get_grain(gid).orientation_matrix().transpose()
        p = HklPlane(h, k, l, lattice)
        G = np.dot(R, np.dot(gt, p.scattering_vector()))
        K = X + G
        # position of the grain at this rotation
        g_pos_rot = np.dot(R, g_center_mm)
        pg = detector.project_along_direction(K, g_pos_rot)
        (up, vp) = detector.lab_to_pixel(pg)
        if verbose:
            print('\n* gid=%d, (%d,%d,%d) plane, angle=%.1f' % (gid, h, k, l, omega))
            print('diffraction vector:', K)
            print('postion of the grain at omega=%.1f is ' % omega, g_pos_rot)
            print('up=%d, vp=%d for plane (%d,%d,%d)' % (up, vp, h, k, l))
        data_dif = grain_data[ndimage.find_objects(data == gid)[0]]
        proj_dif = radiograph(data_dif, omega)  # (Y, Z) coordinate system
        add_to_image(full_proj, proj_dif[::-1, ::-1], (up, vp), verbose)  # (u, v) axes correspond to (-Y, -Z)
    return full_proj
Пример #3
0
 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
Пример #4
0
    def dct_projection(self, omega, include_direct_beam=True, att=5):
        """Function to compute a full DCT projection at a given omega angle.

        :param float omega: rotation angle in degrees.
        :param bool include_direct_beam: flag to compute the transmission through the sample.
        :param float att: an attenuation factor used to limit the gray levels in the direct beam.
        :return: the dct projection as a 2D numpy array
        """
        if len(self.reflections) == 0:
            print(
                'empty list of reflections, you should run the setup function first'
            )
            return None
        grain_ids = self.exp.get_sample().get_grain_ids()
        detector = self.exp.get_active_detector()
        lambda_keV = self.exp.source.max_energy
        lattice = self.exp.get_sample().get_material()
        index = np.argmax(self.omegas > omega)
        dif_grains = self.reflections[
            index -
            1]  # grains diffracting between omegas[index - 1] and omegas[index]
        # intialize image result
        full_proj = np.zeros(detector.get_size_px(), dtype=np.float)
        lambda_nm = lambda_keV_to_nm(lambda_keV)
        omegar = omega * np.pi / 180
        R = np.array([[np.cos(omegar), -np.sin(omegar), 0],
                      [np.sin(omegar), np.cos(omegar), 0], [0, 0, 1]])

        if include_direct_beam:
            # add the direct beam part by computing the radiograph of the sample without the diffracting grains
            data_abs = np.where(grain_ids > 0, 1, 0)
            for (gid, (h, k, l)) in dif_grains:
                mask_dif = (grain_ids == gid)
                data_abs[mask_dif] = 0  # remove this grain from the absorption
            proj = radiograph(
                data_abs, omega
            )[:, ::-1]  # (u, v) axes correspond to (Y, -Z) for DCT detector
            add_to_image(full_proj, proj / att, np.array(full_proj.shape) // 2)

        # add diffraction spots
        X = np.array([1., 0., 0.]) / lambda_nm
        for (gid, (h, k, l)) in dif_grains:
            grain_data = np.where(grain_ids == gid, 1, 0)
            if np.sum(grain_data) < 1:
                print('skipping grain %d' % gid)
                continue
            local_com = np.array(
                ndimage.measurements.center_of_mass(grain_data, grain_ids))
            print('local center of mass (voxel): {0}'.format(local_com))
            g_center_mm = detector.get_pixel_size() * (
                local_com - 0.5 * np.array(grain_ids.shape))
            print('center of mass (voxel): {0}'.format(
                local_com - 0.5 * np.array(grain_ids.shape)))
            print('center of mass (mm): {0}'.format(g_center_mm))
            # compute scattering vector
            gt = self.exp.get_sample().get_microstructure().get_grain(
                gid).orientation_matrix().transpose()
            p = HklPlane(h, k, l, lattice)
            G = np.dot(R, np.dot(gt, p.scattering_vector()))
            K = X + G
            # position of the grain at this rotation angle
            g_pos_rot = np.dot(R, g_center_mm)
            pg = detector.project_along_direction(K, g_pos_rot)
            up, vp = detector.lab_to_pixel(pg)[0]
            if self.verbose:
                print('\n* gid=%d, (%d,%d,%d) plane, angle=%.1f' %
                      (gid, h, k, l, omega))
                print('diffraction vector:', K)
                print('postion of the grain at omega=%.1f is ' % omega,
                      g_pos_rot)
                print('up=%d, vp=%d for plane (%d,%d,%d)' % (up, vp, h, k, l))
            data_dif = grain_data[ndimage.find_objects(grain_ids == gid)[0]]
            proj_dif = radiograph(data_dif, omega)  # (Y, Z) coordinate system
            add_to_image(full_proj, proj_dif[:, ::-1], (up, vp),
                         self.verbose)  # (u, v) axes correspond to (Y, -Z)
        return full_proj