def create_system_configuration(device): """ Create an appropriate system configuration Args: device (str): The device to use Returns: object: The system configuration """ assert device in ["cpu", "gpu"] # Initialise the system configuration system_conf = multem.SystemConfiguration() # Set the precision system_conf.precision = "float" # Set the device if device == "gpu": if multem.is_gpu_available(): system_conf.device = "device" else: system_conf.device = "host" warnings.warn("GPU not present, reverting to CPU") else: system_conf.device = "host" # Print some output logger.info("Simulating using %s" % system_conf.device) # Return the system configuration return system_conf
def test_slice(tmpdir_factory): directory = tmpdir_factory.mktemp("proc") filename = os.path.join(directory, "temp.h5") box = (400, 400, 400) centre = (200, 200, 200) shape = {"type": "cube", "cube": {"length": 400}} sample = parakeet.sample.new(filename, box, centre, shape) parakeet.sample.add_single_molecule(sample, "4v5d") # Create the system configuration system_conf = multem.SystemConfiguration() system_conf.precision = "float" if multem.is_gpu_available(): system_conf.device = "device" else: system_conf.device = "host" # Create the input multislice configuration n_phonons = 50 input_multislice = create_input_multislice(n_phonons, False) input_multislice.spec_atoms = sample.get_atoms().to_multem() input_multislice.spec_lx = sample.containing_box[1][0] input_multislice.spec_ly = sample.containing_box[1][1] input_multislice.spec_lz = sample.containing_box[1][2] input_multislice.spec_dz = 3 print("Standard") output = multem.simulate(system_conf, input_multislice) print("Subslicing") # Create the input multislice configuration n_slices = 4 # Slice the sample subslices = list( multem.slice_spec_atoms( input_multislice.spec_atoms, input_multislice.spec_lz, n_slices ) ) # Do the slices simulation sliced_output = multem.simulate(system_conf, input_multislice, iter(subslices)) # Print the difference a = np.abs(np.array(output.data[-1].psi_coh)) ** 2 b = np.abs(np.array(sliced_output.data[-1].psi_coh)) ** 2 diff = np.max(np.abs(a - b))
def test_system_configuration(): system_conf = multem.SystemConfiguration() system_conf.device = "device" system_conf.precision = "precision" system_conf.cpu_ncores = 1 system_conf.cpu_nthread = 1 system_conf.gpu_device = 1 system_conf.gpu_nstream = 1 def check(): assert system_conf.device == "device" assert system_conf.precision == "precision" assert system_conf.cpu_ncores == 1 assert system_conf.cpu_nthread == 1 assert system_conf.gpu_device == 1 assert system_conf.gpu_nstream == 1 check() system_conf = pickle.loads(pickle.dumps(system_conf)) check()
import multem import numpy import pickle from cu001_crystal import cu001_crystal input_multislice = multem.Input() system_conf = multem.SystemConfiguration() system_conf.precision = "float" system_conf.device = "host" # Set simulation experiment input_multislice.simulation_type = "HRTEM" # Electron-Specimen interaction model input_multislice.interaction_model = "Multislice" # Potential slicing input_multislice.potential_slicing = "Planes" # Electron-Phonon interaction model input_multislice.pn_model = "Frozen_Phonon" input_multislice.pn_coh_contrib = 0 input_multislice.pn_single_conf = False input_multislice.pn_nconf = 10 input_multislice.pn_dim = 110 input_multislice.pn_seed = 300183 # Specimen information na = 16 nb = 16
def compute_exit_wave(atom_data, pixel_size): """ Compute the exit wave """ # Get the dimensions x_min = atom_data.data["x"].min() x_max = atom_data.data["x"].max() y_min = atom_data.data["y"].min() y_max = atom_data.data["y"].max() z_min = atom_data.data["z"].min() z_max = atom_data.data["z"].max() x_size = x_max - x_min y_size = y_max - y_min select = ((atom_data.data["x"] > x_min + x_size / 6) & (atom_data.data["x"] < x_max - x_size / 6) & (atom_data.data["y"] > y_min + y_size / 6) & (atom_data.data["y"] < y_max - y_size / 6)) atom_data = parakeet.sample.AtomData(data=atom_data.data[select]) x_min = atom_data.data["x"].min() x_max = atom_data.data["x"].max() y_min = atom_data.data["y"].min() y_max = atom_data.data["y"].max() z_min = atom_data.data["z"].min() z_max = atom_data.data["z"].max() x_size = x_max - x_min y_size = y_max - y_min z_size = z_max - z_min # Translate to centre x_box_size = x_size y_box_size = y_size z_box_size = z_size # Create the system configuration system_conf = multem.SystemConfiguration() system_conf.precision = "float" system_conf.device = "device" # Create the input multislice configuration input_multislice = create_input_multislice() # Compute the number of pixels nx = next_power_2(int(x_box_size / pixel_size)) ny = next_power_2(int(y_box_size / pixel_size)) assert nx <= 4096 assert ny <= 4096 x_box_size = nx * pixel_size y_box_size = ny * pixel_size x_trans = (x_box_size - x_size) / 2.0 - x_min y_trans = (y_box_size - y_size) / 2.0 - y_min z_trans = (z_box_size - z_size) / 2.0 - z_min atom_data.translate((x_trans, y_trans, z_trans)) # Create the specimen size input_multislice.nx = nx input_multislice.ny = ny input_multislice.spec_lx = x_box_size input_multislice.spec_ly = y_box_size input_multislice.spec_lz = z_box_size input_multislice.spec_dz = 5 # Set the specimen atoms input_multislice.spec_atoms = atom_data.to_multem() # Run the simulation output_multislice = multem.simulate(system_conf, input_multislice) # Get the image physical_image = numpy.array(output_multislice.data[0].psi_coh).T # Create the masker masker = multem.Masker(input_multislice.nx, input_multislice.ny, pixel_size) # Create the size of the cuboid masker.set_cuboid( ( x_box_size / 2 - x_size / 2, y_box_size / 2 - y_size / 2, z_box_size / 2 - z_size / 2, ), (x_size, y_size, z_size), ) # Run the simulation input_multislice.spec_atoms = multem.AtomList() output_multislice = multem.simulate(system_conf, input_multislice, masker) # Get the image random_image = numpy.array(output_multislice.data[0].psi_coh).T # Return the images x0 = numpy.array( (x_box_size / 2 - x_size / 2, y_box_size / 2 - y_size / 2)) x1 = numpy.array( (x_box_size / 2 + x_size / 2, y_box_size / 2 + y_size / 2)) return physical_image, random_image, x0, x1
def compute_observed_mean(size, pixel_size): """ Compute the observed mean """ # Create the system configuration system_conf = multem.SystemConfiguration() system_conf.precision = "float" system_conf.device = "device" # Create the input multislice configuration input_multislice = create_input_multislice() # Compute the number of pixels nx = int(ceil(size / pixel_size)) ny = int(ceil(size / pixel_size)) size = nx * pixel_size # Create the specimen atoms input_multislice.nx = nx input_multislice.ny = ny input_multislice.spec_lx = nx * pixel_size input_multislice.spec_ly = ny * pixel_size input_multislice.spec_lz = nx * pixel_size input_multislice.spec_dz = 1 # For N random placements compute the mean intensity means = [] for j in range(10): # Compute the position x0 = numpy.random.uniform(0, 1) + nx // 2 y0 = numpy.random.uniform(0, 1) + ny // 2 x0 = pixel_size * x0 y0 = pixel_size * y0 # Set the atom list input_multislice.spec_atoms = multem.AtomList([ (1, x0, y0, size / 2.0, 0, 1, 0, 0), (1, x0, y0, size / 2.0, 0, 1, 0, 0), (8, x0, y0, size / 2.0, 0, 1, 0, 0), ]) thickness = [] potential = [] def callback(z0, z1, V): V = numpy.array(V) thickness.append(z1 - z0) potential.append(V) # Run the simulation multem.compute_projected_potential(system_conf, input_multislice, callback) # Compute the mean potential V = numpy.sum(potential, axis=0) means.append(numpy.mean(V)) # Return the size and mean potential return size, numpy.mean(means)
def compute(atom_data, pixel_size, thickness): # Get the dimensions x_min = atom_data.data["x"].min() x_max = atom_data.data["x"].max() y_min = atom_data.data["y"].min() y_max = atom_data.data["y"].max() z_min = atom_data.data["z"].min() z_max = atom_data.data["z"].max() x_size = x_max - x_min y_size = y_max - y_min z_size = z_max - z_min # Translate to centre x_box_size = x_size y_box_size = y_size z_box_size = z_size x_trans = (x_box_size - x_size) / 2.0 - x_min y_trans = (y_box_size - y_size) / 2.0 - y_min z_trans = (z_box_size - z_size) / 2.0 - z_min atom_data.translate((x_trans, y_trans, z_trans)) # Trim the atom data z_select_min = z_box_size / 2 - thickness / 2 z_select_max = z_box_size / 2 + thickness / 2 selection = (atom_data.data["z"] > z_select_min) & (atom_data.data["z"] < z_select_max) atom_data = parakeet.sample.AtomData(data=atom_data.data[selection]) num_atoms = len(atom_data.data) # Create the system configuration system_conf = multem.SystemConfiguration() system_conf.precision = "float" system_conf.device = "device" # Create the input multislice configuration input_multislice = create_input_multislice() # Compute the number of pixels nx = int(x_box_size / pixel_size) ny = int(y_box_size / pixel_size) x_box_size = nx * pixel_size y_box_size = ny * pixel_size # Create the specimen size input_multislice.nx = nx input_multislice.ny = ny input_multislice.spec_lx = x_box_size input_multislice.spec_ly = y_box_size input_multislice.spec_lz = z_box_size input_multislice.spec_dz = thickness # Set the specimen atoms input_multislice.spec_atoms = atom_data.to_multem() potential = [] def callback(z0, z1, V): V = numpy.array(V) potential.append(V) # Run the simulation multem.compute_projected_potential(system_conf, input_multislice, callback) # Save the potential potential = numpy.sum(potential, axis=0) filename = "projected_potential_%.1f_%d.npz" % (pixel_size, thickness) numpy.savez(filename, potential=potential, num_atoms=num_atoms)
import multem input_multislice = multem.Input() config = multem.SystemConfiguration() # print(multem.is_gpu_available()) # if not multem.is_gpu_available(): config.device = "host" result = multem.simulate(config, input_multislice) # print(result)