from pymatgen.core import Structure
from pymatgen.analysis.diffraction.xrd import XRDCalculator
from .filereader import load_data
import fabio
import os
import sys
[docs]
def build_calibration_data_from_cif(
cif_file,
wavelength,
n_peaks=15,
two_theta_range=(0, 2)
):
"""
Generate a list of diffraction peaks from a CIF structure file.
Uses pymatgen's XRD calculator to compute the simulated diffraction
pattern, then exports the d-spacings to a text file (``distances.txt``)
for use by pyFAI-calib2.
Parameters
----------
cif_file : str
Path to the CIF structure file.
wavelength : float
Electron (or X-ray) wavelength in Å.
n_peaks : int, optional
Maximum number of peaks to return. Default is 15.
two_theta_range : tuple of float, optional
Angular range in degrees ``(2θ_min, 2θ_max)`` used to filter peaks.
Default is ``(0, 2)``.
Returns
-------
peaks : list of dict
Each element contains:
- ``'hkl'``: Miller indices
- ``'d'``: d-spacing in Å
- ``'two_theta'``: Bragg angle in degrees
- ``'intensity'``: relative intensity
"""
# Lecture de la structure
structure = Structure.from_file(cif_file)
# Calculateur XRD
xrd = XRDCalculator(wavelength=wavelength)
pattern = xrd.get_pattern(structure, two_theta_range=two_theta_range)
peaks = []
for i in range(min(n_peaks, len(pattern.x))):
peaks.append({
"hkl": pattern.hkls[i][0]["hkl"],
"d": pattern.d_hkls[i],
"two_theta": pattern.x[i],
"intensity": pattern.y[i]
})
line2write=''
for p in peaks:
line2write += str(p['d'])+'\n'
with open('./distances.txt','w') as f:
f.write(line2write)
return peaks
[docs]
def get_calibration_parameters(poni_file: str):
"""
Extract calibration parameters from a PONI file generated by pyFAI-calib2.
Parameters
----------
poni_file : str
Path to the PONI file produced after calibration.
Returns
-------
calibration_params : dict
Dictionary containing the following keys (when present in the file):
- ``'distance'``: sample-to-detector distance (m)
- ``'poni1'``, ``'poni2'``: point of normal incidence coordinates (m)
- ``'rot1'``, ``'rot2'``, ``'rot3'``: detector rotation angles (rad)
- ``'wavelength'``: wavelength (m)
- ``'pixel1'``, ``'pixel2'``: pixel sizes (m)
- ``'max_shape'``: detector shape in pixels
"""
import json
calibration_params = {}
if not os.path.exists(poni_file):
raise FileNotFoundError(f"Fichier PONI non trouvé: {poni_file}")
with open(poni_file, 'r') as f:
lines = f.readlines()
for line in lines:
if line.startswith('Distance:'):
calibration_params['distance'] = float(line.split(':')[1].strip())
elif line.startswith('Poni1:'):
calibration_params['poni1'] = float(line.split(':')[1].strip())
elif line.startswith('Poni2:'):
calibration_params['poni2'] = float(line.split(':')[1].strip())
elif line.startswith('Rot1:'):
calibration_params['rot1'] = float(line.split(':')[1].strip())
elif line.startswith('Rot2:'):
calibration_params['rot2'] = float(line.split(':')[1].strip())
elif line.startswith('Rot3:'):
calibration_params['rot3'] = float(line.split(':')[1].strip())
elif line.startswith('Wavelength:'):
calibration_params['wavelength'] = float(line.split(':')[1].strip())
elif line.startswith('Detector_config:'):
config_str = line.split(':', 1)[1].strip()
config = json.loads(config_str)
calibration_params['pixel1'] = config.get('pixel1', None)
calibration_params['pixel2'] = config.get('pixel2', None)
calibration_params['max_shape'] = config.get('max_shape', None)
return calibration_params