mirror of https://github.com/silx-kit/pyFAI.git
Merge remote-tracking branch 'upstream/master' into 0.18
This commit is contained in:
commit
e06396e30f
|
@ -34,7 +34,7 @@ __authors__ = ["Jerome Kieffer", "Valentin Valls"]
|
|||
__contact__ = "Jerome.Kieffer@ESRF.eu"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "09/05/2019"
|
||||
__date__ = "16/05/2019"
|
||||
__satus__ = "Production"
|
||||
|
||||
import os
|
||||
|
@ -46,7 +46,6 @@ import fabio
|
|||
|
||||
_logger = logging.getLogger("drawmask")
|
||||
|
||||
import silx
|
||||
import silx.gui.plot
|
||||
from silx.gui import qt
|
||||
import pyFAI.utils
|
||||
|
@ -97,12 +96,7 @@ class MaskImageWidget(AbstractMaskImageWidget):
|
|||
|
||||
self.__plot2D = silx.gui.plot.Plot2D()
|
||||
self.__plot2D.setKeepDataAspectRatio(True)
|
||||
if hasattr(self.__plot2D, "getMaskAction"):
|
||||
# silx 0.5 and later
|
||||
maskAction = self.__plot2D.getMaskAction()
|
||||
else:
|
||||
# silx 0.4 and previous
|
||||
maskAction = self.__plot2D.maskAction
|
||||
maskAction = self.__plot2D.getMaskAction()
|
||||
maskAction.setVisible(False)
|
||||
self.__maskPanel = silx.gui.plot.MaskToolsWidget.MaskToolsWidget(plot=self.__plot2D)
|
||||
try:
|
||||
|
|
|
@ -202,7 +202,7 @@ class Geometry(object):
|
|||
return os.linesep.join(lstTxt)
|
||||
|
||||
def check_chi_disc(self, range):
|
||||
"""Check the position of the \chi discontinuity
|
||||
"""Check the position of the :math:`\\chi` discontinuity
|
||||
|
||||
:param range: range of chi for the integration
|
||||
:return: True if there is a problem
|
||||
|
@ -998,7 +998,7 @@ class Geometry(object):
|
|||
"""
|
||||
Calculate the incidence angle (alpha) for current pixels (P).
|
||||
The poni being the point of normal incidence,
|
||||
it's incidence angle is $\{alpha} = 0$ hence $cos(\{alpha}) = 1$
|
||||
it's incidence angle is :math:`\\{alpha} = 0` hence :math:`cos(\\{alpha}) = 1`.
|
||||
|
||||
:param d1: 1d or 2d set of points in pixel coord
|
||||
:param d2: 1d or 2d set of points in pixel coord
|
||||
|
@ -1051,7 +1051,7 @@ class Geometry(object):
|
|||
.. math::
|
||||
|
||||
dOmega = \\frac{Omega(P)}{Omega(C)}
|
||||
= \\frac{A \cdot cos(a)}{SP^2} \cdot \\frac{SC^2}{A \cdot cos(0)}
|
||||
= \\frac{A \\cdot cos(a)}{SP^2} \\cdot \\frac{SC^2}{A \\cdot cos(0)}
|
||||
= \\frac{3}{cos(a)}
|
||||
= \\frac{SC^3}{SP^3}
|
||||
|
||||
|
|
|
@ -34,19 +34,14 @@ __author__ = "Valentin Valls"
|
|||
__contact__ = "valentin.valls@esrf.fr"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "15/01/2019"
|
||||
__date__ = "16/05/2019"
|
||||
|
||||
import unittest
|
||||
import logging
|
||||
import numpy
|
||||
|
||||
from silx.gui import qt
|
||||
try:
|
||||
from silx.gui.utils import testutils
|
||||
except ImportError:
|
||||
# silx 0.8 and earlly
|
||||
from silx.gui.test import utils as testutils
|
||||
|
||||
from silx.gui.utils import testutils
|
||||
import pyFAI.resources
|
||||
import pyFAI.calibrant
|
||||
import pyFAI.detectors
|
||||
|
|
|
@ -34,15 +34,14 @@ __author__ = "Valentin Valls"
|
|||
__contact__ = "valentin.valls@esrf.fr"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "25/02/2019"
|
||||
__date__ = "16/05/2019"
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import logging
|
||||
|
||||
from silx.gui import qt
|
||||
from ...gui.widgets.WorkerConfigurator import WorkerConfigurator
|
||||
from silx.gui.utils import testutils
|
||||
from pyFAI.test.utilstest import UtilsTest
|
||||
from pyFAI.io import integration_config
|
||||
|
||||
|
@ -50,32 +49,15 @@ from pyFAI.io import integration_config
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestIntegrationDialog(unittest.TestCase):
|
||||
class TestIntegrationDialog(testutils.TestCaseQt):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.app = None
|
||||
if sys.platform.startswith('linux') and not os.environ.get('DISPLAY', ''):
|
||||
# On linux and no DISPLAY available (e.g., ssh without -X)
|
||||
logger.warning('pyFAI.integrate_widget tests disabled (DISPLAY env. variable not set)')
|
||||
cls.app = None
|
||||
elif qt is not None:
|
||||
cls.app = qt.QApplication([])
|
||||
|
||||
super(TestIntegrationDialog, cls).setUpClass()
|
||||
config = {"poni": UtilsTest.getimage("Pilatus1M.poni")}
|
||||
integration_config.normalize(config, inplace=True)
|
||||
cls.base_config = config
|
||||
|
||||
def setUp(self):
|
||||
if qt is None:
|
||||
self.skipTest("Qt is not available")
|
||||
if self.__class__.app is None:
|
||||
self.skipTest("DISPLAY env. is not set")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.app = None
|
||||
|
||||
def test_config_flatdark_v1(self):
|
||||
dico = {"dark_current": "a,b,c",
|
||||
"flat_field": "a,b,d"}
|
||||
|
|
|
@ -34,18 +34,13 @@ __author__ = "Valentin Valls"
|
|||
__contact__ = "valentin.valls@esrf.fr"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "11/04/2019"
|
||||
__date__ = "16/05/2019"
|
||||
|
||||
import unittest
|
||||
import logging
|
||||
import numpy
|
||||
|
||||
try:
|
||||
from silx.gui.utils import testutils
|
||||
except ImportError:
|
||||
# silx 0.8 and earlly
|
||||
from silx.gui.test import utils as testutils
|
||||
|
||||
from silx.gui.utils import testutils
|
||||
from ..model.PeakModel import PeakModel
|
||||
from ..model.ListModel import ListModel
|
||||
from ..model.DataModel import DataModel
|
||||
|
|
|
@ -27,7 +27,7 @@ from __future__ import absolute_import
|
|||
|
||||
__authors__ = ["V. Valls"]
|
||||
__license__ = "MIT"
|
||||
__date__ = "10/05/2019"
|
||||
__date__ = "16/05/2019"
|
||||
|
||||
import logging
|
||||
import numpy
|
||||
|
@ -55,6 +55,7 @@ class CalibrantPreview(qt.QFrame):
|
|||
self.__calibrant = None
|
||||
self.__waveLength = None
|
||||
self.__pixmap = None
|
||||
self.__cachedSize = None
|
||||
self.setMinimumSize(qt.QSize(50, 20))
|
||||
|
||||
def setCalibrant(self, calibrant):
|
||||
|
@ -103,14 +104,14 @@ class CalibrantPreview(qt.QFrame):
|
|||
fileds.append((u"Name", name, None))
|
||||
fileds.append((u"Nb registered rays", calibrant.count_registered_dSpacing(), None))
|
||||
dSpacing = calibrant.get_dSpacing()
|
||||
fileds.append((u"Nb visible rays", len(dSpacing), u"between 0 and π"))
|
||||
fileds.append((u"Nb visible rays", len(dSpacing), u"between 0 and 180°"))
|
||||
if len(dSpacing) > 0:
|
||||
ray = calibrant.get_dSpacing()[0]
|
||||
angle = calibrant.get_2th()[0]
|
||||
fileds.append((u"First visible ray", u"%f (%f rad)" % (ray, angle), None))
|
||||
fileds.append((u"First visible ray", u"%f Å (%f°)" % (ray, numpy.rad2deg(angle)), None))
|
||||
ray = calibrant.get_dSpacing()[-1]
|
||||
angle = calibrant.get_2th()[-1]
|
||||
fileds.append((u"Last visible ray", u"%f (%f rad)" % (ray, angle), None))
|
||||
fileds.append((u"Last visible ray", u"%f Å (%f°)" % (ray, numpy.rad2deg(angle)), None))
|
||||
|
||||
toolTip = []
|
||||
for f in fileds:
|
||||
|
@ -124,31 +125,23 @@ class CalibrantPreview(qt.QFrame):
|
|||
toolTip = u"<html><ul>%s</ul></html>" % toolTip
|
||||
self.setToolTip(toolTip)
|
||||
|
||||
def __getPixmap(self):
|
||||
if self.__pixmap is not None:
|
||||
def __getPixmap(self, size=360):
|
||||
if self.__pixmap is not None and self.__cachedSize == size:
|
||||
return self.__pixmap
|
||||
|
||||
calibrant = self.__getConfiguredCalibrant()
|
||||
if calibrant is None:
|
||||
return None
|
||||
tths = numpy.array(calibrant.get_2th())
|
||||
|
||||
tth_min, tth_max = 0, numpy.pi
|
||||
size = 360
|
||||
agregation = numpy.zeros((1, size))
|
||||
for tth in tths:
|
||||
pos = int((tth - tth_min) / (tth_max - tth_min) * size)
|
||||
if pos < 0:
|
||||
continue
|
||||
if pos >= size:
|
||||
continue
|
||||
agregation[0, pos] += 1
|
||||
|
||||
histo = numpy.histogram(tths, bins=size, range=(tth_min, tth_max))
|
||||
agregation = histo[0].reshape(1, -1)
|
||||
colormap = Colormap(name="reversed gray", vmin=agregation.min(), vmax=agregation.max())
|
||||
rgbImage = colormap.applyToData(agregation)[:, :, :3]
|
||||
qimage = imageutils.convertArrayToQImage(rgbImage)
|
||||
qpixmap = qt.QPixmap.fromImage(qimage)
|
||||
self.__pixmap = qpixmap
|
||||
self.__cachedSize = size
|
||||
return self.__pixmap
|
||||
|
||||
def paintEvent(self, event):
|
||||
|
@ -167,9 +160,9 @@ class CalibrantPreview(qt.QFrame):
|
|||
self)
|
||||
|
||||
# content
|
||||
pixmap = self.__getPixmap()
|
||||
pixmapRect = self.rect().adjusted(self._PIXMAP_OFFSET, self._PIXMAP_OFFSET,
|
||||
-self._PIXMAP_OFFSET, -self._PIXMAP_OFFSET)
|
||||
pixmap = self.__getPixmap(size=pixmapRect.width())
|
||||
if pixmap is not None:
|
||||
painter.drawPixmap(pixmapRect,
|
||||
pixmap,
|
||||
|
|
|
@ -29,14 +29,14 @@
|
|||
|
||||
__authors__ = ["Jérôme Kieffer", "Giannis Ashiotis"]
|
||||
__license__ = "MIT"
|
||||
__date__ = "11/01/2019"
|
||||
__date__ = "16/05/2019"
|
||||
__copyright__ = "2014-2017, ESRF, Grenoble"
|
||||
__contact__ = "jerome.kieffer@esrf.fr"
|
||||
|
||||
import logging
|
||||
from collections import OrderedDict
|
||||
import numpy
|
||||
from . import pyopencl, kernel_workgroup_size
|
||||
from . import pyopencl
|
||||
from ..utils import calc_checksum
|
||||
|
||||
if pyopencl:
|
||||
|
@ -46,6 +46,7 @@ else:
|
|||
|
||||
from . import processing
|
||||
from . import get_x87_volatile_option
|
||||
from . import kernel_workgroup_size
|
||||
EventDescription = processing.EventDescription
|
||||
OpenclProcessing = processing.OpenclProcessing
|
||||
BufferDescription = processing.BufferDescription
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
__authors__ = ["Jérôme Kieffer", "Giannis Ashiotis"]
|
||||
__license__ = "MIT"
|
||||
__date__ = "06/05/2019"
|
||||
__date__ = "16/05/2019"
|
||||
__copyright__ = "2014, ESRF, Grenoble"
|
||||
__contact__ = "jerome.kieffer@esrf.fr"
|
||||
|
||||
|
@ -42,8 +42,7 @@ from . import ocl
|
|||
if ocl is not None:
|
||||
from . import pyopencl, allocate_cl_buffers, release_cl_buffers
|
||||
mf = pyopencl.mem_flags
|
||||
from ..ext.splitBBoxLUT import HistoBBox1d
|
||||
from . import utils
|
||||
from . import concatenate_cl_kernel
|
||||
from ..utils import crc32
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -200,7 +199,7 @@ class OCL_Hist_Pixelsplit(object):
|
|||
:param kernel_file: path tothe
|
||||
"""
|
||||
kernel_file = kernel_file or "ocl_hist_pixelsplit.cl"
|
||||
kernel_src = utils.concatenate_cl_kernel([kernel_file])
|
||||
kernel_src = concatenate_cl_kernel([kernel_file])
|
||||
|
||||
template_options = "-D BINS=%i -D NIMAGE=%i -D WORKGROUP_SIZE=%i -D EPS=%f"
|
||||
compile_options = template_options % (self.bins, self.size, self.BLOCK_SIZE, numpy.finfo(numpy.float32).eps)
|
||||
|
|
|
@ -33,7 +33,7 @@ from __future__ import absolute_import, print_function, division
|
|||
|
||||
__author__ = "Jérôme Kieffer"
|
||||
__license__ = "MIT"
|
||||
__date__ = "15/03/2019"
|
||||
__date__ = "16/05/2019"
|
||||
__copyright__ = "2015-2017, ESRF, Grenoble"
|
||||
__contact__ = "jerome.kieffer@esrf.fr"
|
||||
|
||||
|
@ -42,7 +42,10 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
from collections import OrderedDict
|
||||
import numpy
|
||||
from . import pyopencl, mf, processing
|
||||
from . import pyopencl
|
||||
if pyopencl is None:
|
||||
raise ImportError("pyopencl is not installed")
|
||||
from . import mf, processing
|
||||
EventDescription = processing.EventDescription
|
||||
OpenclProcessing = processing.OpenclProcessing
|
||||
BufferDescription = processing.BufferDescription
|
||||
|
|
|
@ -35,7 +35,7 @@ from __future__ import absolute_import, print_function, division
|
|||
|
||||
__author__ = "Jérôme Kieffer"
|
||||
__license__ = "MIT"
|
||||
__date__ = "11/01/2019"
|
||||
__date__ = "16/05/2019"
|
||||
__copyright__ = "2015, ESRF, Grenoble"
|
||||
__contact__ = "jerome.kieffer@esrf.fr"
|
||||
|
||||
|
@ -44,7 +44,7 @@ import logging
|
|||
logger = logging.getLogger(__name__)
|
||||
from collections import OrderedDict
|
||||
import numpy
|
||||
from . import ocl, release_cl_buffers, kernel_workgroup_size, get_x87_volatile_option
|
||||
from . import ocl
|
||||
if ocl:
|
||||
import pyopencl.array
|
||||
from . import processing
|
||||
|
@ -53,6 +53,7 @@ if ocl:
|
|||
BufferDescription = processing.BufferDescription
|
||||
else:
|
||||
raise ImportError("pyopencl is not installed or no device is available")
|
||||
from. import release_cl_buffers, kernel_workgroup_size, get_x87_volatile_option
|
||||
|
||||
|
||||
class Separator(OpenclProcessing):
|
||||
|
|
|
@ -39,7 +39,7 @@ __author__ = "Jérôme Kieffer"
|
|||
__contact__ = "Jerome.Kieffer@esrf.fr"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "2015-2018 European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "11/12/2018"
|
||||
__date__ = "16/05/2019"
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
@ -226,44 +226,64 @@ class TestBugRegression(unittest.TestCase):
|
|||
hc = 12.398419292004204 # Old reference value
|
||||
self.assertAlmostEqual(hc, units.hc, 6, "hc is correct, got %s" % units.hc)
|
||||
|
||||
def test_bug_808(self):
|
||||
def test_import_all_modules(self):
|
||||
"""Try to import every single module in the package
|
||||
"""
|
||||
import pyFAI
|
||||
# print(pyFAI.__file__)
|
||||
# print(pyFAI.__name__)
|
||||
pyFAI_root = os.path.split(pyFAI.__file__)[0]
|
||||
|
||||
def must_be_skipped(path):
|
||||
path = os.path.relpath(path, pyFAI_root)
|
||||
path = path.replace("\\", "/")
|
||||
elements = path.split("/")
|
||||
if "test" in elements:
|
||||
# Always skip test modules
|
||||
logger.warning("Skip test module %s", path)
|
||||
return True
|
||||
if not UtilsTest.WITH_OPENCL_TEST:
|
||||
if "opencl" in elements:
|
||||
logger.warning("Skip %s. OpenCL tests disabled", path)
|
||||
return True
|
||||
if not UtilsTest.WITH_QT_TEST:
|
||||
if "gui" in elements:
|
||||
logger.warning("Skip %s. Qt tests disabled", path)
|
||||
return True
|
||||
return False
|
||||
|
||||
for root, dirs, files in os.walk(pyFAI_root, topdown=True):
|
||||
for adir in dirs:
|
||||
|
||||
subpackage_path = os.path.join(root, adir, "__init__.py")
|
||||
if must_be_skipped(subpackage_path):
|
||||
continue
|
||||
subpackage = "pyFAI" + subpackage_path[len(pyFAI_root):-12].replace(os.sep, ".")
|
||||
if os.path.isdir(subpackage_path):
|
||||
logger.info("Loading subpackage: %s from %s", subpackage, subpackage_path)
|
||||
sys.modules[subpackage] = load_source(subpackage, subpackage_path)
|
||||
for name in files:
|
||||
if name.endswith(".py"):
|
||||
path = os.path.join(root, name)
|
||||
fqn = "pyFAI" + path[len(pyFAI_root):-3].replace(os.sep, ".")
|
||||
logger.info("Importing %s from %s", fqn, path)
|
||||
try:
|
||||
load_source(fqn, path)
|
||||
except Exception as err:
|
||||
if ((isinstance(err, ImportError) and
|
||||
"No Qt wrapper found" in err.__str__() or
|
||||
"pyopencl is not installed" in err.__str__() or
|
||||
"PySide" in err.__str__()) or
|
||||
(isinstance(err, SystemError) and
|
||||
"Parent module" in err.__str__())):
|
||||
if not name.endswith(".py"):
|
||||
continue
|
||||
path = os.path.join(root, name)
|
||||
if must_be_skipped(path):
|
||||
continue
|
||||
fqn = "pyFAI" + path[len(pyFAI_root):-3].replace(os.sep, ".")
|
||||
logger.info("Importing %s from %s", fqn, path)
|
||||
try:
|
||||
load_source(fqn, path)
|
||||
except Exception as err:
|
||||
if ((isinstance(err, ImportError) and
|
||||
"No Qt wrapper found" in err.__str__() or
|
||||
"pyopencl is not installed" in err.__str__() or
|
||||
"PySide" in err.__str__()) or
|
||||
(isinstance(err, SystemError) and
|
||||
"Parent module" in err.__str__())):
|
||||
|
||||
logger.info("Expected failure importing %s from %s with error: %s",
|
||||
fqn, path, err)
|
||||
else:
|
||||
logger.error("Failed importing %s from %s with error: %s%s: %s",
|
||||
fqn, path, os.linesep,
|
||||
err.__class__.__name__, err)
|
||||
raise err
|
||||
logger.info("Expected failure importing %s from %s with error: %s",
|
||||
fqn, path, err)
|
||||
else:
|
||||
logger.error("Failed importing %s from %s with error: %s%s: %s",
|
||||
fqn, path, os.linesep,
|
||||
err.__class__.__name__, err)
|
||||
raise err
|
||||
|
||||
def test_bug_816(self):
|
||||
"Ensure the chi-disontinuity is properly set"
|
||||
|
|
|
@ -33,7 +33,7 @@ __author__ = "Picca Frédéric-Emmanuel, Jérôme Kieffer",
|
|||
__contact__ = "picca@synchrotron-soleil.fr"
|
||||
__license__ = "MIT+"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "01/03/2019"
|
||||
__date__ = "16/05/2019"
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
|
@ -169,7 +169,7 @@ class TestDetector(unittest.TestCase):
|
|||
if os.path.exists(fname): # already tested with another alias
|
||||
continue
|
||||
det = detector_factory(det_name)
|
||||
logger.info("%s --> nxs", det_name)
|
||||
logger.debug("%s --> nxs", det_name)
|
||||
if (det.pixel1 is None) or (det.shape is None):
|
||||
continue
|
||||
if (det.shape[0] > 1900) or (det.shape[1] > 1900):
|
||||
|
|
|
@ -151,9 +151,10 @@ class TestPreproc(unittest.TestCase):
|
|||
|
||||
@unittest.skipIf(UtilsTest.opencl is False, "User request to skip OpenCL tests")
|
||||
def test_opencl(self):
|
||||
from ..opencl import ocl, preproc as ocl_preproc
|
||||
from ..opencl import ocl
|
||||
if ocl is None:
|
||||
self.skipTest("OpenCL not available")
|
||||
from ..opencl import preproc as ocl_preproc
|
||||
self.one_test(ocl_preproc)
|
||||
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ register_radial_unit("q_A^-1",
|
|||
label=r"Scattering vector $q$ ($\AA^{-1}$)",
|
||||
equation=eq_q,
|
||||
short_name="q",
|
||||
unit_symbol="\AA^{-1}")
|
||||
unit_symbol=r"\AA^{-1}")
|
||||
|
||||
register_radial_unit("d*2_A^-2",
|
||||
center="rd2Array",
|
||||
|
@ -214,7 +214,7 @@ register_radial_unit("d*2_A^-2",
|
|||
label=r"Reciprocal spacing squared $d^{*2}$ ($\AA^{-2}$)",
|
||||
equation=lambda x, y, z, wavelength: (eq_q(x, y, z, wavelength) / (2.0 * numpy.pi)) ** 2,
|
||||
short_name="d^{*2}",
|
||||
unit_symbol="\AA^{-2}")
|
||||
unit_symbol=r"\AA^{-2}")
|
||||
|
||||
register_radial_unit("d*2_nm^-2",
|
||||
center="rd2Array",
|
||||
|
|
|
@ -736,10 +736,7 @@ def is_far_from_group(pt, lst_pts, d2):
|
|||
|
||||
|
||||
def rwp(obt, ref):
|
||||
""" ___________________________
|
||||
Calculate \/ 4 ( obt - ref)²
|
||||
V Sum( --------------- )
|
||||
(obt + ref)²
|
||||
"""Compute :math:`\\sqrt{\\sum \\frac{4\\cdot(obt-ref)^2}{(obt + ref)^2}}`.
|
||||
|
||||
This is done for symmetry reason between obt and ref
|
||||
|
||||
|
|
Loading…
Reference in New Issue