REELS tutorial

Before you begin this tutorial, make sure you have followed these steps:


This first tutorial teaches you to do a Reflection Electron Energy Loss Spectroscopy (REELS) experiment. The idea is simple: a thick and large sample is irradiated with electrons from above. Electrons that are emitted back up from the sample (in the "reflection" direction) reach a detector. We are interested in the energy distribution of these electrons.

Sketch of the setup

Input geometry

A triangle file can be downloaded here. Open it in a text editor and take a look. The exact meaning of these numbers are documented here.

The first two triangles are the sample-vacuum interface at z = 0. They form a square, ranging from -500nm to +500nm in both the x and y directions.

The next two lines represent a detector at z = 10nm. You may notice that material -126, the detector material, is on both sides of this plane. Shouldn't we have vacuum on the bottom side? No, because the simulator only cares about the material you are going towards. So we must put the detector material on the upper side, but it doesn't matter what we put on the bottom side because electrons will never go that way.

The four pairs of lines after that are mirrors, with material -122, representing the "sides" of the box. Again, we must put material -122 on the outside, and it doesn't matter what we put on the inside. The mirrors make sure that electrons which reach the edge of the simulation volume are reflected back into the simulation, so we don't lose them.

Finally, there are also "terminators" (material -127) at z = -10 μm. This is necessary because the "simulation domain" is given by the extent of the geometry. If an electron leaves the simulation domain, it is removed. So if you want to simulate a 10 μm thick sample, you need to put triangles at that depth. The reason why we choose terminators instead of mirrors is that if we put mirrors here, the geometry will look like a 20 μm thick sample with detectors on both sides. Of course, if we want to simulate an infinitely thick sample we must make sure that the bottom plane is never reached by the electrons. But we now say that if the bottom plane is reached for whatever reason, we prefer to kill these electrons.

Input electrons

We will launch a million 1 keV primary electrons from z = 5 nm. This position is nicely between the surface of the sample (at z = 0) and the detectors (at z = 10 nm). A python script to generate such a primary electron file can be downloaded here.

The relevant part of the script looks like this:

import numpy as np

# Parameters:
x = 0         # starting x
y = 0         # starting y
z = 5         # starting z
N = 1000000   # Number of electrons
energy = 1000 # Beam energy, in eV

# Open file
with open('reels.pri', 'wb') as file:
    # Allocate numpy buffer
    buffer = np.empty(N, dtype=electron_dtype)

    # Fill with data
    buffer['x'] = x
    buffer['y'] = y
    buffer['z'] = z
    buffer['dx'] = 0
    buffer['dy'] = 0
    buffer['dz'] = -1
    buffer['E'] = energy
    buffer['px'] = 0
    buffer['py'] = 0

    # Write buffer to file

The interesting part starts at with open('reels.pri', 'wb') as file:. This opens a file, reels.pri, for writing in binary format. The next line of code reserves a buffer that we will fill with the data for our primary electrons. N is the size of the buffer (number of primary electrons); electron_dtype is the data type described here. We then fill the buffer with data, setting the parameters for all N electrons to be the same. The last line writes this buffer to file.

Running the simulator

Now, let us generate the primary electrons and run the simulator:

nebula_gpu reels.tri reels.pri silicon.mat > output.det

If you do not have the GPU version installed, please replace nebula_gpu by nebula_cpu_mt in the last command. After running these commands, should have an output.det file, which contains the detected electrons.

Analyzing the output

To analyze the output, download the analysis script. This script reads the detected electrons, makes a histogram of their energy, and shows this in a plot. You can run it as follows:

python output.det

You should see following energy spectrum:

Resulting energy spectrum