예제 #1
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)
예제 #2
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)
예제 #3
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)
예제 #4
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]