Creation of a new calibrant#

In this tutorial we will see how to create a new calibrant. For this example we will use one of the calibrants sold by the NIST: Chromium oxide.

The cell parameters are defined in this document: http://www.cristallografia.org/uploaded/614.pdf

The first step is to record the cell parameters and provide them to pyFAI to define the cell.

import pyFAI
from pyFAI.crystallography.cell import Cell, canonical_hkl

print("pyFAI version",pyFAI.version)
pyFAI version 2026.6.0-dev0
# Define a given calibrant:
crox = Cell.hexagonal(4.958979, 13.59592)

Chromium oxide has a crystal structure of Corundum which is R-3c (space group 167). The selection rules are rather complicated and are available in: http://img.chem.ucl.ac.uk/sgp/large/167bz2.gif

We will setup a function corresponding to the selection rules. It returns True if the reflection is active and False otherwise.

def reflection_condition_167(h,k,l):
    """from http://img.chem.ucl.ac.uk/sgp/large/167bz2.htm"""
    if h == 0 and k == 0:
        # 00l: 6n
        return l%6 == 0
    elif h == 0 and l == 0:
        # 0k0: k=3n
        return k%3 == 0
    elif k == 0 and l == 0:
        # h00: h=3n
        return h%3 == 0
    elif h == k:
        # hhl: l=3n
        return l%3 == 0
    elif l == 0:
        # hk0: h-k = 3n
        return (h-3)%3 == 0
    elif k == 0:
        # h0l: l=2n h-l = 3n
        return (l%2 == 0) and ((h - l)%3 == 0)
    elif h == 0:
        # 0kl: l=2n h+l = 3n
        return (l%2 == 0) and ((k + l)%3 == 0)
    else:
        # -h + k + l = 3n
        return (-h + k + l) % 3 == 0
# Use the actual selection rule, not the short version:
#cro.selection_rules.append(lambda h, k, l: ((-h + k + l) % 3 == 0))
crox.selection_rules.append(reflection_condition_167)
for dspacing, reflexions in crox.calculate_dspacing(1).items():
    print(dspacing, canonical_hkl(reflexions))
1.02378951 (4 0 4)
1.06050522 (0 4 2)
1.09102654 (3 1 5)
1.17323493 (3 1 2)
1.18656342 (1 3 1)
1.12408628 (1 3 4)
1.01538147 (1 3 7)
1.08760849 (2 2 6)
1.19580922 (2 2 3)
1.07031836 (4 -4 -1)
1.19110823 (3 1 0)
1.21025334 (3 0 6)
1.43153393 (3 0 0)
1.04227906 (2 1 10)
1.24551592 (2 1 7)
1.46475151 (2 1 4)
1.61176069 (2 1 1)
1.6232069 (3 -1 0)
1.57882236 (1 2 2)
1.39376261 (1 2 5)
1.17382226 (1 2 8)
1.03909386 (3 -3 9)
1.36505268 (3 -3 3)
1.23974475 (2 2 0)
1.33261591 (2 0 8)
2.04757903 (2 0 2)
1.81538001 (0 2 4)
1.14869756 (0 2 10)
1.03050513 (1 1 12)
1.2900773 (1 1 9)
1.67269102 (1 1 6)
2.17521698 (1 1 3)
1.44043999 (2 -2 7)
2.12101044 (2 -2 1)
1.68520563 (2 -2 -5)
1.07121067 (2 -2 -11)
2.4794895 (1 1 0)
1.29618819 (1 0 10)
2.66523182 (1 0 4)
3.63076001 (0 1 2)
1.58025452 (0 1 8)
1.18777953 (1 -1 11)
2.29739513 (1 -1 5)
4.09515805 (1 -1 -1)
1.76970222 (1 -1 -7)
1.01614322 (1 -1 -13)
1.13299333 (0 0 12)
2.26598667 (0 0 6)
crox.save("Cr2O3", "Eskolaite (R-3c)", dmin=0.1, doi="NIST reference compound SRM 674b")

Conclusion#

This is an advanced tutorial, most users won’t have to define their own calibrant. You can also contact the developers to get your own calibrant integrated into pyFAI which makes things easier for you and other users.