# This script calculates multiple images using a unit cell tiled varying numbers of times in Z. # This type of simulation is useful for determining the true thickness of a sample from experimental images import pyprismatic as pr import numpy as np import matplotlib.pyplot as plt base_output_name = "thickness_scan" base_output_ext = ".mrc" atom_filename = "../SI100.XYZ" tileX = tileY = 3 meta = pr.Metadata(filenameAtoms=atom_filename, tileX=tileX, tileY=tileY) output_filenames = [] # run simulations for tileZ in range(1, 17): meta.tileZ = tileZ meta.filenameOutput = base_output_name + str(tileZ) + base_output_ext output_filenames.extend([meta.filenameOutput]) meta.go() # print the results f, ax = plt.subplots(4, 4) ax = ax.ravel() for i, filename in enumerate(output_filenames): stack = pr.fileio.readMRC(filename) img = np.sum(stack[:, :, :10], axis=2) ax[i].imshow(img) ax[i].set_title("Thicknesss: {:.2f}$\AA$".format((i + 1) * 5.43)) ax[i].set_yticklabels([]) ax[i].set_xticklabels([])
def image_refine_via_intensity_loop(atom_lattice, change_sublattice, calibration_separation, calibration_area, percent_to_nn, mask_radius, element_list, image_sampling, iterations, delta_image_filter, image_size_x_nm, image_size_y_nm, image_size_z_nm, simulation_filename, filename, intensity_type, intensity_refine_name='intensity_refine_', folder_name='refinement_of_intensity'): for sub in atom_lattice.sublattice_list: if sub.name == 'sub1': sub1 = sub elif sub.name == 'sub2': sub2 = sub elif sub.name == 'sub3': sub3 = sub else: pass if len(atom_lattice.image) == 1: # image_pixel_x = len(atom_lattice.image.data[0, :]) # image_pixel_y = len(atom_lattice.image.data[:, 0]) # atom_lattice_data = atom_lattice.image.data atom_lattice_signal = atom_lattice.image elif len(atom_lattice.image) > 1: # image_pixel_x = len(atom_lattice.image[0, :]) # image_pixel_y = len(atom_lattice.image[:, 0]) # atom_lattice_data = atom_lattice.image atom_lattice_signal = atom_lattice.signal ''' Image Intensity Loop ''' if len(calibration_area) != 2: raise ValueError('calibration_area_simulation must be two points') df_inten_refine = pd.DataFrame(columns=element_list) real_sampling_exp_angs = image_sampling * 10 if str(real_sampling_exp_angs)[-1] == '5': real_sampling_sim_angs = real_sampling_exp_angs + 0.000005 else: pass for suffix in range(1, iterations): loading_suffix = '_' + str(suffix) saving_suffix = '_' + str(suffix + 1) if '.xyz' in simulation_filename: pass else: simulation_filename = simulation_filename + '.xyz' file_exists = os.path.isfile(simulation_filename) if file_exists: pass else: raise OSError('XYZ file not found, stopping refinement') file = pr.Metadata(filenameAtoms=simulation_filename, E0=60e3) file.integrationAngleMin = 0.085 file.integrationAngleMax = 0.186 file.interpolationFactorX = file.interpolationFactorY = 16 file.realspacePixelSizeX = file.realspacePixelSizeY = 0.0654 # file.probeStepX = file.cellDimX/atom_lattice_data.shape[1] # file.probeStepY = file.cellDimY/atom_lattice_data.shape[0] file.probeStepX = round(real_sampling_sim_angs, 6) file.probeStepY = round(real_sampling_sim_angs, 6) file.numFP = 1 file.probeSemiangle = 0.030 file.alphaBeamMax = 0.032 # in rads file.detectorAngleStep = 0.001 file.scanWindowXMin = file.scanWindowYMin = 0.0 file.scanWindowYMax = file.scanWindowXMax = 1.0 file.algorithm = "prism" file.numThreads = 2 file.save3DOutput = False file.filenameOutput = intensity_refine_name + loading_suffix + ".mrc" file.go() simulation = hs.load('prism_2Doutput_' + file.filenameOutput) simulation.axes_manager[0].name = 'extra_dimension' simulation = simulation.sum('extra_dimension') simulation.axes_manager[0].scale = image_sampling simulation.axes_manager[1].scale = image_sampling calibrate_intensity_distance_with_sublattice_roi( image=simulation, cropping_area=calibration_area, separation=calibration_separation, filename=intensity_refine_name + "Simulation" + loading_suffix, percent_to_nn=percent_to_nn, mask_radius=mask_radius, scalebar_true=True) # simulation.plot() # Filter the image with Gaussian noise to get better match with # experiment simulation_new = compare_two_image_and_create_filtered_image( image_to_filter=simulation, reference_image=atom_lattice_signal, delta_image_filter=delta_image_filter, cropping_area=calibration_area, separation=calibration_separation, percent_to_nn=percent_to_nn, mask_radius=mask_radius, refine=False, filename=filename) simulation = simulation_new simulation.save(intensity_refine_name + 'Filt_Simulation' + loading_suffix + '.hspy') simulation.plot() plt.title('Filt_Simulation' + loading_suffix, fontsize=20) plt.gca().axes.get_xaxis().set_visible(False) plt.gca().axes.get_yaxis().set_visible(False) plt.tight_layout() plt.savefig(fname=intensity_refine_name + 'Filt_Simulation' + loading_suffix + '.png', transparent=True, frameon=False, bbox_inches='tight', pad_inches=None, dpi=300, labels=False) plt.close() ''' Need to add the intensity type to the image_difference_intensity algorithm! ''' counter_before_refinement = count_atoms_in_sublattice_list( sublattice_list=atom_lattice.sublattice_list, filename=intensity_refine_name + 'Elements' + loading_suffix) if suffix == 1: df_inten_refine = df_inten_refine.append( counter_before_refinement, ignore_index=True).fillna(0) else: pass ''' Sub1 ''' image_difference_intensity(sublattice=sub1, simulation_image=simulation, element_list=element_list, percent_to_nn=percent_to_nn, mask_radius=mask_radius, change_sublattice=change_sublattice, filename=filename) # sub1_info_refined = print_sublattice_elements(sub1) ''' Sub2 ''' image_difference_intensity(sublattice=sub2, simulation_image=simulation, element_list=element_list, percent_to_nn=percent_to_nn, mask_radius=mask_radius, change_sublattice=change_sublattice, filename=filename) # sub2_info_refined = print_sublattice_elements(sub2) ''' Sub3 ''' image_difference_intensity(sublattice=sub3, simulation_image=simulation, element_list=element_list, percent_to_nn=percent_to_nn, mask_radius=mask_radius, change_sublattice=change_sublattice, filename=filename) # sub3_info_refined = print_sublattice_elements(sub3) counter_after_refinement = count_atoms_in_sublattice_list( sublattice_list=atom_lattice.sublattice_list, filename=intensity_refine_name + 'Elements' + saving_suffix) df_inten_refine = df_inten_refine.append(counter_after_refinement, ignore_index=True).fillna(0) compare_sublattices = compare_count_atoms_in_sublattice_list( counter_list=[counter_before_refinement, counter_after_refinement]) if compare_sublattices is True: print('Finished Refinement! No more changes.') break if suffix > 4: if df_inten_refine.diff(periods=2)[-4:].all(axis=1).all() is False: # if statement steps above: # .diff(periods=2) gets the difference between each row, # and the row two above it [-4:] slices this new difference # df to get the final four rows # .all(axis=1) checks if # all row elements are zero or NaN and returns False # .all() check if all four of these results are False # Basically checking that the intensity refinement is # repeating every second iteration print('Finished Refinement! Repeating every second iteration.') break ''' Remake XYZ file for further refinement''' # loading_suffix is now saving_suffix create_dataframe_for_xyz( sublattice_list=atom_lattice.sublattice_list, element_list=element_list, x_distance=image_size_x_nm * 10, y_distance=image_size_y_nm * 10, z_distance=image_size_z_nm * 10, filename=filename + saving_suffix, header_comment='Something Something Something Dark Side') # dataframe_intensity = create_dataframe_for_xyz( # sublattice_list=atom_lattice.sublattice_list, # element_list=element_list, # x_distance=image_size_x_nm*10, # y_distance=image_size_y_nm*10, # z_distance=image_size_z_nm*10, # filename=intensity_refine_name + image_name + saving_suffix, # header_comment='Something Something Something Dark Side') # when ready: example_df_cif = create_dataframe_for_cif( sublattice_list=atom_lattice.sublattice_list, element_list=element_list) write_cif_from_dataframe(dataframe=example_df_cif, filename=intensity_refine_name + filename + saving_suffix, chemical_name_common='MoSx-1Sex', cell_length_a=image_size_x_nm * 10, cell_length_b=image_size_y_nm * 10, cell_length_c=image_size_z_nm * 10) df_inten_refine.to_pickle(intensity_refine_name + 'df_inten_refine.pkl') df_inten_refine.to_csv(intensity_refine_name + 'df_inten_refine.csv', sep=',', index=False) # https://python-graph-gallery.com/124-spaghetti-plot/ # https://stackoverflow.com/questions/8931268/using-colormaps- # to-set-color-of-line-in-matplotlib plt.figure() palette = plt.get_cmap('tab20') # plt.style.use('seaborn-darkgrid') # multiple line plot color_num = 0 for df_column in df_inten_refine: # print(df_column) color_num += 1 plt.plot(df_inten_refine.index, df_inten_refine[df_column], marker='', color=palette(color_num), linewidth=1, alpha=0.9, label=df_column) plt.xlim(0, len(df_inten_refine.index) + 1) plt.legend(loc=5, ncol=1, fontsize=10, fancybox=True, frameon=True, framealpha=1) plt.title("Refinement of Atoms via Intensity \nAll Elements", loc='left', fontsize=16, fontweight=0) plt.xlabel("Refinement Iteration", fontsize=16, fontweight=0) plt.ylabel("Count of Element", fontsize=16, fontweight=0) plt.tight_layout() plt.savefig(fname=intensity_refine_name + 'inten_refine_all.png', transparent=True, frameon=False, bbox_inches='tight', pad_inches=None, dpi=300, labels=False) plt.close() atom_of_interest = 'Mo_1' # Highlight Plot text_position = (len(df_inten_refine.index) + 0.2) - 1 plt.figure() # plt.style.use('seaborn-darkgrid') # multiple line plot for df_column in df_inten_refine: plt.plot(df_inten_refine.index, df_inten_refine[df_column], marker='', color='grey', linewidth=1, alpha=0.4) plt.plot(df_inten_refine.index, df_inten_refine[atom_of_interest], marker='', color='orange', linewidth=4, alpha=0.7) plt.xlim(0, len(df_inten_refine.index) + 1) # Let's annotate the plot num = 0 for i in df_inten_refine.values[len(df_inten_refine.index) - 2][1:]: num += 1 name = list(df_inten_refine)[num] if name != atom_of_interest: plt.text(text_position, i, name, horizontalalignment='left', size='small', color='grey') plt.text(text_position, df_inten_refine.Mo_1.tail(1), 'Moly', horizontalalignment='left', size='medium', color='orange') plt.title("Refinement of Atoms via Intensity", loc='left', fontsize=16, fontweight=0) plt.xlabel("Refinement Iteration", fontsize=16, fontweight=0) plt.ylabel("Count of Element", fontsize=16, fontweight=0) plt.tight_layout() plt.savefig(fname=intensity_refine_name + 'inten_refine.png', transparent=True, frameon=False, bbox_inches='tight', pad_inches=None, dpi=300, labels=False) plt.close() ''' ATOM LATTICE with simulation refinement ''' atom_lattice_int_ref_name = 'Atom_Lattice_' + \ intensity_type + '_refined' + saving_suffix atom_lattice_int_ref = am.Atom_Lattice( image=atom_lattice_signal, name=atom_lattice_int_ref_name, sublattice_list=atom_lattice.sublattice_list) atom_lattice_int_ref.save(filename=intensity_refine_name + atom_lattice_int_ref_name + ".hdf5", overwrite=True) atom_lattice_int_ref.save(filename=atom_lattice_int_ref_name + "_intensity.hdf5", overwrite=True) atom_lattice_int_ref.get_sublattice_atom_list_on_image(markersize=2).plot() plt.title(atom_lattice_int_ref_name, fontsize=20) plt.gca().axes.get_xaxis().set_visible(False) plt.gca().axes.get_yaxis().set_visible(False) plt.tight_layout() plt.savefig(fname=intensity_refine_name + atom_lattice_int_ref_name + '.png', transparent=True, frameon=False, bbox_inches='tight', pad_inches=None, dpi=300, labels=False) plt.close() create_new_folder('./' + folder_name + '/') intensity_refine_filenames = glob('*' + intensity_refine_name + '*') for intensity_refine_file in intensity_refine_filenames: # print(position_refine_file, position_refine_name + '/' + # position_refine_file) os.rename(intensity_refine_file, folder_name + '/' + intensity_refine_file)
def run_sim(self): # Changing units from SI to A and mrad and kV xyz = self.params_dict['atomic_model'] pixelSize = self.params_dict['pixel-size-x'] * 1e10 num_FP = self.params_dict['num-FP'] slice_thickness = self.params_dict['slice-thickness'] * 1e10 E0 = self.params_dict['energy'] * 1e-3 alpha_max = self.params_dict['alpha-max'] * 1e3 step_size = self.params_dict['probe-step-x'] * 1e10 cell_tiling = self.params_dict['tile-uc'] def_val = self.params_dict['probe-defocus'] * 1e10 conv_semiangle = self.params_dict['probe-semiangle'] * 1e3 scan_win_x = self.params_dict['scan-window-x'] scan_win_y = self.params_dict['scan-window-y'] probe_tilt_x = self.params_dict['probe-xtilt'] * 1e3 probe_tilt_y = self.params_dict['probe-ytilt'] * 1e3 c3 = self.params_dict['C3'] * 1e10 c5 = self.params_dict['C5'] * 1e10 meta = pr.Metadata(filenameAtoms=xyz) meta.algorithm = 'multislice' meta.filenameOutput = self.params_dict['output_path'] meta.realspacePixelSizeX = pixelSize meta.realspacePixelSizeY = pixelSize meta.potBound = 2 meta.numFP = num_FP meta.sliceThickness = slice_thickness meta.E0 = E0 meta.alphaBeamMax = alpha_max meta.batchSizeCPU = 1 meta.probeStepX = float(step_size) meta.probeStepY = float(step_size) cell_dims = self._get_cell_dims() meta.cellDimX = cell_dims[0] meta.cellDimY = cell_dims[1] meta.cellDimZ = cell_dims[2] meta.tileX = cell_tiling[0] meta.tileY = cell_tiling[1] meta.tileZ = cell_tiling[2] meta.probeDefocus = float(def_val) meta.C3 = c3 meta.C5 = c5 if 'aberrations_file' in self.params_dict: if self.params_dict['aberrations_file'] is not None: meta.aberrations_file = self.params_dict['aberrations_file'] meta.probeSemiangle = float(conv_semiangle) meta.detectorAngleStep = 1 meta.probeXtilt = probe_tilt_x meta.probeYtilt = probe_tilt_y meta.scanWindowXMin = scan_win_x[0] meta.scanWindowXMax = scan_win_x[1] meta.scanWindowYMin = scan_win_y[0] meta.scanWindowYMax = scan_win_y[1] meta.randomSeed = self.params_dict['random_seed'] meta.includeThermalEffects = self.params_dict['thermal-effects'] meta.save2DOutput = 0 meta.save3DOutput = 0 meta.save4DOutput = 1 meta.nyquistSampling = 0 meta.saveDPC_CoM = 0 meta.savePotentialSlices = self.params_dict['save-potential-slices'] meta.alsoDoCPUWork = 1 meta.batchSizeGPU = 1 meta.numGPUs = 2 meta.numStreamsPerGPU = 3 meta.saveProbe = 1 meta.maxFileSize = 5 * 10**9 meta.go()
def simulate_with_prismatic(xyz_filename, filename, reference_image=None, probeStep=1.0, E0=60e3, integrationAngleMin=0.085, integrationAngleMax=0.186, detectorAngleStep=0.001, interpolationFactor=16, realspacePixelSize=0.0654, numFP=1, cellDimXYZ=None, tileXYZ=None, probeSemiangle=0.030, alphaBeamMax=0.032, scanWindowMin=0.0, scanWindowMax=1.0, algorithm="prism", numThreads=2): ''' Simulate an xyz coordinate model with pyprismatic fast simulation software. Parameters ---------- xyz_filename : string filename of the xyz coordinate model. Must be in the prismatic format. See http://prism-em.com/docs-inputs/ for more information. filename : string, default None name with which the image will be saved reference_image : hyperspy signal 2D image from which calibration information is taken, such as sampling, pixel height and pixel width probeStep : float, default 1.0 Should be the sampling of the image, where sampling = length (in angstrom)/pixels If you want the probeStep to be calculated from the reference image, set this to None. E0, numThreads etc., : Prismatic parameters See http://prism-em.com/docs-params/ cellDimXYZ : tuple, default None A tuple of length 3. Example (2.3, 4.5, 5.6). If this is set to None, the cell dimension values from the .xyz file will be used (default). If it is specified, it will overwrite the .xyz file values. tileXYZ : tuple, deault None A tuple of length 3. Example (5, 5, 2) would multiply the model in x and y by 5, and z by 2. Default of None is just set to (1, 1, 1) Returns ------- Simulated image as a 2D mrc file Examples -------- >>> from temul.simulations import simulate_with_prismatic >>> simulate_with_prismatic( ... xyz_filename="example_data/prismatic/" ... "MoS2_hex_prismatic.xyz", ... filename='prismatic_simulation', ... probeStep=1.0, reference_image=None, E0=60e3, ... integrationAngleMin=0.085, ... integrationAngleMax=0.186, ... interpolationFactor=16, ... realspacePixelSize=0.0654, ... numFP=1, probeSemiangle=0.030, alphaBeamMax=0.032, ... scanWindowMin=0.0, scanWindowMax=1.0, ... algorithm="prism", numThreads=2) ''' if '.xyz' not in xyz_filename: simulation_filename = xyz_filename + '.XYZ' else: simulation_filename = xyz_filename file_exists = os.path.isfile(simulation_filename) if file_exists: pass else: raise OSError('XYZ file not found in directory, stopping refinement') # param inputs, feel free to add more!! pr_sim = pr.Metadata(filenameAtoms=simulation_filename) # use the reference image to get the probe step if given # fix these if reference_image is None and probeStep is None: raise ValueError("Both reference_image and probeStep are None.\ Either choose a reference image, from which a probe step can\ be calculated, or choose a probeStep.") elif reference_image is not None and probeStep is not None: print("Note: Both reference_image and probeStep have been specified. " "reference_image will be used.") if reference_image is not None: real_sampling = reference_image.axes_manager[0].scale if reference_image.axes_manager[-1].units == 'nm': real_sampling_exp_angs = real_sampling * 10 else: real_sampling_exp_angs = real_sampling if str(real_sampling_exp_angs)[-1] == '5': real_sampling_sim_angs = real_sampling_exp_angs + 0.000005 pr_sim.probeStepX = pr_sim.probeStepY = round( real_sampling_sim_angs, 6) else: real_sampling_sim_angs = real_sampling_exp_angs + 0.000005 pr_sim.probeStepX = pr_sim.probeStepY = round( real_sampling_sim_angs, 6) else: pr_sim.probeStepX = pr_sim.probeStepY = probeStep # if you specify cellDimXYZ, you overwrite the values from the xyz file if cellDimXYZ is not None: pr_sim.cellDimX, pr_sim.cellDimX, pr_sim.cellDimX = cellDimXYZ if tileXYZ is not None: pr_sim.tileX, pr_sim.tileY, pr_sim.tileZ = tileXYZ # pr_sim.probeStepX = pr_sim.cellDimX/atom_lattice_data.shape[1] # pr_sim.probeStepY = pr_sim.cellDimY/atom_lattice_data.shape[0] pr_sim.detectorAngleStep = detectorAngleStep pr_sim.save2DOutput = True pr_sim.save3DOutput = False pr_sim.E0 = E0 pr_sim.integrationAngleMin = integrationAngleMin pr_sim.integrationAngleMax = integrationAngleMax pr_sim.interpolationFactorX = pr_sim.interpolationFactorY = \ interpolationFactor pr_sim.realspacePixelSizeX = pr_sim.realspacePixelSizeY = \ realspacePixelSize pr_sim.numFP = numFP pr_sim.probeSemiangle = probeSemiangle pr_sim.alphaBeamMax = alphaBeamMax # in rads pr_sim.scanWindowXMin = pr_sim.scanWindowYMin = scanWindowMin pr_sim.scanWindowYMax = pr_sim.scanWindowXMax = scanWindowMax pr_sim.algorithm = algorithm pr_sim.numThreads = numThreads pr_sim.filenameOutput = filename + '.mrc' pr_sim.go()
def run_sim(submit_path, root_path, xyz, pixelSize, conv_semiangle, def_val, step_size): ''' generates a meta parametre and runs a pyprismatic simulation Parameters _____________ submit_path: str full path of the cluster script submit directory root_path: str full path of the directory where the sims are being saved xyz: str full path of the xyz coordination file pixelSize: float pixel size in (m) in real space conv_semiangle: float probe convergence semi angle in (rad) def_val: float defocus value in (m) ste_size: float probe step size in (m) Returns _____________ ''' meta = pr.Metadata(filenameAtoms=xyz) meta.algorithm = 'multislice' meta.filenameOutput = make_output_filename(root_path, xyz, conv_semiangle, def_val, step_size) sim_file_path = make_output_filename(root_path, xyz, conv_semiangle, def_val, step_size) # meta.writeParameters(param_filename(xyz, conv_semiangle, def_val)) meta.numThreads = 12 pixelSize = float(pixelSize) meta.realspacePixelSizeX = pixelSize * 1e10 meta.realspacePixelSizeY = pixelSize * 1e10 meta.potBound = 2 meta.numFP = 8 meta.sliceThickness = 8 # may change this #meta.numSlices = 1 #meta.zStart = 0 meta.E0 = 80 meta.alphaBeamMax = 45 meta.batchSizeCPU = 1 meta.probeStepX = step_size * 1e10 meta.probeStepY = step_size * 1e10 cell_dims = get_cell_dims(xyz) meta.cellDimX = cell_dims[0] meta.cellDimY = cell_dims[1] meta.cellDimZ = cell_dims[2] #TODO: make this an input param! meta.tileX = 2 meta.tileY = 2 meta.tileZ = 1 meta.probeDefocus = def_val * 1e10 meta.C3 = 0 meta.C5 = 0 meta.probeSemiangle = conv_semiangle * 1e3 meta.detectorAngleStep = 1 meta.probeXtilt = 0 meta.probeYtilt = 0 meta.scanWindowXMin = 0.33 meta.scanWindowXMax = 0.63 meta.scanWindowYMin = 0.33 meta.scanWindowYMax = 0.63 #meta.scanWindowXMin_r = 0 #meta.scanWindowXMax_r = 0 #meta.scanWindowYMin_r = 0 #meta.scanWindowYMax_r = 0 meta.randomSeed = 25212 meta.includeThermalEffects = 1 meta.save2DOutput = 0 meta.save3DOutput = 0 meta.save4DOutput = 1 meta.nyquistSampling = 0 meta.saveDPC_CoM = 1 meta.savePotentialSlices = 1 meta.alsoDoCPUWork = 1 meta.batchSizeGPU = 1 meta.numGPUs = 2 meta.numStreamsPerGPU = 3 meta.go() copy_scratch_file(submit_path, root_path, xyz, conv_semiangle, def_val, step_size) return sim_file_path