diff --git a/src/pyFAI/integrator/azimuthal.py b/src/pyFAI/integrator/azimuthal.py index fb9772e14..5ff85390d 100644 --- a/src/pyFAI/integrator/azimuthal.py +++ b/src/pyFAI/integrator/azimuthal.py @@ -42,7 +42,7 @@ from .common import Integrator # from ..geometry import Geometry from .. import units -from ..utils import EPS32, deg2rad, crc32 +from ..utils import EPS32, deg2rad, crc32, rad2rad # from ..utils.decorators import deprecated, deprecated_warning from ..containers import Integrate1dResult, Integrate2dResult, SeparateResult, ErrorModel from ..io import DefaultAiWriter, save_integrate_result @@ -718,9 +718,6 @@ def integrate2d_ng(self, data, npt_rad, npt_azim=360, shape = data.shape - if radial_range: - radial_range = tuple([i / pos0_scale for i in radial_range]) - error_model = ErrorModel.parse(error_model) if variance is not None: assert variance.size == data.size @@ -733,10 +730,26 @@ def integrate2d_ng(self, data, npt_rad, npt_azim=360, variance = (numpy.maximum(data, 1.0) + numpy.maximum(dark, 0.0)).astype(numpy.float32) if azimuth_range is not None and azimuth_unit.period: - azimuth_range = tuple(deg2rad(azimuth_range[i], self.chiDiscAtPi) for i in (0, -1)) + if azimuth_unit.name.split("_")[-1] == "deg": + azimuth_range = tuple(deg2rad(azimuth_range[i], self.chiDiscAtPi) for i in (0, -1)) + elif azimuth_unit.name.split("_")[-1] == "rad": + azimuth_range = tuple(rad2rad(azimuth_range[i], self.chiDiscAtPi) for i in (0, -1)) if azimuth_range[1] <= azimuth_range[0]: azimuth_range = (azimuth_range[0], azimuth_range[1] + 2 * pi) self.check_chi_disc(azimuth_range) + elif azimuth_range is not None: + azimuth_range = tuple([i / pos1_scale for i in azimuth_range]) + + if radial_range is not None and radial_unit.period: + if radial_unit.name.split("_")[-1] == "deg": + radial_range = tuple(deg2rad(radial_range[i], self.chiDiscAtPi) for i in (0, -1)) + elif azimuth_unit.name.split("_")[-1] == "rad": + azimuth_range = tuple(rad2rad(azimuth_range[i], self.chiDiscAtPi) for i in (0, -1)) + if radial_range[1] <= radial_range[0]: + radial_range = (radial_range[0], radial_range[1] + 2 * pi) + self.check_chi_disc(radial_range) + elif radial_range is not None: + radial_range = tuple([i / pos0_scale for i in radial_range]) if correctSolidAngle: solidangle = self.solidAngleArray(shape, correctSolidAngle) diff --git a/src/pyFAI/test/test_azimuthal_integrator.py b/src/pyFAI/test/test_azimuthal_integrator.py index 4c174880d..a0ccc049e 100644 --- a/src/pyFAI/test/test_azimuthal_integrator.py +++ b/src/pyFAI/test/test_azimuthal_integrator.py @@ -33,7 +33,7 @@ __contact__ = "Jerome.Kieffer@ESRF.eu" __license__ = "MIT" __copyright__ = "European Synchrotron Radiation Facility, Grenoble, France" -__date__ = "15/01/2025" +__date__ = "29/01/2025" import unittest import os @@ -866,6 +866,54 @@ def test_unweighted(self): except Exception as err: self.fail(f"Unweighted failed for {method} with exception {err}") +# Non-regression tests added for pyFAI version 2025.01 +class TestRadialAzimuthalScale(unittest.TestCase): + @classmethod + def setUpClass(cls): + dist = 0.1 + poni1 = 0.02 + poni2 = 0.02 + detector = detector_factory("Pilatus100k") + wavelength = 1e-10 + cls.data = UtilsTest.get_rng().random(detector.shape) + cls.ai = AzimuthalIntegrator(dist=dist, + poni1=poni1, + poni2=poni2, + wavelength=wavelength, + detector=detector, + ) + + def test_limits_normal_units(self): + qnm = units.to_unit("q_nm^-1") + qA = units.to_unit("q_A^-1") + chideg = units.to_unit("chi_deg") + chirad = units.to_unit("chi_rad") + nm_range = [10,20] + A_range = [1,2] + deg_range = [-30,30] + rad_range = [-1,1] + CONFIGS = [{"unit" : (qnm, chideg), "radial_range" : nm_range, "azimuth_range" : deg_range}, + {"unit" : (chideg, qnm), "radial_range" : deg_range, "azimuth_range" : nm_range}, + {"unit" : (qA, chideg), "radial_range" : A_range, "azimuth_range" : deg_range}, + {"unit" : (chideg, qA), "radial_range" : deg_range, "azimuth_range" : A_range}, + {"unit" : (qA, chirad), "radial_range" : A_range, "azimuth_range" : rad_range}, + {"unit" : (chirad, qA), "radial_range" : rad_range, "azimuth_range" : A_range}, + {"unit" : (qA, chideg), "radial_range" : A_range, "azimuth_range" : deg_range}, + {"unit" : (chideg, qA), "radial_range" : deg_range, "azimuth_range" : A_range}, + ] + atol = 1e-1 + self.ai.chiDiscAtPi = True + for config in CONFIGS: + res = self.ai.integrate2d(data=self.data, npt_azim=360, npt_rad=500, **config) + self.assertAlmostEqual(res.radial.min(), config["radial_range"][0], delta=atol) + self.assertAlmostEqual(res.radial.max(), config["radial_range"][1], delta=atol) + self.assertAlmostEqual(res.azimuthal.min(), config["azimuth_range"][0], delta=atol) + self.assertAlmostEqual(res.azimuthal.max(), config["azimuth_range"][1], delta=atol) + + def test_limits_fiber_units(self): + ## TODO next fiber units PR + ... + def suite(): loader = unittest.defaultTestLoader.loadTestsFromTestCase diff --git a/src/pyFAI/utils/mathutil.py b/src/pyFAI/utils/mathutil.py index e1c00e7e8..cbe1f9ef5 100644 --- a/src/pyFAI/utils/mathutil.py +++ b/src/pyFAI/utils/mathutil.py @@ -69,6 +69,19 @@ def deg2rad(dd, disc=1): rp -= 2.0 return rp * math.pi +def rad2rad(r, disc=1): + """ + Transform radians in the range [-π->π[ or [0->2π[ + + :param r: angle in radians + :return: angle in radians in the selected range + """ + # Set r between (0,2pi) + r = r % (2*math.pi) + if disc: + if r > math.pi: + r = r - 2 * math.pi + return r def expand2d(vect, size2, vertical=True): """