# Path: pymicro/xray/xray_utils.py
# def f_atom(q, Z):
#     """Empirical function for the atomic form factor f.
# 
#     This function implements the empirical function from the paper of Muhammad and Lee
#     to provide value of f for elements in the range Z <= 30.
#     doi:10.1371/journal.pone.0069608.t001
# 
#     :param float q: value or series for the momentum transfer, unit is angstrom^-1
#     :param int Z: atomic number, must be lower than 30.
#     :return: the atomic form factor value or series corresponding to q.
#     """
#     if Z > 30:
#         raise ValueError('only atoms with Z<=30 are supported, consider using tabulated data.')
#     a0 = 0.52978  # angstrom, Bohr radius
#     params = np.genfromtxt(os.path.join(PYMICRO_XRAY_DATA_DIR, 'f_atom_params.txt'), names=True)
#     Z, r, a1, b1, a2, b2, a3, b3, _, _, _ = params[int(Z - 1)]
#     print(Z, r, a1, b1, a2, b2, a3, b3)
#     f = (a1 * Z) ** r / ((a1 * Z) ** r + b1 * (2 * pi * a0 * q) ** r) ** r + \
#         (a2 * Z) ** r / ((2 * a2 * Z) ** r + b2 * (2 * pi * a0 * q) ** 2) ** 2 + \
#         (a3 * Z) ** r / ((2 * a3 * Z) ** 2 + b3 * (2 * pi * a0 * q) ** 2) ** 2
#     return f


import unittest
from pymicro.xray.xray_utils import f_atom

class XrayUtilsTests(unittest.TestCase):

    def test_f_atom(self):
        """Verify the calculation of the atom form factor."""
        for Z in range(1, 30):
            # error is less than 3%

# Path: pymicro/xray/xray_utils.py
# def f_atom(q, Z):
#     """Empirical function for the atomic form factor f.
# 
#     This function implements the empirical function from the paper of Muhammad and Lee
#     to provide value of f for elements in the range Z <= 30.
#     doi:10.1371/journal.pone.0069608.t001
# 
#     :param float q: value or series for the momentum transfer, unit is angstrom^-1
#     :param int Z: atomic number, must be lower than 30.
#     :return: the atomic form factor value or series corresponding to q.
#     """
#     if Z > 30:
#         raise ValueError('only atoms with Z<=30 are supported, consider using tabulated data.')
#     a0 = 0.52978  # angstrom, Bohr radius
#     params = np.genfromtxt(os.path.join(PYMICRO_XRAY_DATA_DIR, 'f_atom_params.txt'), names=True)
#     Z, r, a1, b1, a2, b2, a3, b3, _, _, _ = params[int(Z - 1)]
#     print(Z, r, a1, b1, a2, b2, a3, b3)
#     f = (a1 * Z) ** r / ((a1 * Z) ** r + b1 * (2 * pi * a0 * q) ** r) ** r + \
#         (a2 * Z) ** r / ((2 * a2 * Z) ** r + b2 * (2 * pi * a0 * q) ** 2) ** 2 + \
#         (a3 * Z) ** r / ((2 * a3 * Z) ** 2 + b3 * (2 * pi * a0 * q) ** 2) ** 2
#     return f


# Path: pymicro/xray/tests/test_xray_utils.py
import unittest
from pymicro.xray.xray_utils import f_atom


class XrayUtilsTests(unittest.TestCase):

    def test_f_atom(self):
        """Verify the calculation of the atom form factor."""
        for Z in range(1, 30):
            # error is less than 3%

            self.assertLess(abs(f_atom(0., Z) - Z) / Z, 0.03)