codexbragg-primitive-cubic-calculated-peak-positions.py
bragg-primitive-cubic-calculated-peak-positions.py
"""Original position strips; Python 3.14, matplotlib 3.10.7, numpy 2.3.5.
Primitive cubic point lattice with one identical scatterer per primitive cell.
Run from _media; no intensity model is specified or plotted.
"""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def peak_positions(a_nm=.400, wavelength_nm=.154):
hkl = np.array([[1, 0, 0], [1, 1, 0], [1, 1, 1], [2, 0, 0]])
s = np.sum(hkl**2, axis=1)
d_nm = a_nm / np.sqrt(s)
argument = wavelength_nm / (2 * d_nm)
if np.any(argument > 1):
raise ValueError("A requested reflection has no real Bragg angle")
return hkl, s, d_nm, 2 * np.degrees(np.arcsin(argument))
def main():
plt.rcParams.update({"font.size": 12, "font.family": "DejaVu Sans"})
hkl, s, d_nm, angles = peak_positions()
fig, ax = plt.subplots(figsize=(10, 5.9), facecolor="white")
fig.subplots_adjust(left=.23, right=.96, top=.73, bottom=.22)
colors = ["#2166ac", "#27877a", "#925aa5", "#c45b10"]
for i, (indices, ss, dd, angle, color) in enumerate(zip(hkl, s, d_nm, angles, colors)):
row = 3 - i
ax.hlines(row, 0, 55, color="#e0e4ea", lw=1.4)
ax.vlines(angle, row - .28, row + .28, color=color, lw=3)
ax.plot(angle, row, "o", color=color, ms=6)
ax.text(angle + 1, row + .15, f"{angle:.3f}°", color=color, fontsize=13)
ax.set_yticks([3, 2, 1, 0],
[f"({''.join(map(str, indices))}) S = {ss}\nd = {dd:.5f} nm"
for indices, ss, dd in zip(hkl, s, d_nm)])
ax.set(xlim=(0, 55), ylim=(-.65, 3.65), xlabel=r"Scattering deflection $2\theta$ (degrees)")
ax.set_xticks(np.arange(0, 56, 5))
ax.grid(axis="x", color="#eef0f4", lw=.7)
ax.tick_params(axis="y", length=0, pad=12)
for side in ("left", "right", "top"):
ax.spines[side].set_visible(False)
fig.text(.5, .94, "Calculated Bragg positions: primitive cubic point lattice",
ha="center", fontsize=16, weight="bold")
fig.text(.5, .865, r"$a=0.400$ nm, $\lambda=0.154$ nm; one identical point scatterer per cell",
ha="center", fontsize=12)
fig.text(.5, .795, r"$S=h^2+k^2+l^2,\quad d_{hkl}=a/\sqrt{S},\quad 2\theta=2\arcsin(\lambda\sqrt{S}/2a)$",
ha="center", fontsize=14)
fig.text(.5, .08, "Each strip marks an angle only. Row positions and marker lengths encode no intensity.",
ha="center", fontsize=12)
fig.text(.5, .035, "Chosen ideal model, not measured data. Other reflections beyond these four are not shown.",
ha="center", fontsize=11, color="#596574")
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), dpi=100, facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()