XAS in transmission mode
Instrument configuration
The first step is to choose and prepare a configuration (e.g., fixed source vs. fixed detector) for the measurement. Refer to section Revontuli's configurations.
Monochromator selection
The next step is to select a suitable monochromator crystal. The choice depends on:
- the element of interest (e.g., Fe, Mn, Cu)
- the absorption edge to be probed (e.g., K, LIII)
- the available crystals (typically silicon (Si) or germanium (Ge))
- the Bragg angle limitations: usable range is ~65-90 degrees; below 65° the beam is spread because of the crystal astigmatism; above ~85° there is a risk of collision (tube and detector)
Info
PyMca can be used to find the values of the absorption edges: Navigate to "Tools" → "Elements Info", and choose the desired element to see the information. This information is important for determining the Bragg angle/energy range to be scanned.
A Python script called reflection_finder.py helps to find the proper crystal configuration for the application. To launch the script, open the Anaconda prompt on the measurement PC, navigate to TBA, and run python reflection_finder.py. Make sure you have the dependencies installed (numpy and pandas) in the active conda environment (e.g., conda activate xas_general).
In the script, the user provides the chemical symbol of the element of interest, the absorption edge to be probed, and the crystal material. For example, the input "Fe K Si" corresponds to iron, its K-edge and silicon as a choice for the material of the crystal.
The user can also set the desired energy range in which to measure (e.g., 50-200 corresponds to 50 eV before and 200 eV after the edge). Moreover, the usable Bragg angle range can be given (usually 65-85°). The script will then output a list of crystals and their reflections as seen in the figure below.

The output dataframe shows the crystal planes and their corresponding crystal (orientation) available in the laboratory, sorted by intensity. When α=0, the configuration is symmetric, otherwise it is asymmetric (see section Revontuli's configurations). The energy range requested by the user corresponds to the shown Bragg angle range, "Theta_Min" to "Theta_Max". "Theta" corresponds to the Bragg angle of the absorption edge. For best energy resolution, higher Bragg angles (for the edge position) should be preferred. In such a case, the use of an asymmetric configuration could be useful.
If there are multiple options for crystals, it is best to choose the one providing highest intensity. It is also important to take into account harmonic reflections of the crystal (integer multiples of the fundamental energy, higher order Bragg reflections), as these unwanted peaks in the energy spectrum can saturate the detector or cause other unwanted effects to the measured data. Moreover, in asymmetric configuration, the most benefit is gained from angles α < 10°.
Configuration file
The configuration file (or script), e.g., revontuli_XAS.py is needed for the operation of the system. The following are set in the file:
- Motor channels (controller) and names
- Initialization, movement direction, and soft limits (to avoid hardware collisions) for the motors
- Initialization of the detector
- Asymmetric angle (alpha in degrees)
- Calibration status (True/False) to be used when executing the script: whether to use the offsets for motor positions (from theoretical values) or not
- Geometry definition and calibration equations for motor positions (output from Minipix alignment, see below)
- Monochromator crystal plane (miller indices) to be used
An example configuration file can be found in xxx.
Motor movement and XAS scans are done inside an interactive python session using the configuration file. This session can be started with the following steps:
- Open
Anaconda prompton the measurement PC - Navigate to
D:\Revontuliwith thecdcommand - Activate "borealis" environment:
conda activate borealis - Run
ipython -i revontuli_XAS.py
Note
Whenever you change something in the configuration file, the interactive python session should be restarted: Close it first with the exit command, and then re-run it.
Component status check
Please refer to the scan preparation section.
Sample preparation
Please refer to the sample preparation section.
Experimental workflow
Spectrometer Commands
Please refer to the section Borealis → Commands.
Alignment procedure
The spectrometer is mounted according to the Rowland circle, x and y formulated accordingly in the configuration script (see section Revontuli's configurations). The script calculates theoretical values of the positions but there is some error from manual mounting of the motors, which means that a corrective term must be added to the script.
Alignment with laser:
Note
A proper alignment with the laser is only necessary if something in the system hardware has changed (e.g., physical stage positions; controller lost positions after power was cut). Otherwise a quick alignment check with the laser will suffice.
For full laser alignment, proceed with the following (TO BE UPDATED):
- Remove sample platform from rail (or move away), move detector away (to avoid collisions)
- In the
revontuli_XASfile, setcalibration=Falseand save - Open
Anaconda prompt- Navigate to
D:\Revontuliwith thecdcommand - Activate "borealis" environment:
conda activate borealis - Run
ipython -i revontuli_XAS.py - Set all motors to zero/rest positions:
tubex/y/r/monor.amove(0),monox.amove(500)
- Navigate to
- Check the gauges/scales on the motors/stages themselves; from Huber controller, click on the motor, then "t" in right bottom corner, and choose zero when the hardware and software values match
- Laser used to determine offsets to the gauge zero values
- Put laser in front of source, check that the laser beam hits the crystal in the middle (adjust source y and rot when not); check also that beam reflects back to middle of laser source; when fine, zero the motor values from Huber controller screen
- Check that the alignment is still ok near the wanted Bragg angle, run e.g.
theta.amove(80)(calibration=False); check this also with detector on place - Check soft limits (tube) by choosing theta close to 90 degrees (gradually closer) and set them in
revontuli_XAS.py; usetheta.where()to see motor positions and set minimum values that prevent hitting anything - Exit and restart
revontuli_XAS.pyafter modifications to file
Alignment with the Minipix detector:
The Minipix alignment should be done/checked before each measurement.
- On the measurement PC, navigate to
D:\Revontuliand open therevontuli_XAS.pyfile in a text editor. Set the correct "miller_idx" of the crystal plane (for energy calculation), "calibration=False", "asymmetric angle"; save the file. - Open the
Anaconda prompt, and activate the "borealis" environment:conda activate borealis. - Navigate again to
D:\Revontuliusingcd, and runipython -i .\revontuli_XAS.py. - Move the monochromator crystal to its rest position:
monor.amove(0),monox.amove(500). -
Unmount (or move to the side) the MCA detector and replace it with the Minipix device. Mount the Minipix first on its backplate and then on the "filter holder" (first one from the left). The manual rotation stage can be mounted on the rail carrier as shown in the figure below. Position the right edge of the carrier to ~380 mm on the rail's scale. With the monochromator crystal in its rest position, check that the distance from the Minipix window to the crystal surface is 500 mm (i.e., it sits on the Rowland circle).

-
Open the (physical) Minipix window.
- Turn on X-ray tube fans. Open the
Ux(GUI) program to control the X-ray tube:- Accept the licence terms
- Choose TCP/IP and set the correct IP (found at the bottom of the configuration file), press "Connect"
- On the "Home" tab, set (by clicking "Setpoint" fields) e.g. 20 kV and 0.5 mA for the alignment
- Make sure all the enclosure doors are properly closed
- Press the RED button to turn on X-rays
- Launch the
Pixet(GUI) program. In the right panel, set type to "Frames", "Count" to 1, check "repeat", and press "Start". - Use the terminal command
theta.amove(xx)withxxbeing a Bragg angle in the range to be scanned to set a starting point for the alignment. - In Pixet, check that the beam is in the detector field of view. If not, use
tubey.rmove(xx)andtubex.rmove(xx)with moderate steps to find the beam. If there is still no beam, it might be that it is above or below the Minipix FOV, and vertical adjustment is needed (next step). - Vertically center the beam by manually adjusting the crystal rotation. For this, loosen the small screw on the crystal holder and rotate the crystal in moderate steps/angles around the axis perpendicular to its surface.
-
To start the main alignment, type
%run -i alignment.py(insiderevontuli_XAS.pysession):- Input your Bragg angle working range corresponding to your desired scan range (angle min, angle max), and give an angle step (1 or 2 is ok). The spectrometer will first move to the maximal angle.
- The goal is to find x-axis and y-axis positions where the beam spot is horizontally centered and as narrow as possible.
- The program will start by moving on the x-axis. Input a number in millimeter. For example, to move 5 mm in the positive direction, input
5. - Especially with angles close to 90 degrees, be careful to avoid collisions of the hardware. Make sure the soft limits are set correctly in the configuration file.
- To change the axis from x to y, input
y. - Input
readywhen you are happy with the beam shape. The spectrometer will move to the next angle.
Note
At Bragg angles closer to 90 degrees, the focal spot appears smaller, which makes the alignment by visual inspection slightly more difficult. Thus, it would probably be useful to start the alignment at the lower Bragg angle range.
Info
After the first angle, calculate what total x move and y move you did → should be approximately the same for other angles.
- Repeat the operation until it is finished. The code will give you the correction equations.
- Exit the alignment script (press "Enter" twice, type "exit" and press "Enter").
- Exit the
revontuli_XAS.pysession (runexit). - Put the correction equations given by the alignment program in the
revontuli_XAS.pyor file ("tubex_correction"/"dx" and "tubey_correction"/"dy"), and set also "calibration=True". Save the file. - Launch again
revontuli_XAS.pyin theAnaconda prompt. - Check if the calibration is ok by moving theta to, e.g., start, middle and end of scanning range (for example
theta.amove(75)). - Close Pixet.
- Turn off X-rays (GREEN button in
Ux). - Remove Minipix and reposition the MCA/SDD detector.
Measurement Procedure
A XAS analysis consists of three different measurements:
- Samples measurement
- I0 measurement: the environment of the signal without the element of interest has to be as close as possible as the environment with it. For example, if the sample is in a plastic wrapping, it is better to put the same plastic wrapping while performing I0.
- Metallic foil measurement to calibrate in energy. Choose metal foils with well-defined and well-characterized absorption edges close to the energy range you are interested in.
Once the spectrometer is aligned, the measurements can start:
- Check that you are in the correct conda environment; you can activate it by using the command:
conda activate borealis. - Launch the script
revontuli_XAS.pywithipython -i .\revontuli_XAS.py. - Make sure to have the correction terms for
tubexandtubey, check thatcalibration = True, add the miller index of the plane used in the code:miller_index = (h,k,l), and check the d used in the calculationd_hkl(d ≈ 5.431 for Si and 5.658 for Ge).
Symmetric:asymmetric angle = 0
Asymmetric:asymmetric angle = value in degrees -
Place the sample (metallic foil, sample, I0) in the beam path. For a measurement in transmission mode, it can be fixed on the tube outlet or right in front of the detector on the dedicated holders.

-
Place the SDD detector (if not already in place), and run
ProSpect. -
Check the signal (spectrum, counts) and the dead-time at min and max theta. Dead time should be below 10%, preferably below 5%. Check that the proper reflection is seen. Multiple peaks in the spectrum can be caused, for example, by harmonic reflections and detector pile-up, as well as source anode material/air.
Refer to Experimental optimization for further information.
-
Set kV to around 2x desired edge. This ensures that the maximum of the source's Bremsstrahlung is approximately at the inspected edge's energy. Adjust kV and use filters to minimize peaks caused by harmonics, as well as dead time. Keep the mA setting below 1 mA to preserve the tube lifetime.
- Close ProSpect.
- In the
revontuli_XAS.pysession, runnew_file("experiment number"), andnew_sample("experiment number sample")). -
Start a new scan with the command:
energy.scan(E_min, E_max, steps, integration time per point)To find the proper integration time for a sample, check the count rate before and after the inspected absorption edge. A good guideline to aim is a total of 10k (?) counts after the edge.
To find a proper energy step for the scan, refer to xxx, and aim for ~1/10 (or at least ~1/x) of the...
-
The data are saved in the hdf5 datafile created by starting a scan.
PyMcacan be used to display scans while running. The data (inPyMCA) is not updated automatically during the scan; this has to be done manually. - When the scan has finished, turn off the X-rays from
Ux, change or remove the sample (for I0 scan), close the doors, and put the X-rays back on. Wait for the mA value reach the setpoint before starting a scan. - Repeat until all samples are measured.
Inspecting data with PyMCA (to be improved)
To have a quick look at the acquired data (even during a scan), the PyMCA program can be used.
- Open the scan file (HDF5).
- The HDF5 file structure is shown. Each scan is saved in a dataset (or group?). TODO: add description of items.
- The output of the MCA detector can be inspected by double-clicking "MCA" under "Ketek". Tick the "signal" checkbox to plot each spectrum as a function of the respective scan number. I.e., each vertical line (output of each channel of the detector) of the MCA image represents a spectrum of a single MCA measurement.
- To plot an intensity curve, one can take a ROI (e.g., height of 150 lines) around the main peak. TODO: Add image.
- Another option would be to plot "user_position" (axis, energy or theta), "runtime" (signal), and "OCR" (monitor); logarithmic y axis.
Energy calibration
Online pre-analysis
Below is old documentation to help building above up-to-date documentation
All the software mentioned in this part are detailed in section 1.2 Software glossary.
Preliminary settings
list of items of what to check before started with X-rays.
Mounting to check → be in XAS configuration not XES + tube or detector moving?
Crystal selection
The first step is to select a suitable monochromator crystal. The choice depends on: - the element of interest; - the absorption edge to be probed (e.g., K, L_III), PyMca can be used to find the values of the edges; - the available crystals (typically silicon or germanium material); - the Bragg angle limitations: below 65° the beam is spread because of the crystal astigmatism.
A Python script called reflection_finder helps with this step. The user provides the chemical symbol of the element of interest, the absorption edge and the crystal material, from two available: silicon (Si) or germanium (Ge).
For example, the following input (Fe K Si) corresponds to iron, its K-edge and silicon as a choice for the material of the crystal. The python script would then output a list of crystals and their reflections as seen below. It helps choosing reflections by ordering them based on the energy resolution. Figure 1 shows the results obtained for this example.
!Image
Results obtained with reflection_finder.py for the input "Fe K Si" which corresponds to iron, K-edge and silicon as crystal material.
The data frame shows the planes and their corresponding crystal available in the laboratory, sorted by intensity. When α = 0, the configuration is symmetric, otherwise it is asymmetric (section 1.5Config).
Energy range corresponds to Bragg angle range, theta minimum to theta maximum. Theta is the Bragg angle of the absorption edge.
What to know before choosing a crystal using the code: 1. Element and its desired edge (K, L, M,…). 2. Which crystal elements are available for use (In our case Si and Ge). 3. The energy range in which to measure (example input: 50–200 eV, 50 eV before the edge and 200 eV after the edge). 4. Bragg angle range in which to measure, usually 65–90°.
With these three pieces of information, the code can determine all information needed for the acquisition script.
Experimental parameters
Before starting measurements, the spectrometer configuration should be checked.
The components have to be as follows:
- X-ray tube on the Rowland circle;
- Rotation φ of the crystal at 0°;
💬 XAS measurements can be performed with the tube in a fixed position as well as the detector. Note that the script is referring to tube even if the detector is the one moving. Motor movements are detailed in sections Motors_commands and Pseudo-motors_commands.
💬 Maximum voltage: 22 keV and maximum current: 1 mA. For more information, refer to section 1.4 XR settings.
Experiment
Alignment procedure
The spectrometer has been mounted according to the Rowland circle, x and y formulated accordingly in the MCA script. MCA script calculates theoretical values of the positions but there is some error from manual mounting of the motors which means a corrective term must be implemented to the script.
1 - check with laser.
How to get started:
1. Unmount the detector and replace it with Minipix device. The MiniPix has its own stand.
2. Launch revontuli_XAS.py in the borealis base. Make sure calibration = False.
3. Use terminal commands monor.amove(0) to move crystal to zero position which is at 90° and use command monox.amove(500) to move monochromator to its x-axis rest position.
4. Open the Minipix window, turn on the X-rays and launch Pixet.
5. Launch alignment.py:
- Input your Bragg angle working range (angle min, angle max). The spectrometer will move to the minimal angle.
- Find x-axis and y-axis positions where the spot is centered and round.
It will start by moving on the x-axis, for that input number in millimeter. For example, to move 5 mm, input "5".
If the beam movement on the y-axis doesn’t correspond to horizontal movement, flip the 2D image in Pixet.
- To change the axis from x to y, input "y". The beam spot on Pixet has to be the most circular and concentrated.
- When the beam is as narrow as possible and centered, input ready. The spectrometer will move to the next angle.
- Repeat the operation until it is finished. The code will give you the correction equations and plot the corresponding curves.
- Put the correction equations in revontuli_XAS.py or in revontuli_asymmetric_XAS.py, exit and relaunch the script.
To do the alignment manually:
- Start by moving to an angle.
- Move the tube in x- and y-directions until the spot is in the center and round. If the beam movement on the y-axis doesn’t correspond to horizontal movement, flip the 2D image in Pixet.
- Find out where in x-axis and y-axis the tube is located.
- Input the position to excel sheet.
Spectrometer Commands
All the spectrometer commands are detailed in appendix Motors_commands and Pseudo-motors_commands. Here is a list of useful ones for the alignment procedure:
theta.amove(Bragg angle in degree)moves the tube and monochromator(crystal) to the given Bragg angletubex.rmove(x-axis(mm))moves relatively the x-ray tubes motors on the x-axistubey.rmove(y-axis(mm))moves relatively the x-ray tubes motors on the y-axistubex.where()tells you what the position is on the x-axistubey.where()tells you what the position is on the y-axis
💬 Note: motors called tubex and tubey can refer to the tube movement or detector movement depending on the spectrometer mounting.
💬 After any modifications in a script, do not forget to exit and relaunch it.
Measurement Procedure
To perform an XAS analysis, three types of measurement have to be performed:
(a) Samples measurement
(b) I₀ measurement: the environment of the signal without the element of interest has to be as close as possible as the environment with it.
For example, if the sample is in a plastic wrapping, it is better to put the same plastic wrapping while performing I₀.
Spectrometer Commands
All the spectrometer commands are detailed in appendix Motors_commands and Pseudo-motors_commands. Here is a list of useful ones for the alignment procedure:
theta.amove(Bragg angle in degree)moves the tube and monochromator(crystal) to the given Bragg angletubex.rmove(x-axis(mm))moves relatively the x-ray tubes motors on the x-axistubey.rmove(y-axis(mm))moves relatively the x-ray tubes motors on the y-axistubex.where()tells you what the position is on the x-axistubey.where()tells you what the position is on the y-axis
💬 Note: motors called tubex and tubey can refer to the tube movement or detector movement depending on the spectrometer mounting.
💬 After any modifications in a script, do not forget to exit and relaunch it.
Measurement Procedure
To perform an XAS analysis, three types of measurement have to be performed:
(a) Samples measurement
(b) I₀ measurement: the environment of the signal without the element of interest has to be as close as possible as the environment with it.
For example, if the sample is in a plastic wrapping, it is better to put the same plastic wrapping while performing I₀.
(c) Metallic foil measurement to calibrate in energy. Choose metal foils with well-defined and well-characterized absorption edges close to the energy range you are interested in.
Once the spectrometer is aligned, measurements can start:
1. Check that you are in the correct base, you can activate it by using the command: conda activate borealis.
2. Launch the script revontuli_XAS.py.
3. Make sure to have the correction terms for tubex and tubey, check that calibration = True, add the miller index of the plane used in the code: miller_index = h k l and check the d used in the calculation d_hkl (d ≈ 5.431 for Si and 5.658 for Ge).
Symmetric: asymmetric angle = 0
Asymmetric: asymmetric angle = value in degree
4. Place the sample on the beam path (metallic foil, sample, I₀). For a measurement in transmission mode, it can be fixed on the tube outlet or right in front of the detector using tape.
Check the signal and the dead-time on Prospect, it should not be above 10. Chapter 3 Exp optimization discusses experimental optimization and problem-solving using software and auxiliary components.
5. Before starting a new scan, a file has to be created.
6. Start a new scan with the command: energy.scan(E_min, E_max, steps, integration time per point)
7. The data are saved in the datafile created by starting a scan. PyMca can be used to display scans while running. The data is not updated automatically during the scan; this has to be done manually.
💬 To calibrate in energy the spectrometer, it is possible to use a metallic foil of the element of interest, an element with a similar energy or using harmonics. It will depend on the experimental conditions.
💬 To organize data, it is possible to name samples via the command: COMMAND.
While running, scan checking: I₀ decreasing...