Calibration of a diffraction setup using Jupyter
notebooks¶
This notebook presents a very simple GUI for doing the calibration of diffraction setup within the Jupyter environment with Matplotlib
and Ipywidgets
.
Despite this is in the cookbook
section, this tutorial requires advanced Python programming knowledge and some good understanding of PyFAI
.
The basic idea is to port, more or less directly, the pyFAI-calib
interface which was done with matplotlib into the Jupyter notebook.
The PeakPicker class has been addapted and this notebook presents mainly its usage.
Most credits go Philipp Hans for the adaptation of the origin PeakPicker class to Jupyter.
[1]:
%matplotlib nbagg
import pyFAI
import logging
import pyFAI.test.utilstest
import fabio
from matplotlib.pyplot import subplots
from ipywidgets import *
from pyFAI.gui import jupyter
from pyFAI.gui.jupyter.peak_picker import PeakPicker
from pyFAI.geometryRefinement import GeometryRefinement
logging.basicConfig(level=logging.INFO)
print(f"PyFAI version {pyFAI.version}")
WARNING:pyFAI.gui.matplotlib:matplotlib already loaded, setting its backend may not work
PyFAI version 0.21.0-dev0
[2]:
# Some parameters like the wavelength, the calibrant and the diffraction image (downloaded from internet)
wavelength = 1e-10
pilatus = pyFAI.detector_factory("Pilatus1M")
AgBh = pyFAI.calibrant.CALIBRANT_FACTORY("AgBh")
AgBh.wavelength = wavelength
img = pyFAI.test.utilstest.UtilsTest.getimage("Pilatus1M.edf")
fimg = fabio.open(img)
image = fimg.data
[3]:
#Simple display of the image:
_ = jupyter.display(image)
[4]:
#PeakPicker is used in the same way as the one in the CLI.
pp = PeakPicker(data=fimg.data, calibrant=AgBh, wavelength=wavelength, detector=pilatus)
pp.gui(log=True)
[5]:
# Display a summary of control points
pp.points
[5]:
ControlPoints instance containing 2 group of point:
AgBh Calibrant with 49 reflections at wavelength 1e-10
Containing 2 groups of points:
# a ring 0: 47 points
# b ring 1: 56 points
[6]:
gr = GeometryRefinement(pp.points.getList(),
detector=pilatus,
calibrant=AgBh,
wavelength=wavelength)
print("Before refinement: parameters are guessed from the ellipse fitting")
print(gr)
print(f"Cost={gr.chi2()}")
Before refinement: parameters are guessed from the ellipse fitting
Detector Pilatus 1M PixelSize= 1.720e-04, 1.720e-04 m
Wavelength= 1.000000e-10m
SampleDetDist= 1.626147e+00m PONI= 2.708786e-02, 3.348170e-02m rot1=0.001543 rot2= 0.011011 rot3= 0.000000 rad
DirectBeamDist= 1626.248mm Center: x=180.074, y=261.592 pix Tilt=0.637 deg tiltPlanRotation= 97.976 deg
Cost=9.887803776029084e-06
[7]:
# Reset the detector to be normal to the incident beam
gr.rot1=0
gr.rot2=0
gr.rot3=0
print(gr)
print(f"Cost={gr.chi2()}")
Detector Pilatus 1M PixelSize= 1.720e-04, 1.720e-04 m
Wavelength= 1.000000e-10m
SampleDetDist= 1.626147e+00m PONI= 2.708786e-02, 3.348170e-02m rot1=0.000000 rot2= 0.000000 rot3= 0.000000 rad
DirectBeamDist= 1626.147mm Center: x=194.661, y=157.488 pix Tilt=0.000 deg tiltPlanRotation= 0.000 deg
Cost=0.00880358236262962
[8]:
# Geometry refinement with some constrains
gr.refine3(fix=["wavelength", "rot1", "rot2", "rot3"])
print(gr)
print(f"Cost={gr.chi2()}")
Detector Pilatus 1M PixelSize= 1.720e-04, 1.720e-04 m
Wavelength= 1.000000e-10m
SampleDetDist= 1.634709e+00m PONI= 4.543052e-02, 3.095243e-02m rot1=0.000000 rot2= 0.000000 rot3= 0.000000 rad
DirectBeamDist= 1634.709mm Center: x=179.956, y=264.131 pix Tilt=0.000 deg tiltPlanRotation= 0.000 deg
Cost=9.301553574504124e-08
[9]:
# Validate the calibration by overlaying the ring position in Figure #2
pp.contour(gr.array_from_unit(scale=False))
Visually check that the overlaid dashed curve on the Debye-Sherrer rings of the image
Check also for correct indexing of rings
[10]:
gr.save("jupyter.poni")
gr.get_config()
[10]:
OrderedDict([('poni_version', 2),
('detector', 'Pilatus1M'),
('detector_config', OrderedDict()),
('dist', 1.6347089410819242),
('poni1', 0.04543052458127472),
('poni2', 0.030952434520236285),
('rot1', 0.0),
('rot2', 0.0),
('rot3', 0.0),
('wavelength', 1e-10)])
[11]:
ai = pyFAI.load(gr)
ai
[11]:
Detector Pilatus 1M PixelSize= 1.720e-04, 1.720e-04 m
Wavelength= 1.000000e-10m
SampleDetDist= 1.634709e+00m PONI= 4.543052e-02, 3.095243e-02m rot1=0.000000 rot2= 0.000000 rot3= 0.000000 rad
DirectBeamDist= 1634.709mm Center: x=179.956, y=264.131 pix Tilt=0.000 deg tiltPlanRotation= 0.000 deg
Conclusion¶
This short notebook shows how to interact with a calibration image to pick some control-point from the Debye-Scherrer ring and to perform the calibration of the experimental setup.