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
Beispiel #2
0
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))
Beispiel #3
0
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()
Beispiel #4
0
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)
Beispiel #8
0
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)