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 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)
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)
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]