예제 #1
0
    def diffraction_pattern_for_radial(self):
        """
        Two diffraction patterns with easy to see radial profiles, wrapped
        in ElectronDiffraction  <2|8,8>
        """
        dp = ElectronDiffraction(np.zeros((2, 8, 8)))
        dp.data[0] = np.array([[0., 0., 2., 2., 2., 2., 0., 0.],
                               [0., 2., 3., 3., 3., 3., 2., 0.],
                               [2., 3., 3., 4., 4., 3., 3., 2.],
                               [2., 3., 4., 5., 5., 4., 3., 2.],
                               [2., 3., 4., 5., 5., 4., 3., 2.],
                               [2., 3., 3., 4., 4., 3., 3., 2.],
                               [0., 2., 3., 3., 3., 3., 2., 0.],
                               [0., 0., 2., 2., 2., 2., 0., 0.]])

        dp.data[1] = np.array([[0., 0., 0., 0., 0., 0., 0., 0.],
                               [0., 0., 0., 0., 0., 0., 0., 0.],
                               [0., 0., 0., 0., 0., 0., 0., 0.],
                               [1., 1., 1., 1., 1., 1., 1., 1.],
                               [1., 1., 1., 1., 1., 1., 1., 1.],
                               [0., 0., 0., 0., 0., 0., 0., 0.],
                               [0., 0., 0., 0., 0., 0., 0., 0.],
                               [0., 0., 0., 0., 0., 0., 0., 0.]])

        return dp
예제 #2
0
def test_reproject_as_polar(diffraction_pattern: ElectronDiffraction):
    shape_cartesian = diffraction_pattern.axes_manager.signal_shape
    diffraction_pattern.reproject_as_polar()
    assert isinstance(diffraction_pattern, Signal2D)
    shape_polar = diffraction_pattern.axes_manager.signal_shape
    assert shape_polar[0] == max(shape_cartesian)
    assert shape_polar[1] > np.sqrt(2) * shape_cartesian[0] / 2
예제 #3
0
    def plot_calibrated_data(self, data_to_plot, *args, **kwargs):
        """ Plot calibrated data for visual inspection.

        Parameters
        ----------
        data_to_plot : string
            Specify the calibrated data to be plotted. Valid options are:
            {'au_x_grating_dp', 'au_x_grating_im', 'moo3_dp', 'moo3_im'}
        """
        # Construct object containing user defined data to plot and set the
        # calibration checking that it is defined.
        if data_to_plot == 'au_x_grating_dp':
            dpeg = self.calibration_data.au_x_grating_dp
            size = dpeg.data.shape[0]
            dpegs = stack_method([dpeg, dpeg, dpeg, dpeg])
            dpegs = ElectronDiffraction(dpegs.data.reshape((2, 2, size, size)))
            dpegs.apply_affine_transformation(self.affine_matrix,
                                              preserve_range=True,
                                              inplace=True)
            data = dpegs.mean((0, 1))
            data.set_diffraction_calibration(self.diffraction_calibration)
        elif data_to_plot == 'au_x_grating_im':
            data = self.calibration_data.au_x_grating_im
        #Plot the data
        data.plot(*args, **kwargs)
 def pattern_for_fit_ring(self, input_parameters):
     dp = ElectronDiffraction(np.zeros((256, 256)))
     x0 = input_parameters
     dp.data = dp.generate_ring_pattern(mask=True,
                                        mask_radius=10,
                                        scale=x0[0],
                                        amplitude=x0[1],
                                        spread=x0[2],
                                        direct_beam_amplitude=x0[3],
                                        asymmetry=x0[4],
                                        rotation=x0[5])
     return dp
예제 #5
0
 def ragged_peak(self):
     """
     A small selection of peaks in an ElectronDiffraction, to allow flexibilty
     of test building here.
     """
     pattern = np.zeros((2, 2, 128, 128))
     pattern[:, :, 40:42, 45] = 1
     pattern[:, :, 110, 30:32] = 1
     pattern[1, 0, 71:73, 21:23] = 1
     dp = ElectronDiffraction(pattern)
     dp.set_diffraction_calibration(1)
     return dp
예제 #6
0
def test_plot_best_matching_results_on_signal_vector(structure, rot_list, edc):
    # Just test that the code runs
    library, match_results = get_vector_match_results(structure, rot_list, edc)
    # Hyperspy can only add markers to square signals
    match_results.data = np.vstack((match_results.data, match_results.data))
    dp = ElectronDiffraction(2 * [2 * [np.zeros((144, 144))]])
    match_results.plot_best_matching_results_on_signal(dp, library=library)
예제 #7
0
def test_bad_vectors_numpy():
    """ tests that putting bad vectors in causes an error to be thrown when
    you initiate the geneartor
    """
    v = np.array([[1, -100]])
    dp = ElectronDiffraction(np.ones((20, 20)))
    sprg = SubpixelrefinementGenerator(dp, v)
예제 #8
0
    def as_signal(self, size, sigma, max_r):
        """Returns the diffraction data as an ElectronDiffraction signal with
        two-dimensional Gaussians representing each diffracted peak. Should only
        be used for qualitative work.

        Parameters
        ----------
        size : int
            Side length (in pixels) for the signal to be simulated.
        sigma : float
            Standard deviation of the Gaussian function to be plotted.
        max_r : float
            Half the side length in reciprocal Angstroms. Defines the signal's
            calibration

        Returns
        -------

        dp : ElectronDiffraction
            Simulated electron diffraction pattern.

        """
        from skimage.filters import gaussian as point_spread

        l, delta_l = np.linspace(-max_r, max_r, size, retstep=True)

        mask_for_max_r = np.logical_and(
            np.abs(self.coordinates[:, 0]) < max_r,
            np.abs(self.coordinates[:, 1]) < max_r)

        coords = self.coordinates[mask_for_max_r]
        inten = self.intensities[mask_for_max_r]

        dp_dat = np.zeros([size, size])
        x, y = (coords)[:, 0], (coords)[:, 1]
        if len(x) > 0:  # avoiding problems in the peakless case
            num = np.digitize(x, l, right=True), np.digitize(y, l, right=True)
            dp_dat[num] = inten
            # sigma in terms of pixels. transpose for Hyperspy
            dp_dat = point_spread(dp_dat, sigma=sigma / delta_l).T
            dp_dat = dp_dat / np.max(dp_dat)

        dp = ElectronDiffraction(dp_dat)
        dp.set_diffraction_calibration(2 * max_r / size)

        return dp
예제 #9
0
 def test_apply_affine_transformation_with_casting(self,
                                                   diffraction_pattern):
     diffraction_pattern.change_dtype('uint8')
     transformed_dp = ElectronDiffraction(
         diffraction_pattern).apply_affine_transformation(D=np.array(
             [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.2]]),
                                                          order=2,
                                                          keep_dtype=True,
                                                          inplace=False)
     assert transformed_dp.data.dtype == 'uint8'
예제 #10
0
    def get_distortion_residuals(self, mask_radius, spread):
        """Obtain residuals for experimental data and distortion corrected data
        with respect to a simulated symmetric ring pattern.

        Parameters
        ----------
        mask_radius : int
            Radius, in pixels, for a mask over the direct beam disc.
        spread : float
            Gaussian spread of each ring in the simulated pattern.

        Returns
        -------
        diff_init : ElectronDiffraction
            Difference between experimental data and simulated symmetric ring
            pattern.
        diff_end : ElectronDiffraction
            Difference between distortion corrected data and simulated symmetric
            ring pattern.
        """
        # Check all required parameters are defined as attributes
        if self.calibration_data.au_x_grating_dp is None:
            raise ValueError(
                "This method requires an Au X-grating diffraction "
                "pattern to be provided. Please update the "
                "CalibrationDataLibrary.")
        if self.affine_matrix is None:
            raise ValueError(
                "This method requires a distortion matrix to have "
                "been determined. Use get_elliptical_distortion "
                "to determine this matrix.")
        # Set name for experimental data pattern
        dpeg = self.calibration_data.au_x_grating_dp
        ringP = self.ring_params
        size = dpeg.data.shape[0]
        dpref = generate_ring_pattern(image_size=size,
                                      mask=True,
                                      mask_radius=mask_radius,
                                      scale=ringP[0],
                                      amplitude=ringP[1],
                                      spread=spread,
                                      direct_beam_amplitude=ringP[3],
                                      asymmetry=1,
                                      rotation=ringP[5])
        # Apply distortion corrections to experimental data
        dpegs = stack_method([dpeg, dpeg, dpeg, dpeg])
        dpegs = ElectronDiffraction(dpegs.data.reshape((2, 2, size, size)))
        dpegs.apply_affine_transformation(self.affine_matrix,
                                          preserve_range=True,
                                          inplace=True)
        # Calculate residuals to be returned
        diff_init = ElectronDiffraction(dpeg.data - dpref.data)
        diff_end = ElectronDiffraction(dpegs.inav[0, 0].data - dpref.data)
        residuals = stack_method([diff_init, diff_end])

        return ElectronDiffraction(residuals)
예제 #11
0
    def diffraction_pattern(self):
        dp = ElectronDiffraction(np.zeros((2, 8, 8)))
        dp.data[0] = np.array([[0., 0., 2., 2., 2., 2., 0., 0.],
                               [0., 2., 3., 3., 3., 3., 2., 0.],
                               [2., 3., 3., 4., 4., 3., 3., 2.],
                               [2., 3., 4., 5., 5., 4., 3., 2.],
                               [2., 3., 4., 5., 5., 4., 3., 2.],
                               [2., 3., 3., 4., 4., 3., 3., 2.],
                               [0., 2., 3., 3., 3., 3., 2., 0.],
                               [0., 0., 2., 2., 2., 2., 0., 0.]])

        dp.data[1] = np.array([[0., 0., 0., 0., 0., 0., 0., 0.],
                               [0., 0., 0., 0., 0., 0., 0., 0.],
                               [0., 0., 0., 0., 0., 0., 0., 0.],
                               [0., 0., 0., 1., 1., 0., 0., 0.],
                               [0., 0., 0., 1., 1., 0., 0., 0.],
                               [0., 0., 0., 0., 0., 0., 0., 0.],
                               [0., 0., 0., 0., 0., 0., 0., 0.],
                               [0., 0., 0., 0., 0., 0., 0., 0.]])

        return dp
예제 #12
0
def ring_pattern(input_parameters):
    x0 = input_parameters
    ring_data = generate_ring_pattern(image_size=256,
                                      mask=True,
                                      mask_radius=10,
                                      scale=x0[0],
                                      amplitude=x0[1],
                                      spread=x0[2],
                                      direct_beam_amplitude=x0[3],
                                      asymmetry=x0[4],
                                      rotation=x0[5])

    return ElectronDiffraction(ring_data)
예제 #13
0
    def plot_corrected_diffraction_pattern(self, reference_circle=True):
        """Plot the distortion corrected diffraction pattern with an optional
        reference circle.

        Parameters
        ----------
        reference_circle : bool
            If True a CircleROI widget is added to the plot for reference.

        """
        # Check all required parameters are defined as attributes
        if self.calibration_data.au_x_grating_dp is None:
            raise ValueError(
                "This method requires an Au X-grating diffraction "
                "pattern to be provided. Please update the "
                "CalibrationDataLibrary.")
        if self.affine_matrix is None:
            raise ValueError(
                "This method requires a distortion matrix to have "
                "been determined. Use get_elliptical_distortion "
                "to determine this matrix.")
        # Set name for experimental data pattern
        dpeg = self.calibration_data.au_x_grating_dp
        # Apply distortion corrections to experimental data
        size = dpeg.data.shape[0]
        dpegs = stack_method([dpeg, dpeg, dpeg, dpeg])
        dpegs = ElectronDiffraction(dpegs.data.reshape((2, 2, size, size)))
        dpegs.apply_affine_transformation(self.affine_matrix,
                                          preserve_range=True,
                                          inplace=True)
        dpegm = dpegs.mean((0, 1))
        # Plot distortion corrected data
        dpegm.plot(cmap='magma', vmax=0.1)
        # add reference circle if specified
        if reference_circle is True:
            circ = CircleROI(cx=128, cy=128, r=53.5, r_inner=0)
            circ.add_widget(dpegm)
예제 #14
0
def test_strain_mapping_affine_transform():
    latt = diffpy.structure.lattice.Lattice(3, 3, 3, 90, 90, 90)
    atom = diffpy.structure.atom.Atom(atype='Zn', xyz=[0, 0, 0], lattice=latt)
    structure = diffpy.structure.Structure(atoms=[atom], lattice=latt)
    ediff = DiffractionGenerator(300., 0.025)
    affines = [[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
               [[1.04, 0, 0], [0, 1, 0], [0, 0, 1]],
               [[1.08, 0, 0], [0, 1, 0], [0, 0, 1]],
               [[1.12, 0, 0], [0, 1, 0], [0, 0, 1]]]

    data = []
    for affine in affines:
        # same coords as used for latt above
        latt_rot = diffpy.structure.lattice.Lattice(3,
                                                    3,
                                                    3,
                                                    90,
                                                    90,
                                                    90,
                                                    baserot=affine)
        structure.placeInLattice(latt_rot)

        diff_dat = ediff.calculate_ed_data(structure, 2.5)
        dpi = diff_dat.as_signal(64, 0.02, 2.5)
        data.append(dpi.data)
    data = np.array(data)
    dp = ElectronDiffraction(data.reshape((2, 2, 64, 64)))

    m = dp.create_model()
    ref = ScalableReferencePattern(dp.inav[0, 0])
    m.append(ref)
    m.multifit()
    disp_grad = ref.construct_displacement_gradient()

    assert disp_grad.data.shape == np.asarray(affines).reshape(2, 2, 3,
                                                               3).shape
예제 #15
0
def create_spot():
    z1 = np.zeros((128, 128))
    z2 = np.zeros((128, 128))

    for r in [4, 3, 2]:
        c = 1 / r
        rr, cc = draw.circle(30, 90, radius=r, shape=z1.shape)  #30 is y!
        z1[rr, cc] = c
        z2[rr, cc] = c
        rr2, cc2 = draw.circle(100, 60, radius=r, shape=z2.shape)
        z2[rr2, cc2] = c

    dp = ElectronDiffraction(np.asarray([[z1, z1],
                                         [z2, z2]]))  # this needs to be in 2x2
    print(dp.axes_manager)
    return dp
예제 #16
0
 def single_peak(self):
     pattern = np.zeros((2, 2, 128, 128))
     pattern[:, :, 40, 45] = 1  #single point peak
     return ElectronDiffraction(pattern)
예제 #17
0
 def test_remove_background(self, diffraction_pattern: ElectronDiffraction,
                            method, kwargs):
     bgr = diffraction_pattern.remove_background(method=method, **kwargs)
     assert bgr.data.shape == diffraction_pattern.data.shape
     assert bgr.max() <= diffraction_pattern.max()
예제 #18
0
 def test_get_background_model(self,
                               diffraction_pattern: ElectronDiffraction,
                               saturation_radius):
     bgm = diffraction_pattern.get_background_model(saturation_radius)
     assert bgm.axes_manager.signal_shape == diffraction_pattern.axes_manager.signal_shape
예제 #19
0
def test_get_diffraction_variance(diffraction_pattern: ElectronDiffraction):
    dv = diffraction_pattern.get_diffraction_variance()
    assert dv.axes_manager.navigation_shape == (3, )
    assert dv.axes_manager.signal_shape == diffraction_pattern.axes_manager.signal_shape
예제 #20
0
def test_init():
    z = np.zeros((2, 2, 2, 2))
    dp = ElectronDiffraction(
        z, metadata={'Acquisition_instrument': {
            'SEM': 'Expensive-SEM'
        }})
예제 #21
0
def test_apply_gain_normalisation(diffraction_pattern: ElectronDiffraction,
                                  dark_reference, bright_reference):
    diffraction_pattern.apply_gain_normalisation(
        dark_reference=dark_reference, bright_reference=bright_reference)
    assert diffraction_pattern.max() == bright_reference
    assert diffraction_pattern.min() == dark_reference
예제 #22
0
    def get_diffraction_calibration(self, mask_length, linewidth):
        """Determine the diffraction pattern pixel size calibration in units of
        reciprocal Angsstroms per pixel.

        Parameters
        ----------
        mask_length : float
            Halfwidth of the region excluded from peak finding around the
            diffraction pattern center.
        linewidth : float
            Width of Line2DROI used to obtain line trace from distortion
            corrected diffraction pattern.

        Returns
        -------
        diff_cal : float
            Diffraction calibration in reciprocal Angstroms per pixel.

        """
        # Check that necessary calibration data is provided
        if self.calibration_data.au_x_grating_dp is None:
            raise ValueError(
                "This method requires an Au X-grating diffraction "
                "pattern to be provided. Please update the "
                "CalibrationDataLibrary.")
        if self.affine_matrix is None:
            raise ValueError(
                "This method requires a distortion matrix to have "
                "been determined. Use get_elliptical_distortion "
                "to determine this matrix.")
        dpeg = self.calibration_data.au_x_grating_dp
        size = dpeg.data.shape[0]
        dpegs = stack_method([dpeg, dpeg, dpeg, dpeg])
        dpegs = ElectronDiffraction(dpegs.data.reshape((2, 2, size, size)))
        dpegs.apply_affine_transformation(self.affine_matrix,
                                          preserve_range=True,
                                          inplace=True)
        dpegm = dpegs.mean((0, 1))
        # Define line roi along which to take trace for calibration
        line = Line2DROI(x1=5, y1=5, x2=250, y2=250, linewidth=linewidth)
        # Obtain line trace
        trace = line(dpegm)
        trace = trace.as_signal1D(0)
        # Find peaks in line trace either side of direct beam
        db = (np.sqrt(2) * 128) - (5 * np.sqrt(2))
        pka = trace.isig[db +
                         mask_length:].find_peaks1D_ohaver()[0]['position']
        pkb = trace.isig[:db -
                         mask_length].find_peaks1D_ohaver()[0]['position']
        # Determine predicted position of 022 peak of Au pattern d022=1.437
        au_pre = db - (self.ring_params[0] / 1.437)
        au_post = db + (self.ring_params[0] / 1.437)
        # Calculate differences between predicted and measured positions
        prediff = np.abs(pkb - au_pre)
        postdiff = np.abs(pka - au_post)
        # Calculate new calibration value based on most accurate peak positions
        dc = (2 / 1.437) / (pka[postdiff == min(postdiff)] -
                            pkb[prediff == min(prediff)])
        # Store diffraction calibration value as attribute
        self.diffraction_calibration = dc[0]

        return dc[0]
예제 #23
0
def simulate_kinematic_scattering(atomic_coordinates,
                                  element,
                                  accelerating_voltage,
                                  simulation_size=256,
                                  max_k=1.5,
                                  illumination='plane_wave',
                                  sigma=20,
                                  scattering_params='lobato'):
    """Simulate electron scattering from arrangement of atoms comprising one
    elemental species.

    Parameters
    ----------
    atomic_coordinates : array
        Array specifying atomic coordinates in structure.
    element : string
        Element symbol, e.g. "C".
    accelerating_voltage : float
        Accelerating voltage in keV.
    simulation_size : int
        Simulation size, n, specifies the n x n array size for
        the simulation calculation.
    max_k : float
        Maximum scattering vector magnitude in reciprocal angstroms.
    illumination : string
        Either 'plane_wave' or 'gaussian_probe' illumination
    sigma : float
        Gaussian probe standard deviation, used when illumination == 'gaussian_probe'
    scattering_params : string
        Type of scattering factor calculation to use. One of 'lobato', 'xtables'.

    Returns
    -------
    simulation : ElectronDiffraction
        ElectronDiffraction simulation.
    """
    # Delayed loading to prevent circular dependencies.
    from pyxem.signals.electron_diffraction import ElectronDiffraction

    # Get atomic scattering parameters for specified element.
    coeffs = np.array(get_scattering_params_dict(scattering_params)[element])

    # Calculate electron wavelength for given keV.
    wavelength = get_electron_wavelength(accelerating_voltage)

    # Define a 2D array of k-vectors at which to evaluate scattering.
    l = np.linspace(-max_k, max_k, simulation_size)
    kx, ky = np.meshgrid(l, l)

    # Convert 2D k-vectors into 3D k-vectors accounting for Ewald sphere.
    k = np.array((kx, ky, (wavelength / 2) * (kx**2 + ky**2)))

    # Calculate scattering vector squared for each k-vector.
    gs_sq = np.linalg.norm(k, axis=0)**2

    # Get the scattering factors for this element.
    fs = get_atomic_scattering_factors(gs_sq, coeffs[np.newaxis, :],
                                       scattering_params)

    # Evaluate scattering from all atoms
    scattering = np.zeros_like(gs_sq)
    if illumination == 'plane_wave':
        for r in atomic_coordinates:
            scattering = scattering + (fs *
                                       np.exp(np.dot(k.T, r) * np.pi * 2j))
    elif illumination == 'gaussian_probe':
        for r in atomic_coordinates:
            probe = (1 / (np.sqrt(2 * np.pi) * sigma)) * \
                np.exp((-np.abs(((r[0]**2) - (r[1]**2)))) / (4 * sigma**2))
            scattering = scattering + (probe * fs *
                                       np.exp(np.dot(k.T, r) * np.pi * 2j))
    else:
        raise ValueError(
            "User specified illumination '{}' not defined.".format(
                illumination))

    # Calculate intensity
    intensity = (scattering * scattering.conjugate()).real

    return ElectronDiffraction(intensity)
예제 #24
0
 def ragged_peak(self):
     pattern = np.zeros((2, 2, 128, 128))
     pattern[:, :, 40, 45] = 1
     pattern[1, 0, 71, 21] = 1
     return ElectronDiffraction(pattern)
예제 #25
0
def diffraction_pattern(request):
    return ElectronDiffraction(request.param)
예제 #26
0
 def axes_test_dp(self):
     dp_data = np.random.randint(0, 10, (2, 2, 10, 10))
     dp = ElectronDiffraction(dp_data)
     return dp
예제 #27
0
def diffraction_pattern(request):
    """
    A boring, multiuse dp, with signature: ElectronDiffraction <2,2|8,8>
    """
    return ElectronDiffraction(request.param)
예제 #28
0
def diffraction_pattern_one_dimension(request):
    """
    1D (in navigation space) diffraction pattern <1|8,8>
    """
    return ElectronDiffraction(request.param)
예제 #29
0
def simulate_kinematic_scattering(atomic_coordinates,
                                  element,
                                  accelerating_voltage,
                                  simulation_size=256,
                                  max_k=1.5,
                                  illumination='plane_wave',
                                  sigma=20,
                                  scattering_params='lobato'):
    """Simulate electron scattering from arrangement of atoms comprising one
    elemental species.

    Parameters
    ----------
    atomic_coordinates : array
        Array specifying atomic coordinates in structure.
    element : string
        Element symbol, e.g. "C".
    accelerating_voltage : float
        Accelerating voltage in keV.
    simulation_size : int
        Simulation size, n, specifies the n x n array size for
        the simulation calculation.
    max_k : float
        Maximum scattering vector magnitude in reciprocal angstroms.
    illumination = string
        Either 'plane_wave' or 'gaussian_probe' illumination

    Returns
    -------
    simulation : ElectronDiffraction
        ElectronDiffraction simulation.
    """
    # Delayed loading to prevent circular dependencies.
    from pyxem.signals.electron_diffraction import ElectronDiffraction

    # Get atomic scattering parameters for specified element.
    if scattering_params == 'lobato':
        c = np.array(ATOMIC_SCATTERING_PARAMS_LOBATO[element])
    elif scattering_params == 'xtables':
        c = np.array(ATOMIC_SCATTERING_PARAMS[element])
    else:
        raise NotImplementedError(
            "The scattering parameters `{}` are not implemented. "
            "See documentation for available "
            "implementations.".format(scattering_params))
    # Calculate electron wavelength for given keV.
    wavelength = get_electron_wavelength(accelerating_voltage)

    # Define a 2D array of k-vectors at which to evaluate scattering.
    l = np.linspace(-max_k, max_k, simulation_size)
    kx, ky = np.meshgrid(l, l)

    # Convert 2D k-vectors into 3D k-vectors accounting for Ewald sphere.
    k = np.array((kx, ky, (wavelength / 2) * (kx**2 + ky**2)))

    # Calculate scatering angle squared for each k-vector.
    s2s = (np.linalg.norm(k, axis=0) / 2)**2
    gs = (np.linalg.norm(k, axis=0))

    # Evaluate atomic scattering factor.
    if scattering_params == 'lobato':
        fs = np.zeros_like(s2s)
        for i in np.arange(5):
            fs = (fs + c[i, 0] * (2 + c[i, 1] * gs**2) *
                  np.divide(1, np.square(1 + c[i, 1] * gs**2)))
    elif scattering_params == 'xtables':
        fs = np.zeros_like(s2s)
        for i in np.arange(5):
            fs = fs + (c[i][0] * np.exp(-c[i][1] * s2s))

    # Evaluate scattering from all atoms
    scattering = np.zeros_like(s2s)
    if illumination == 'plane_wave':
        for r in atomic_coordinates:
            scattering = scattering + (fs *
                                       np.exp(np.dot(k.T, r) * np.pi * 2j))
    elif illumination == 'gaussian_probe':
        for r in atomic_coordinates:
            probe = (1 / (np.sqrt(2 * np.pi) * sigma)) * \
                np.exp((-np.abs(((r[0]**2) - (r[1]**2)))) / (4 * sigma**2))
            scattering = scattering + (probe * fs *
                                       np.exp(np.dot(k.T, r) * np.pi * 2j))
    else:
        raise ValueError("User specified illumination not defined.")

    # Calculate intensity
    intensity = (scattering * scattering.conjugate()).real

    return ElectronDiffraction(intensity)
예제 #30
0
def diffraction_pattern(request):
    """A simple, multiuse dp, with dimensions: ElectronDiffraction <2,2|8,8>
    """
    return ElectronDiffraction(request.param)