Creation of hydrocerussite calibrant#
In this tutorial we will see how to create a new calibrant. For this example we will use one of the componant of mostpaintings: hydrocerussite.
The cell parameter are definied in this document: http://rruff.geo.arizona.edu/AMS/AMC_text_files/11987_amc.txt
The first step is to record the cell parameters and provide them to pyFAI to define the cell.
[1]:
import pyFAI
print("pyFAI version",pyFAI.version)
pyFAI version 2025.11.0-dev0
[2]:
from pyFAI.calibrant import Cell
hydroc_hex = Cell.hexagonal(5.24656, 23.7023)
#This is an alternative representation, where extinction rules are already definied ... but that's cheating
hydroc_rho = Cell.hexagonal(5.24656, 23.7023, lattice_type="R")
Chromium oxide has a crystal structure de Corrundom which is R-3m (space group 166). The selection rules are rather complicated and are available in: 
We will setup a function corresponding to the selection rules. It returns True if the reflection is active and False otherwise.
[3]:
from pyFAI.crystallography.space_groups import ReflectionCondition
#from http://img.chem.ucl.ac.uk/sgp/large/166bz2.htm
reflection_condition_166 = ReflectionCondition.group166_R3bar_m
import inspect
print(inspect.getsource(reflection_condition_166))
@staticmethod
def group166_R3bar_m(h: int, k: int, l: int) -> bool: # noqa: E741
"""
Space group 166: R3̅m. Trigonal (hexagonal axes), rhombohedral lattice.
Valid reflections must satisfy:
- hkil: -h + k + l = 3n
- hki0 (l = 0): -h + k = 3n
- hh(-2h)l: l = 3n
- h(-h)0l (i = 0, k = -h): h + l = 3n
- 000l (h = k = 0): l = 3n
- h(-h)00 (l = 0, k = -h): h = 3n
Source:
Reflection conditions from ITC (in hkil), adapted to (h, k, l)
using the relation i = -(h + k).
JKC: http://img.chem.ucl.ac.uk/sgp/large/166bz2.htm
validated
"""
if (-h + k + l) % 3 != 0:
return False # hkil
if l == 0:
return (-h + k) % 3 == 0 # hki0
if h == k:
return l % 3 == 0 # hh(-2h)l
if k == -h:
return (h + l) % 3 == 0 # h(-h)0l (i = 0)
if h == 0 and k == 0:
return l % 3 == 0 # 000l
if k == -h and l == 0:
return h % 3 == 0 # h(-h)00
return True
[4]:
# Use the actual selection rule, not the short version:
#cro.selection_rules.append(lambda h, k, l: ((-h + k + l) % 3 == 0))
hydroc_hex.selection_rules.append(reflection_condition_166)
[5]:
reflections = hydroc_hex.calculate_dspacing(1)
d_spacing = list(reflections.keys())
d_spacing.sort(reverse=True)
print("+" + "-"*9 + "+" + "-"*60 + "+")
print("|" + "d-spacing" + "|" + "Miller indices"+ " "*46 + "|")
print("+" + "-"*9 + "+" + "-"*60 + "+")
for d in d_spacing:
print(f"|{d:9f}|{' '.join([str(i) for i in reflections[d]])[:60]:60s}|")
print("+" + "-"*9 + "+" + "-"*60 + "+")
+---------+------------------------------------------------------------+
|d-spacing|Miller indices |
+---------+------------------------------------------------------------+
| 7.900767|(0 0 -3) (0 0 3) |
| 4.462403|(1 -1 -1) (-1 0 -1) (0 1 -1) (0 -1 1) (1 0 1) (-1 1 1) |
| 4.242534|(0 -1 -2) (1 0 -2) (-1 1 -2) (1 -1 2) (-1 0 2) (0 1 2) |
| 3.950383|(0 0 -6) (0 0 6) |
| 3.605663|(1 -1 -4) (-1 0 -4) (0 1 -4) (0 -1 4) (1 0 4) (-1 1 4) |
| 3.280218|(0 -1 -5) (1 0 -5) (-1 1 -5) (1 -1 5) (-1 0 5) (0 1 5) |
| 2.715045|(1 -1 -7) (-1 0 -7) (0 1 -7) (0 -1 7) (1 0 7) (-1 1 7) |
| 2.633589|(0 0 -9) (0 0 9) |
| 2.623280|(1 -2 0) (-1 -1 0) (2 -1 0) (-2 1 0) (1 1 0) (-1 2 0) |
| 2.489635|(1 -2 -3) (-1 -1 -3) (2 -1 -3) (-2 1 -3) (1 1 -3) (-1 2 -3) |
| 2.481778|(0 -1 -8) (1 0 -8) (-1 1 -8) (1 -1 8) (-1 0 8) (0 1 8) |
| 2.261463|(0 -2 -1) (2 0 -1) (-2 2 -1) (2 -2 1) (-2 0 1) (0 2 1) |
| 2.231201|(2 -2 -2) (-2 0 -2) (0 2 -2) (0 -2 2) (2 0 2) (-2 2 2) |
| 2.185329|(1 -2 -6) (-1 -1 -6) (2 -1 -6) (-2 1 -6) (1 1 -6) (-1 2 -6) |
| 2.121267|(0 -2 -4) (2 0 -4) (-2 2 -4) (2 -2 4) (-2 0 4) (0 2 4) |
| 2.101481|(1 -1 -10) (-1 0 -10) (0 1 -10) (0 -1 10) (1 0 10) (-1 1 10)|
| 2.048710|(2 -2 -5) (-2 0 -5) (0 2 -5) (0 -2 5) (2 0 5) (-2 2 5) |
| 1.975192|(0 0 -12) (0 0 12) |
| 1.946919|(0 -1 -11) (1 0 -11) (-1 1 -11) (1 -1 11) (-1 0 11) (0 1 11)|
| 1.886546|(0 -2 -7) (2 0 -7) (-2 2 -7) (2 -2 7) (-2 0 7) (0 2 7) |
| 1.858573|(1 -2 -9) (-1 -1 -9) (2 -1 -9) (-2 1 -9) (1 1 -9) (-1 2 -9) |
| 1.802832|(2 -2 -8) (-2 0 -8) (0 2 -8) (0 -2 8) (2 0 8) (-2 2 8) |
| 1.712850|(2 -3 -1) (3 -2 -1) (-2 -1 -1) (-3 1 -1) (1 2 -1) (-1 3 -1) |
| 1.699588|(1 -3 -2) (-1 -2 -2) (3 -1 -2) (2 1 -2) (-3 2 -2) (-2 3 -2) |
| 1.692104|(1 -1 -13) (-1 0 -13) (0 1 -13) (0 -1 13) (1 0 13) (-1 1 13)|
| 1.649463|(2 -3 -4) (3 -2 -4) (-2 -1 -4) (-3 1 -4) (1 2 -4) (-1 3 -4) |
| 1.640109|(0 -2 -10) (2 0 -10) (-2 2 -10) (2 -2 10) (-2 0 10) (0 2 10)|
| 1.614651|(1 -3 -5) (-1 -2 -5) (3 -1 -5) (2 1 -5) (-3 2 -5) (-2 3 -5) |
| 1.586467|(0 -1 -14) (1 0 -14) (-1 1 -14) (1 -1 14) (-1 0 14) (0 1 14)|
| 1.580153|(0 0 -15) (0 0 15) |
| 1.577918|(1 -2 -12) (-1 -1 -12) (2 -1 -12) (-2 1 -12) (1 1 -12) (-1 2|
| 1.563392|(2 -2 -11) (-2 0 -11) (0 2 -11) (0 -2 11) (2 0 11) (-2 2 11)|
| 1.531610|(2 -3 -7) (3 -2 -7) (-2 -1 -7) (-3 1 -7) (1 2 -7) (-1 3 -7) |
| 1.514551|(0 -3 0) (3 -3 0) (-3 0 0) (3 0 0) (-3 3 0) (0 3 0) |
| 1.487468|(0 -3 -3) (3 -3 -3) (-3 0 -3) (3 0 -3) (-3 3 -3) (0 3 -3) (0|
| 1.485787|(1 -3 -8) (-1 -2 -8) (3 -1 -8) (2 1 -8) (-3 2 -8) (-2 3 -8) |
| 1.421952|(0 -2 -13) (2 0 -13) (-2 2 -13) (2 -2 13) (-2 0 13) (0 2 13)|
| 1.414178|(0 -3 -6) (3 -3 -6) (-3 0 -6) (3 0 -6) (-3 3 -6) (0 3 -6) (0|
| 1.408427|(1 -1 -16) (-1 0 -16) (0 1 -16) (0 -1 16) (1 0 16) (-1 1 16)|
| 1.390676|(2 -3 -10) (3 -2 -10) (-2 -1 -10) (-3 1 -10) (1 2 -10) (-1 3|
| 1.357522|(2 -2 -14) (-2 0 -14) (0 2 -14) (0 -2 14) (2 0 14) (-2 2 14)|
| 1.353560|(1 -2 -15) (-1 -1 -15) (2 -1 -15) (-2 1 -15) (1 1 -15) (-1 2|
| 1.342980|(1 -3 -11) (-1 -2 -11) (3 -1 -11) (2 1 -11) (-3 2 -11) (-2 3|
| 1.332910|(0 -1 -17) (1 0 -17) (-1 1 -17) (1 -1 17) (-1 0 17) (0 1 17)|
| 1.316794|(0 0 -18) (0 0 18) |
| 1.312923|(0 -3 -9) (3 -3 -9) (-3 0 -9) (3 0 -9) (-3 3 -9) (0 3 -9) (0|
| 1.311640|(2 -4 0) (-2 -2 0) (4 -2 0) (-4 2 0) (2 2 0) (-2 4 0) |
| 1.293930|(2 -4 -3) (-2 -2 -3) (4 -2 -3) (-4 2 -3) (2 2 -3) (-2 4 -3) |
| 1.258406|(1 -4 -1) (-1 -3 -1) (4 -1 -1) (3 1 -1) (-4 3 -1) (-3 4 -1) |
| 1.253118|(3 -4 -2) (4 -3 -2) (-3 -1 -2) (-4 1 -2) (1 3 -2) (-1 4 -2) |
| 1.250110|(2 -3 -13) (3 -2 -13) (-2 -1 -13) (-3 1 -13) (1 2 -13) (-1 3|
| 1.244817|(2 -4 -6) (-2 -2 -6) (4 -2 -6) (-4 2 -6) (2 2 -6) (-2 4 -6) |
| 1.240889|(0 -2 -16) (2 0 -16) (-2 2 -16) (2 -2 16) (-2 0 16) (0 2 16)|
| 1.232617|(1 -4 -4) (-1 -3 -4) (4 -1 -4) (3 1 -4) (-4 3 -4) (-3 4 -4) |
| 1.217884|(3 -4 -5) (4 -3 -5) (-3 -1 -5) (-4 1 -5) (1 3 -5) (-1 4 -5) |
| 1.205653|(1 -3 -14) (-1 -2 -14) (3 -1 -14) (2 1 -14) (-3 2 -14) (-2 3|
| 1.202972|(1 -1 -19) (-1 0 -19) (0 1 -19) (0 -1 19) (1 0 19) (-1 1 19)|
| 1.201888|(0 -3 -12) (3 -3 -12) (-3 0 -12) (3 0 -12) (-3 3 -12) (0 3 -|
| 1.188312|(2 -2 -17) (-2 0 -17) (0 2 -17) (0 -2 17) (2 0 17) (-2 2 17)|
| 1.181041|(1 -4 -7) (-1 -3 -7) (4 -1 -7) (3 1 -7) (-4 3 -7) (-3 4 -7) |
| 1.176850|(1 -2 -18) (-1 -1 -18) (2 -1 -18) (-2 1 -18) (1 1 -18) (-1 2|
| 1.174084|(2 -4 -9) (-2 -2 -9) (4 -2 -9) (-4 2 -9) (2 2 -9) (-2 4 -9) |
| 1.159645|(3 -4 -8) (4 -3 -8) (-3 -1 -8) (-4 1 -8) (1 3 -8) (-1 4 -8) |
| 1.146749|(0 -1 -20) (1 0 -20) (-1 1 -20) (1 -1 20) (-1 0 20) (0 1 20)|
| 1.134611|(4 -4 -1) (-4 0 -1) (0 4 -1) (0 -4 1) (4 0 1) (-4 4 1) |
| 1.130731|(0 -4 -2) (4 0 -2) (-4 4 -2) (4 -4 2) (-4 0 2) (0 4 2) |
| 1.128681|(0 0 -21) (0 0 21) |
| 1.121722|(2 -3 -16) (3 -2 -16) (-2 -1 -16) (-3 1 -16) (1 2 -16) (-1 3|
| 1.115601|(4 -4 -4) (-4 0 -4) (0 4 -4) (0 -4 4) (4 0 4) (-4 4 4) |
| 1.112693|(1 -4 -10) (-1 -3 -10) (4 -1 -10) (3 1 -10) (-4 3 -10) (-3 4|
| 1.104643|(0 -4 -5) (4 0 -5) (-4 4 -5) (4 -4 5) (-4 0 5) (0 4 5) |
| 1.093479|(0 -2 -19) (2 0 -19) (-2 2 -19) (2 -2 19) (-2 0 19) (0 2 19)|
| 1.093406|(0 -3 -15) (3 -3 -15) (-3 0 -15) (3 0 -15) (-3 3 -15) (0 3 -|
| 1.092665|(2 -4 -12) (-2 -2 -12) (4 -2 -12) (-4 2 -12) (2 2 -12) (-2 4|
| 1.087806|(3 -4 -11) (4 -3 -11) (-3 -1 -11) (-4 1 -11) (1 3 -11) (-1 4|
| 1.082434|(1 -3 -17) (-1 -2 -17) (3 -1 -17) (2 1 -17) (-3 2 -17) (-2 3|
| 1.076930|(4 -4 -7) (-4 0 -7) (0 4 -7) (0 -4 7) (4 0 7) (-4 4 7) |
| 1.060634|(0 -4 -8) (4 0 -8) (-4 4 -8) (4 -4 8) (-4 0 8) (0 4 8) |
| 1.050740|(2 -2 -20) (-2 0 -20) (0 2 -20) (0 -2 20) (2 0 20) (-2 2 20)|
| 1.048310|(1 -1 -22) (-1 0 -22) (0 1 -22) (0 -1 22) (1 0 22) (-1 1 22)|
| 1.041379|(3 -5 -1) (5 -3 -1) (-3 -2 -1) (-5 2 -1) (2 3 -1) (-2 5 -1) |
| 1.038377|(2 -5 -2) (-2 -3 -2) (5 -2 -2) (3 2 -2) (-5 3 -2) (-3 5 -2) |
| 1.036788|(1 -2 -21) (-1 -1 -21) (2 -1 -21) (-2 1 -21) (1 1 -21) (-1 2|
| 1.036663|(1 -4 -13) (-1 -3 -13) (4 -1 -13) (3 1 -13) (-4 3 -13) (-3 4|
| 1.026622|(3 -5 -4) (5 -3 -4) (-3 -2 -4) (-5 2 -4) (2 3 -4) (-2 5 -4) |
| 1.024355|(4 -4 -10) (-4 0 -10) (0 4 -10) (0 -4 10) (4 0 10) (-4 4 10)|
| 1.018064|(2 -5 -5) (-2 -3 -5) (5 -2 -5) (3 2 -5) (-5 3 -5) (-3 5 -5) |
| 1.010886|(3 -4 -14) (4 -3 -14) (-3 -1 -14) (-4 1 -14) (1 3 -14) (-1 4|
| 1.009305|(2 -3 -19) (3 -2 -19) (-2 -1 -19) (-3 1 -19) (1 2 -19) (-1 3|
| 1.009247|(2 -4 -15) (-2 -2 -15) (4 -2 -15) (-4 2 -15) (2 2 -15) (-2 4|
| 1.005009|(0 -1 -23) (1 0 -23) (-1 1 -23) (1 -1 23) (-1 0 23) (0 1 23)|
| 1.004838|(0 -4 -11) (4 0 -11) (-4 4 -11) (4 -4 11) (-4 0 11) (0 4 11)|
+---------+------------------------------------------------------------+
[6]:
print("Hexagonal vs Rhombohedral:")
print("length is the same: ", len(hydroc_hex.calculate_dspacing(1)) == len(hydroc_rho.calculate_dspacing(1)))
ds_hex=list(hydroc_hex.calculate_dspacing(1).keys())
ds_hex.sort()
ds_rho=list(hydroc_rho.calculate_dspacing(1).keys())
ds_rho.sort()
print("Content is the same:", ds_hex == ds_rho)
Hexagonal vs Rhombohedral:
length is the same: True
Content is the same: True
[7]:
hydroc_rho.save("hydrocerussite", "basic lead carbonate (R-3m)", dmin=1, doi="https://doi.org/10.1107/S0108270102006844")
Conclusion#
This is an advanced tutorial, most user 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.