Merge remote-tracking branch 'upstream/master' into 0.18

This commit is contained in:
Jerome Kieffer 2019-05-17 08:06:55 +02:00
commit e06396e30f
15 changed files with 90 additions and 109 deletions

View File

@ -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:

View File

@ -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}

View File

@ -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

View File

@ -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"}

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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):

View File

@ -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"

View File

@ -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):

View File

@ -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)

View File

@ -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",

View File

@ -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