Setting up a diffraction pattern
In this example, we initialize the pattern object via the Pattern class, which enables to handle and prepare diffraction data for the reconstruction.
Loading experimental data
Depending on the facility where the experiment has been perfomed and properties of the acquired data, there are different ways to access the raw data. This step is in charge of the user. To perform a reconstruction, the following information is strictly necessary:
A matrix containing the measured pattern
A matrix indicating the pixels that have to be excluded from the reconstruction (mask)
A list containing the identification numbers of the pattern. For example, if run number is
123
and pulse-id is456789
, the list will be[123,456789]
.The coordinates of the center position of the diffraction pattern
In the folder examples/data
it is possible to find test files that already contain these information. For example:
import numpy as np
data = np.load('data/example_B_1.npz')
for f in data.files:
print(f, data[f].shape)
pattern (1054, 1024)
mask (1054, 1024)
pid (2,)
center (2,)
Initializing the Pattern
The Pattern can be now initialized with the necessary data.
from spring import Pattern
patt = Pattern(pattern=data['pattern'], mask=data['mask'], center=data['center'], pid=data['pid'], satvalue=3e4)
The satvalue
option indicate at which value the pixels have to be considered saturated, such that they are also excluded from the reconstruction (along with those where mask==1
).
Note
In priciple, saturated pixels can be included directly in the mask array. It is however reccomended to use thesatvalue
option, as those pixels are treated differently when the optionbounds
in the settings is set to a value greater than 0
The prepared pattern can be inspected via the get method, which returns the prepared numpy array. Data is prepared as a square matrix. If no further option is given when the object is defined, the prepared matrix has dimensions equal to the maximum of the two dimensions of the original pattern. Missing data in the other dimension is padded with zero values
print(patt.get().shape)
(1054, 1054)
The prepared pattern can be visually inspected by plotting the array given by get. In the prepared pattern, masked pixels have value -1, while saturated pixels are set to -2.
# Manual plot
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
plt.imshow(patt.get(), norm=LogNorm(vmin=10))
plt.show()
![../_images/2fa06e0477bf8bcd695fa83c0239771eb79f445b470936620d1cd0f9b5759dfc.png](../_images/2fa06e0477bf8bcd695fa83c0239771eb79f445b470936620d1cd0f9b5759dfc.png)
It is also possible to make use of a helper method, plot() ,which performs directly the plotting via matplotlib. In addition, it places as a title the information contained in the pid
.
A further helper method plot_mask() reports the masked and saturated pixels.
# Plot using helper method
patt.plot()
patt.plot_mask()
![../_images/d0351f71966fb82a5c4bd112eaf0047d8b3391cfcd512cbd0d6a52a814a1a8bb.png](../_images/d0351f71966fb82a5c4bd112eaf0047d8b3391cfcd512cbd0d6a52a814a1a8bb.png)
![../_images/be66ffe571635468124131e27ad8fcfa8598a4f65da0d24dd45d23cabd00a9c3.png](../_images/be66ffe571635468124131e27ad8fcfa8598a4f65da0d24dd45d23cabd00a9c3.png)
It is additionally possible to manually indicate at which size the crop operation is exectuted, by setting the cropsize
parameter:
Pattern(pattern=data['pattern'], mask=data['mask'], center=data['center'], pid=data['pid'], satvalue=3e4, cropsize=1200).plot()
Pattern(pattern=data['pattern'], mask=data['mask'], center=data['center'], pid=data['pid'], satvalue=3e4, cropsize=1024).plot()
Pattern(pattern=data['pattern'], mask=data['mask'], center=data['center'], pid=data['pid'], satvalue=3e4, cropsize=600).plot()
![../_images/ad248e05a9c27d8a558492c04da09741d583fbc03f0a4d0c277318993af90436.png](../_images/ad248e05a9c27d8a558492c04da09741d583fbc03f0a4d0c277318993af90436.png)
![../_images/d0351f71966fb82a5c4bd112eaf0047d8b3391cfcd512cbd0d6a52a814a1a8bb.png](../_images/d0351f71966fb82a5c4bd112eaf0047d8b3391cfcd512cbd0d6a52a814a1a8bb.png)
![../_images/58af63348f0c1d86cd4bdeb722fc5a2d2c9e73c4d849f03fc1118b6afd4b96dd.png](../_images/58af63348f0c1d86cd4bdeb722fc5a2d2c9e73c4d849f03fc1118b6afd4b96dd.png)
Similarly, the diffraction pattern can be rescaled or binned via the size
option, to set the final pattern size:
Pattern(pattern=data['pattern'], mask=data['mask'], center=data['center'], pid=data['pid'], satvalue=3e4, cropsize=1024, size=512).plot()
Pattern(pattern=data['pattern'], mask=data['mask'], center=data['center'], pid=data['pid'], satvalue=3e4, cropsize=1024, size=128).plot()
![../_images/4ff299a9f3d9af08cf2f2b2dc6f6870f7d7653ce8ac9f2a617ee53cb053436db.png](../_images/4ff299a9f3d9af08cf2f2b2dc6f6870f7d7653ce8ac9f2a617ee53cb053436db.png)
![../_images/deb17ca43f0e22184e14bafc41d9d97a3a6ef6e793f558d15935bad4452f28f6.png](../_images/deb17ca43f0e22184e14bafc41d9d97a3a6ef6e793f558d15935bad4452f28f6.png)
Identifying the center
The imaging process requires the zero-frequency peak to be in the center of the pattern matrix. As the central data of a pattern is missing, the identification of the center position is done by looking at the symmetries in the diffraction pattern.
To help the user in identifying the correct center, it is possible to provide the circles
argument to the plot funcion. In this case, the indicated number of concentric circles are superimposed on the pattern image to guide the eye towards the identification of the correct coordinates of the pattern’s center
patt = Pattern(pattern=data['pattern'],
mask=data['mask'],
center=data['center'],
pid=data['pid'],
satvalue=3e4, cropsize=1024)
patt.plot(circles=4)
patt.plot(circles=4, cropsize=256)
![../_images/f186f0cbae05320cc4f9416d0b15301c9925f33f4d268c3784b30c278abe9601.png](../_images/f186f0cbae05320cc4f9416d0b15301c9925f33f4d268c3784b30c278abe9601.png)
![../_images/4e27e1b8a636e2cfe3f7b8501ce0c806239325004e3ae764b4d761b82ebd9e48.png](../_images/4e27e1b8a636e2cfe3f7b8501ce0c806239325004e3ae764b4d761b82ebd9e48.png)
patt_offcenter = Pattern(pattern=data['pattern'],
mask=data['mask'],
center=data['center'] + np.array([7, -5]),
pid=data['pid'],
satvalue=3e4, cropsize=1024)
patt_offcenter.plot(circles=4, cropsize=256)
![../_images/e397700706523bf063d52452c59a212634996b88e4149806f7b09f2450a904c1.png](../_images/e397700706523bf063d52452c59a212634996b88e4149806f7b09f2450a904c1.png)