def add_to_mask(mask, pix_list, save_path=None): """ Adds an arbitrary list of pixels to a mask. Parameters __________ mask: pyxem ElectronDiffraction2D mask as pyxem object pix_list: list of tuples of ints list of pixels expressed as tuples to be added to a mask save_path: str default None. If desired to save this new version, full path of h5 file to be provided here. Returns ___________ mask_new: pyxem ElectronDiffraction2D """ mask_new = mask.data for pix in range(len(pix_list)): mask_new[pix_list[pix][1], pix_list[pix][0]] = False if save_path is not None: h5f = h5py.File(save_path, 'w') h5f.create_dataset('merlin_mask', data=mask_new) h5f.close() mask_new = pxm.ElectronDiffraction2D(mask_new) pxm_name, ext = os.path.splitext(save_path) mask.save(pxm_name) else: mask_new = pxm.ElectronDiffraction2D(mask_new) return mask_new
def generate_diffraction_patterns(structure,edc): # generates 4, dumb patterns in a 2x2 array, rotated around c axis dp_library = get_template_library(structure, [(90,90,4)], edc) for sim in dp_library['A']['simulations']: pattern = (sim_as_signal(sim, 2 * half_side_length, 0.025, 1).data) dp = pxm.ElectronDiffraction2D([[pattern, pattern], [pattern, pattern]]) return dp
def make_mask(flat_field, hot_pix_factor, show_mask=True, dest_h5_path=None, show_hist=False): """ Creates mask for Merlin Medipix Parameters: _____________ flat_field: str full path of the flat-field mib data hot_pix_factor: float intensity factor above average intensity to determine hot pixels show_mask: bool Default True. For plotting the mask. dest_h5_path: str default None. full path of the h5 file to be saved. key for mask: 'merlin_mask'. A pyxem version of the mask is also saved in the same destination. show_hist: bool If passed as True a histogram of the flat-feild data is shown (averaged if the data is a stack) Returns ________ mask: pyxem ElectronDiffraction2D mask pyxem object """ flat_data = pxm.load_mib(flat_field) flat_data.compute() shape = flat_data.axes_manager[-1].size * flat_data.axes_manager[-2].size # in case a stack, replace with mean if flat_data.axes_manager[0].size > 1: flat_data = flat_data.mean() if show_hist: flat_int_array = flat_data.data.reshape((shape, )) plt.figure() plt.hist(flat_int_array, bins=100, log=True) flat_int_ave = np.mean(flat_data.data) print('flat field intensity average is: ', flat_int_ave) mask_dead = flat_data.data.astype(bool) mask_hot = flat_data.data < (flat_int_ave * hot_pix_factor) mask_hot_and_dead = np.logical_and(mask_dead, mask_hot) # Do we need to save these separately? mask = mask_hot_and_dead mask = pxm.ElectronDiffraction2D(mask) if show_mask: plt.figure() plt.imshow(mask_hot_and_dead) if dest_h5_path is not None: h5f = h5py.File(dest_h5_path, 'w') h5f.create_dataset('merlin_mask', data=mask_hot_and_dead) h5f.close() pxm_name, ext = os.path.splitext(dest_h5_path) mask.save(pxm_name) return mask
def investigate_dog_background_removal_interactive( sample_dp, std_dev_maxs, std_dev_mins ): """Utility function to help the parameter selection for the difference of gaussians (dog) background subtraction method Parameters ---------- sample_dp : ElectronDiffraction2D A single diffraction pattern std_dev_maxs : iterable Linearly spaced maximum standard deviations to be tried, ascending std_dev_mins : iterable Linearly spaced minimum standard deviations to be tried, ascending Returns ------- A hyperspy like navigation (sigma parameters), signal (proccessed patterns) plot See Also -------- subtract_background_dog : The background subtraction method used. np.arange : Produces suitable objects for std_dev_maxs """ gauss_processed = np.empty( (len(std_dev_maxs), len(std_dev_mins), *sample_dp.axes_manager.signal_shape) ) for i, std_dev_max in enumerate(tqdm(std_dev_maxs, leave=False)): for j, std_dev_min in enumerate(std_dev_mins): gauss_processed[i, j] = sample_dp.subtract_diffraction_background( 'difference of gaussians', lazy_result=False, min_sigma=std_dev_min, max_sigma=std_dev_max, show_progressbar=False, ) dp_gaussian = pxm.ElectronDiffraction2D(gauss_processed) dp_gaussian.metadata.General.title = "Gaussian preprocessed" dp_gaussian.axes_manager.navigation_axes[0].name = r"$\sigma_{\mathrm{min}}$" dp_gaussian.axes_manager.navigation_axes[1].name = r"$\sigma_{\mathrm{max}}$" for axes_number, axes_value_list in [(0, std_dev_mins), (1, std_dev_maxs)]: dp_gaussian.axes_manager.navigation_axes[axes_number].offset = axes_value_list[ 0 ] dp_gaussian.axes_manager.navigation_axes[axes_number].scale = ( axes_value_list[1] - axes_value_list[0] ) dp_gaussian.axes_manager.navigation_axes[axes_number].units = "" dp_gaussian.plot(cmap="viridis") return None
def get_template_match_results(structure, pattern_list, edc, rot_list, mask=None, inplane_rotations=[0]): dp_library = get_template_library(structure, pattern_list, edc) for sim in dp_library['A']['simulations']: pattern = (sim_as_signal(sim, 2 * half_side_length, 0.025, 1).data) dp = pxm.ElectronDiffraction2D([[pattern, pattern], [pattern, pattern]]) library = get_template_library(structure, rot_list, edc) indexer = IndexationGenerator(dp, library) return indexer.correlate(mask=mask, inplane_rotations=inplane_rotations)
def test_marker_placement_correct_beta(): dps = [] dp_cord_list = np.divide(generate_dp_cord_list(), 80) max_r = np.max(dp_cord_list) + 0.1 for coords in dp_cord_list: dp_sim = DiffractionSimulation(coordinates=coords, intensities=np.ones_like(coords[:, 0])) dps.append(sim_as_signal(dp_sim, 144, 0.025, max_r).data) # stores a numpy array of pattern dp = pxm.ElectronDiffraction2D(np.array([dps[0:2], dps[2:]])) # now from a 2x2 array of patterns dp.set_diffraction_calibration(2 * max_r / (144)) local_plotter(dp, dp_cord_list) # This is human assessed, if you see this comment, you should check it assert True
def test_marker_placement_correct_alpha(): dps = [] dp_cord_list = generate_dp_cord_list() for coords in dp_cord_list: back = np.zeros((144, 144)) x = coords.astype(int)[0, 0] y = coords.astype(int)[0, 1] back[x, y] = 1 dps.append(back.T) # stores a numpy array of pattern, This is dangerous (T everywhere) dp = pxm.ElectronDiffraction2D(np.array([dps[0:2], dps[2:]])) local_plotter(dp, dp_cord_list) # This is human assessed, if you see this comment, you should check it assert True
def create_library_and_diffraction_pattern(): """ This creates a library, the first 4 entries of which are used to create the relevant diffraction patterns, we then test the we get suitable results for matching """ dps = [] half_shape = (72, 72) num_orientations = 11 simulations = np.empty(num_orientations, dtype="object") orientations = np.empty(num_orientations, dtype="object") pixel_coords = np.empty(num_orientations, dtype="object") intensities = np.empty(num_orientations, dtype="object") # Creating the matchresults. for alpha in np.arange(11): coords = (np.random.rand(5, 2) - 0.5) * 2 # zero mean, range from -1 to +1 simulated_pattern = DiffractionSimulation( coordinates=coords, intensities=np.ones_like(coords[:, 0]), calibration=1 / 72, ) simulations[alpha] = simulated_pattern orientations[alpha] = (alpha, alpha, alpha) intensities[alpha] = simulated_pattern.intensities pixel_coords[alpha] = ( simulated_pattern.calibrated_coordinates[:, :2] + half_shape).astype(int) if alpha < 4: z = sim_as_signal(simulated_pattern, 2 * 72, 0.075, 1) dps.append(z.data) # stores a numpy array of pattern dp = pxm.ElectronDiffraction2D([dps[0:2], dps[2:] ]) # now from a 2x2 array of patterns library = DiffractionLibrary() library["Phase"] = { "simulations": simulations, "orientations": orientations, "pixel_coords": pixel_coords, "intensities": intensities, } return dp, library
def create_diffraction_from_fft(image, number_of_tiles=16): image = hs.load(image) ## here we are going to split the images into number_of_tiles = number_of_tiles split_images = image.split(axis='x', number_of_parts=number_of_tiles) for i in range(len(split_images)): split_images[i] = split_images[i].split( axis='y', number_of_parts=number_of_tiles) ## getting all the callibration value to use for diffraction pattern tiles later size = split_images[0][0].axes_manager['x'].size scale = split_images[0][0].axes_manager['x'].scale units = split_images[0][0].axes_manager['x'].units scan_step = size * scale fft_list = [] for j in range(number_of_tiles): col = [] for i in range(number_of_tiles): im = split_images[i][j] fft = im.fft(shift=True, apodization=True).amplitude fft_list.append(fft.data) pattern_size = fft.axes_manager['x'].size calibration = fft.axes_manager['x'].scale units = fft.axes_manager['x'].units ## reshape and stack dp = pxm.ElectronDiffraction2D( np.asarray(fft_list).reshape(number_of_tiles, number_of_tiles, pattern_size, pattern_size)) dp.set_diffraction_calibration(calibration / 10) dp.set_scan_calibration(scan_step) return dp
def create_library(): dps = [] half_side_length = 72 half_shape = (half_side_length, half_side_length) num_orientations = 11 simulations = np.empty(num_orientations, dtype='object') orientations = np.empty(num_orientations, dtype='object') pixel_coords = np.empty(num_orientations, dtype='object') intensities = np.empty(num_orientations, dtype='object') # Creating the matchresults. for alpha in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]: coords = (np.random.rand(5, 2) - 0.5) * 2 # zero mean, range from -1 to +1 dp_sim = DiffractionSimulation(coordinates=coords, intensities=np.ones_like(coords[:, 0]), calibration=1 / half_side_length) simulations[alpha] = dp_sim orientations[alpha] = (alpha, alpha, alpha) pixel_coords[alpha] = (dp_sim.calibrated_coordinates[:, :2] + half_shape).astype(int) intensities[alpha] = dp_sim.intensities if alpha < 4: dps.append( sim_as_signal(dp_sim, 2 * half_side_length, 0.075, 1).data) # stores a numpy array of pattern library = DiffractionLibrary() library["Phase"] = { 'simulations': simulations, 'orientations': orientations, 'pixel_coords': pixel_coords, 'intensities': intensities, } dp = pxm.ElectronDiffraction2D([dps[0:2], dps[2:] ]) # now from a 2x2 array of patterns return dp, library
def _load_and_cast(filepath,x,y,chunk_size): """ Loads a chunk of a larger diffraction pattern""" s = hs.load(filepath,lazy=True) s = s.inav[x:x+chunk_size,y:y+chunk_size] s.compute() return pxm.ElectronDiffraction2D(s)
aug = diffpy.structure.loadStructure('augite.cif') pig = diffpy.structure.loadStructure('pigeonite.cif') structure_library_generator = StructureLibraryGenerator( [('Aug', aug, 'monoclinic'), ('Pig', pig, 'monoclinic')]) in_plane_rotation = [(0,), (0,)] angular_resolution = 1 structure_library = structure_library_generator.get_orientations_from_stereographic_triangle( in_plane_rotation, # In-plane rotations angular_resolution) # Angular resolution of the library ### load fft and set as ElectronDiffraction2D im = pxm.load_hspy(dps.loc[image,'dp']) dp = pxm.ElectronDiffraction2D(im.data) dp.set_diffraction_calibration(im.axes_manager['kx'].scale) dp.set_scan_calibration(im.axes_manager['x'].scale) pattern_size = dp.axes_manager['x'].size calibration = dp.axes_manager['kx'].scale diffraction_calibration = calibration half_pattern_size = pattern_size // 2 reciprocal_radius = diffraction_calibration*(half_pattern_size - 1) beam_energy = 300.0 ediff = DiffractionGenerator(beam_energy, 0.025) diff_gen = DiffractionLibraryGenerator(ediff)
def big_electron_diffraction_pattern(): z = np.arange(0, 160, step=1).reshape(4, 10, 2, 2) # x_size=10, y_size=4 in hspy dp = pxm.ElectronDiffraction2D(z) return dp