mirror of https://github.com/silx-kit/pyFAI.git
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
3ca98bf762
76
README.rst
76
README.rst
|
@ -3,7 +3,7 @@ pyFAI: Fast Azimuthal Integration in Python
|
|||
|
||||
Main development website: https://github.com/silx-kit/pyFAI
|
||||
|
||||
|Build Status| |Appveyor Status|
|
||||
|Build Status| |Appveyor Status| |myBinder Launcher|
|
||||
|
||||
pyFAI is an azimuthal integration library that tries to be fast (as fast as C
|
||||
and even more using OpenCL and GPU).
|
||||
|
@ -122,15 +122,15 @@ Python 2.7, 3.4, 3.5, 3.6 and 3.7 are well tested.
|
|||
Python 2.6, 3.2 and 3.3 are no more supported since pyFAI 0.12
|
||||
For full functionality of pyFAI the following modules need to be installed.
|
||||
|
||||
* numpy - http://www.numpy.org
|
||||
* scipy - http://www.scipy.org
|
||||
* matplotlib - http://matplotlib.sourceforge.net/
|
||||
* fabio - http://sourceforge.net/projects/fable/files/fabio/
|
||||
* h5py - http://www.h5py.org/
|
||||
* pyopencl - http://mathema.tician.de/software/pyopencl/
|
||||
* python-pyqt5 - http://www.riverbankcomputing.co.uk/software/pyqt/intro
|
||||
* silx - http://www.silx.org
|
||||
* numexpr - https://github.com/pydata/numexpr
|
||||
* ``numpy`` - http://www.numpy.org
|
||||
* ``scipy`` - http://www.scipy.org
|
||||
* ``matplotlib`` - http://matplotlib.sourceforge.net/
|
||||
* ``fabio`` - http://sourceforge.net/projects/fable/files/fabio/
|
||||
* ``h5py`` - http://www.h5py.org/
|
||||
* ``pyopencl`` - http://mathema.tician.de/software/pyopencl/
|
||||
* ``pyqt5`` - http://www.riverbankcomputing.co.uk/software/pyqt/intro
|
||||
* ``silx`` - http://www.silx.org
|
||||
* ``numexpr`` - https://github.com/pydata/numexpr
|
||||
|
||||
Those dependencies can simply be installed by::
|
||||
|
||||
|
@ -149,15 +149,15 @@ or using apt-get on from the command line in a terminal::
|
|||
|
||||
The extra Ubuntu packages needed are:
|
||||
|
||||
* python-numpy
|
||||
* python-scipy
|
||||
* python-matplotlib
|
||||
* python-dev
|
||||
* python-fabio
|
||||
* python-pyopencl
|
||||
* python-pyqt5
|
||||
* python-silx
|
||||
* python-numexpr
|
||||
* ``python-numpy``
|
||||
* ``python-scipy``
|
||||
* ``python-matplotlib``
|
||||
* ``python-dev``
|
||||
* ``python-fabio``
|
||||
* ``python-pyopencl``
|
||||
* ``python-pyqt5``
|
||||
* ``python-silx``
|
||||
* ``python-numexpr``
|
||||
|
||||
and the same with python3
|
||||
using apt-get these can be installed as::
|
||||
|
@ -203,34 +203,36 @@ One needs to subscribe by sending an email to sympa@esrf.fr with a subject "subs
|
|||
Maintainers
|
||||
-----------
|
||||
|
||||
* Jérôme Kieffer (ESRF)
|
||||
* Valentin Valls (ESRF)
|
||||
* Jérôme Kieffer (ESRF)
|
||||
* Valentin Valls (ESRF)
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Frédéric-Emmanuel Picca (Soleil)
|
||||
* Thomas Vincent (ESRF)
|
||||
* Dimitris Karkoulis (ESRF)
|
||||
* Aurore Deschildre (ESRF)
|
||||
* Giannis Ashiotis (ESRF)
|
||||
* Zubair Nawaz (Sesame)
|
||||
* Jon Wright (ESRF)
|
||||
* Amund Hov (ESRF)
|
||||
* Dodogerstlin @github
|
||||
* Gunthard Benecke (Desy)
|
||||
* Gero Flucke (Desy)
|
||||
* Frédéric-Emmanuel Picca (Soleil)
|
||||
* Thomas Vincent (ESRF)
|
||||
* Dimitris Karkoulis (ESRF)
|
||||
* Aurore Deschildre (ESRF)
|
||||
* Giannis Ashiotis (ESRF)
|
||||
* Zubair Nawaz (Sesame)
|
||||
* Jon Wright (ESRF)
|
||||
* Amund Hov (ESRF)
|
||||
* Dodogerstlin @github
|
||||
* Gunthard Benecke (Desy)
|
||||
* Gero Flucke (Desy)
|
||||
|
||||
Indirect contributors (ideas...)
|
||||
--------------------------------
|
||||
|
||||
* Peter Boesecke
|
||||
* Manuel Sánchez del Río
|
||||
* Vicente Armando Solé
|
||||
* Brian Pauw
|
||||
* Veijo Honkimaki
|
||||
* Peter Boesecke
|
||||
* Manuel Sánchez del Río
|
||||
* Vicente Armando Solé
|
||||
* Brian Pauw
|
||||
* Veijo Honkimaki
|
||||
|
||||
.. |Build Status| image:: https://travis-ci.org/silx-kit/pyFAI.svg?branch=master
|
||||
:target: https://travis-ci.org/silx-kit/pyFAI
|
||||
.. |Appveyor Status| image:: https://ci.appveyor.com/api/projects/status/github/silx-kit/pyfai?svg=true
|
||||
:target: https://ci.appveyor.com/project/ESRF/pyfai
|
||||
.. |myBinder Launcher| image:: https://mybinder.org/badge_logo.svg
|
||||
:target: https://mybinder.org/v2/gh/silx-kit/pyFAI/master?filepath=binder%2Findex.ipynb
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# [pyFAI](https://github.com/silx-kit/pyFAI) cookbooks and tutorials\n",
|
||||
"\n",
|
||||
"See the [full documentation](http://www.silx.org/doc/pyFAI/latest/) for more information."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Cookbooks\n",
|
||||
"\n",
|
||||
"- [Integration with python](../doc/source/usage/cookbook/integration_with_python.ipynb)\n",
|
||||
"- [Integration with scripts](../doc/source/usage/cookbook/integration_with_scripts.ipynb)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Tutorials\n",
|
||||
"\n",
|
||||
"- [Introduction](../doc/source/usage/tutorial/Introduction/introduction.ipynb)\n",
|
||||
"- [CCD calibration](../doc/source/usage/tutorial/CCD_Calibration/CCD_calibration.ipynb)\n",
|
||||
"- [Calibrant](../doc/source/usage/tutorial/Calibrant/Calibrant.ipynb)\n",
|
||||
"- [New calibrant](../doc/source/usage/tutorial/Calibrant/new_calibrant.ipynb)\n",
|
||||
"- [Distortion](../doc/source/usage/tutorial/Distortion/Distortion.ipynb)\n",
|
||||
"- [Geometry](../doc/source/usage/tutorial/Geometry/geometry.ipynb)\n",
|
||||
"- Goniometer:\n",
|
||||
"\n",
|
||||
" - [Rotation-Pilatus100k](../doc/source/usage/tutorial/Goniometer/Rotation-Pilatus100k/Multi120_Pilatus100k.ipynb)\n",
|
||||
" - [Rotation-XPADS540](../doc/source/usage/tutorial/Goniometer/Rotation-XPADS540/D2AM-15.ipynb)\n",
|
||||
" - [Translation-Pilatus6M](../doc/source/usage/tutorial/Goniometer/Translation-Pilatus6M/TTcalibration.ipynb)\n",
|
||||
" \n",
|
||||
"- [Inpainting](../doc/source/usage/tutorial/Inpainting/Inpainting.ipynb)\n",
|
||||
"- [LogScale](../doc/source/usage/tutorial/LogScale/Guinier.ipynb)\n",
|
||||
"- [MakeCalibrant](../doc/source/usage/tutorial/MakeCalibrant/make_calibrant.ipynb)\n",
|
||||
"- [MultiGeometry](../doc/source/usage/tutorial/MultiGeometry/MultiGeometry.ipynb)\n",
|
||||
"- [Ellipse](../doc/source/usage/tutorial/Ellipse/ellipse.ipynb)\n",
|
||||
"- Soleil:\n",
|
||||
"\n",
|
||||
" - [Cristal_Mythen](../doc/source/usage/tutorial/Soleil/Cristal_Mythen.ipynb)\n",
|
||||
" - [Diffabs_Calibration_K6C](../doc/source/usage/tutorial/Soleil/Soleil_Diffabs_Calibration_K6C.ipynb)\n",
|
||||
" - [Diffabs_Diffraction_Tomography](../doc/source/usage/tutorial/Soleil/Soleil_Diffabs_Diffraction_Tomography.ipynb)\n",
|
||||
"\n",
|
||||
"- Thick Detector:\n",
|
||||
"\n",
|
||||
" - [Deconvolution](../doc/source/usage/tutorial/ThickDetector/deconvolution.ipynb)\n",
|
||||
" - [Goniometer id28](../doc/source/usage/tutorial/ThickDetector/goniometer_id28.ipynb)\n",
|
||||
" - [Raytracing](../doc/source/usage/tutorial/ThickDetector/raytracing.ipynb)\n",
|
||||
"\n",
|
||||
"- [Variance](../doc/source/usage/tutorial/Variance/Variance.ipynb)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.4.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Setup jupyter bash kernel
|
||||
python -m bash_kernel.install
|
||||
|
||||
# Download resources
|
||||
RESOURCES_URL="http://www.silx.org/pub/pyFAI"
|
||||
echo "Download notebooks from ${RESOURCES_URL}"
|
||||
|
||||
COOKBOOK_DIR="doc/source/usage/cookbook"
|
||||
COOKBOOK_FILES="LaB6_29.4keV.tif
|
||||
LaB6_29.4keV.poni
|
||||
F_K4320T_Cam43_30012013_distorsion.spline"
|
||||
|
||||
for FILE in ${COOKBOOK_FILES}; do
|
||||
URL="${RESOURCES_URL}/cookbook/calibration/${FILE}";
|
||||
echo "Download ${URL}";
|
||||
wget "${URL}" -O ${COOKBOOK_DIR}/${FILE};
|
||||
done
|
|
@ -0,0 +1,3 @@
|
|||
pyFAI
|
||||
ipympl
|
||||
bash_kernel
|
|
@ -1,13 +1,36 @@
|
|||
:Author: Jérôme Kieffer
|
||||
:Date: 19/12/2018
|
||||
:Date: 16/05/2019
|
||||
:Keywords: changelog
|
||||
|
||||
ChangeLog of Versions
|
||||
=====================
|
||||
|
||||
0.18.0 15/05/2019
|
||||
-----------------
|
||||
* Last release with Valentin as he finishes his contract soon
|
||||
* almost 800 commits, 60 PR since the last release: this is a huge release !
|
||||
* Major rework on all GUIs, mainly pyFAI-calib2 and pyFAI-integrate.
|
||||
* Possibility to integrate image stacks (i.e. from HDF5), ...
|
||||
* Rework the *method* to specify the algorithm, pixel splitting and implementation
|
||||
with sensible fall-backs. Also available via the different GUIs
|
||||
* 3D visualization of detectors and experimental setup, useful for non flat detectors.
|
||||
* `integrate1d_ng` is available with histogramming without pixel splitting in
|
||||
Python, Cython and OpenCL. Now, propagates the variance properly !
|
||||
* IO sub-packages with associated refactoring for ponifile, json, ...
|
||||
* Improved management of OpenMP: simplify the code for histograms.
|
||||
* Improved geometry description and tutorial for writing exchange with other
|
||||
software (ImageD11, thanks to Carsten Detlefs).
|
||||
* More reliable simple ellipse fitting with tests and doc.
|
||||
* Better POCL integration (debugged on cuda, x87, Power9, ...)
|
||||
* Rely on *silx* mechanics for the build, test, download, GUI, opencl ...
|
||||
* Many new tutorials, now available on binder-hub: new calibrants, Pilatus calibration, ...
|
||||
* Fix many issues reported in third-party software (Dioptas, ...)
|
||||
* Drop support of debian8, Python 2.7 and Python 3.4 on all platforms.
|
||||
It is likely most functionalities still work but without guaranty.
|
||||
|
||||
0.17.0 19/12/2018
|
||||
-----------------
|
||||
* Only 200 commits in a couple of month, this ia a small release
|
||||
* Only 200 commits in a couple of month, this is a small release
|
||||
* Fix major bugs in pyFAI-calib2 (double validator, initial guess, ring position)
|
||||
* Constrains have been added to the geometry fitting of pyFAI-calib2
|
||||
* New pyFAI-integrate graphical application
|
||||
|
|
|
@ -35,7 +35,7 @@ __author__ = "Jérôme Kieffer"
|
|||
__contact__ = "Jerome.Kieffer@ESRF.eu"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "01/03/2019"
|
||||
__date__ = "16/05/2019"
|
||||
__status__ = "stable"
|
||||
|
||||
|
||||
|
@ -1111,13 +1111,15 @@ class NexusDetector(Detector):
|
|||
setattr(cloned, name, value)
|
||||
return cloned
|
||||
|
||||
def __deepcopy__(self):
|
||||
def __deepcopy__(self, memo=None):
|
||||
import copy
|
||||
cloned = self.__class__()
|
||||
if memo is not None:
|
||||
memo[id(self)] = cloned
|
||||
for name in self._ATTRIBUTES_TO_CLONE:
|
||||
if hasattr(self, name):
|
||||
value = getattr(self, name)
|
||||
value = copy.deepcopy(value)
|
||||
value = copy.deepcopy(value, memo)
|
||||
setattr(cloned, name, value)
|
||||
return cloned
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ __author__ = "Jerome Kieffer"
|
|||
__contact__ = "Jerome.Kieffer@ESRF.eu"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "09/05/2019"
|
||||
__date__ = "16/05/2019"
|
||||
__status__ = "production"
|
||||
__docformat__ = 'restructuredtext'
|
||||
|
||||
|
@ -1439,6 +1439,91 @@ class Geometry(object):
|
|||
logger.warning("Rotation conversion from pyFAI to SPD is not yet implemented")
|
||||
return res
|
||||
|
||||
def getImageD11(self):
|
||||
"""Export the current geometry in ImageD11 format.
|
||||
Please refer to the documentation in doc/source/geometry_conversion.rst
|
||||
for the orientation and units of those values.
|
||||
|
||||
:return: an Ordered dict with those parameters:
|
||||
distance 294662.658 #in nm
|
||||
o11 1
|
||||
o12 0
|
||||
o21 0
|
||||
o22 -1
|
||||
tilt_x 0.00000
|
||||
tilt_y -0.013173
|
||||
tilt_z 0.002378
|
||||
wavelength 0.154
|
||||
y-center 1016.328171
|
||||
y-size 48.0815
|
||||
z-center 984.924425
|
||||
z-size 46.77648
|
||||
"""
|
||||
f2d = self.getFit2D()
|
||||
distance = f2d.get("directDist", 0) * 1e3 # mm -> µm
|
||||
y_center = f2d.get("centerX", 0) # in pixel
|
||||
z_center = f2d.get("centerY", 0) # in pixel
|
||||
|
||||
tilt_x = self.rot3
|
||||
tilt_y = self.rot2
|
||||
tilt_z = -self.rot1
|
||||
out = OrderedDict([("distance", distance),
|
||||
("o11", 1),
|
||||
("o12", 0),
|
||||
("o21", 0),
|
||||
("o22", -1),
|
||||
("tilt_x", tilt_x),
|
||||
("tilt_y", tilt_y),
|
||||
("tilt_z", tilt_z),
|
||||
])
|
||||
if self._wavelength:
|
||||
out["wavelength"] = self.wavelength * 1e9 # nm
|
||||
if y_center:
|
||||
out["y-center"] = y_center
|
||||
out["y-size"] = self.detector.pixel2 * 1e6 # µm
|
||||
if z_center:
|
||||
out["z-center"] = z_center
|
||||
out["z-size"] = self.detector.pixel1 * 1e6 # µm
|
||||
return out
|
||||
|
||||
def setImageD11(self, param):
|
||||
"""Set the geometry from the parameter set which contains distance,
|
||||
o11, o12, o21, o22, tilt_x, tilt_y tilt_z, wavelength, y-center, y-size,
|
||||
z-center and z-size.
|
||||
Please refer to the documentation in doc/source/geometry_conversion.rst
|
||||
for the orientation and units of those values.
|
||||
|
||||
:param param: dict with the values to set.
|
||||
"""
|
||||
o11 = param.get("o11")
|
||||
if o11 is not None:
|
||||
assert o11 == 1, "Only canonical orientation is supported"
|
||||
o12 = param.get("o12")
|
||||
if o12 is not None:
|
||||
assert o12 == 0, "Only canonical orientation is supported"
|
||||
o21 = param.get("o21")
|
||||
if o21 is not None:
|
||||
assert o21 == 0, "Only canonical orientation is supported"
|
||||
o22 = param.get("o22")
|
||||
if o22 is not None:
|
||||
assert o22 == -1, "Only canonical orientation is supported"
|
||||
|
||||
self.rot3 = param.get("tilt_x", 0.0)
|
||||
self.rot2 = param.get("tilt_y", 0.0)
|
||||
self.rot1 = -param.get("tilt_z", 0.0)
|
||||
distance = param.get("distance", 0.0) * 1e-6 # ->m
|
||||
self.dist = distance * cos(self.rot2) * cos(self.rot1)
|
||||
pixel_v = param.get("z-size", 0.0) * 1e-6
|
||||
pixel_h = param.get("y-size", 0.0) * 1e-6
|
||||
self.poni1 = -distance * sin(self.rot2) + pixel_v * param.get("z-center", 0.0)
|
||||
self.poni2 = +distance * cos(self.rot2) * sin(self.rot1) + pixel_h * param.get("y-center", 0.0)
|
||||
self.detector = detectors.Detector(pixel1=pixel_v, pixel2=pixel_h)
|
||||
wl = param.get("wavelength")
|
||||
if wl:
|
||||
self.wavelength = wl * 1e-9
|
||||
self.reset()
|
||||
return self
|
||||
|
||||
def set_param(self, param):
|
||||
"""set the geometry from a 6-tuple with dist, poni1, poni2, rot1, rot2,
|
||||
rot3
|
||||
|
|
|
@ -27,7 +27,7 @@ from __future__ import absolute_import
|
|||
|
||||
__authors__ = ["V. Valls"]
|
||||
__license__ = "MIT"
|
||||
__date__ = "03/01/2019"
|
||||
__date__ = "14/05/2019"
|
||||
|
||||
import logging
|
||||
import functools
|
||||
|
@ -91,9 +91,10 @@ class MarkerManager(object):
|
|||
_logger.debug("Backtrace", exc_info=True)
|
||||
self.__directDist = None
|
||||
|
||||
invertGeometry = InvertGeometry(
|
||||
self.__geometry.array_from_unit(typ="center", unit=pyFAI.units.TTH_RAD, scale=False),
|
||||
self.__geometry.chiArray())
|
||||
if geometry is not None:
|
||||
invertGeometry = InvertGeometry(
|
||||
geometry.array_from_unit(typ="center", unit=pyFAI.units.TTH_RAD, scale=False),
|
||||
geometry.chiArray())
|
||||
|
||||
self.__markerModel.lockSignals()
|
||||
for marker in self.__markerModel:
|
||||
|
@ -102,12 +103,12 @@ class MarkerManager(object):
|
|||
|
||||
chiRad, tthRad = marker.physicalPosition()
|
||||
pixel = None
|
||||
if self.__geometry is not None:
|
||||
if geometry is not None:
|
||||
pixel = invertGeometry(tthRad, chiRad, True)
|
||||
|
||||
ax, ay = numpy.array([pixel[1]]), numpy.array([pixel[0]])
|
||||
tth = self.__geometry.tth(ay, ax)[0]
|
||||
chi = self.__geometry.chi(ay, ax)[0]
|
||||
tth = geometry.tth(ay, ax)[0]
|
||||
chi = geometry.chi(ay, ax)[0]
|
||||
|
||||
error = numpy.sqrt((tthRad - tth) ** 2 + (chiRad - chi) ** 2)
|
||||
if error > 0.05:
|
||||
|
|
|
@ -115,9 +115,9 @@ class CalibrationState(qt.QObject):
|
|||
|
||||
def __init__(self, parent):
|
||||
qt.QObject.__init__(self, parent)
|
||||
self.__reset()
|
||||
self.reset()
|
||||
|
||||
def __reset(self):
|
||||
def reset(self):
|
||||
self.__geoRef = None
|
||||
self.__geometry = None
|
||||
self.__rings = None
|
||||
|
@ -157,7 +157,7 @@ class CalibrationState(qt.QObject):
|
|||
"""Invalidate the object and remove the ownershit of the geometry
|
||||
refinment"""
|
||||
geoRef = self.__geoRef
|
||||
self.__reset()
|
||||
self.reset()
|
||||
return geoRef
|
||||
|
||||
def update(self, calibration):
|
||||
|
@ -909,15 +909,19 @@ class GeometryTask(AbstractCalibrationTask):
|
|||
def __geometryUpdated(self):
|
||||
calibration = self.__getCalibration()
|
||||
if calibration is None:
|
||||
self.__calibrationState.reset()
|
||||
return
|
||||
if not calibration.isValid():
|
||||
self.__showDialogCalibrationDiverge()
|
||||
self.__calibrationState.reset()
|
||||
return
|
||||
geometry = self.model().fittedGeometry()
|
||||
if geometry.isValid():
|
||||
resetResidual = self.__fitting is not True
|
||||
calibration.fromGeometryModel(geometry, resetResidual=resetResidual)
|
||||
self.__calibrationState.update(calibration)
|
||||
else:
|
||||
self.__calibrationState.reset()
|
||||
|
||||
geoRef = calibration.getPyfaiGeometry()
|
||||
self.__plot.markerManager().updatePhysicalMarkerPixels(geoRef)
|
||||
|
|
|
@ -27,7 +27,7 @@ from __future__ import absolute_import
|
|||
|
||||
__authors__ = ["V. Valls"]
|
||||
__license__ = "MIT"
|
||||
__date__ = "07/05/2019"
|
||||
__date__ = "15/05/2019"
|
||||
|
||||
import logging
|
||||
import numpy
|
||||
|
@ -378,19 +378,31 @@ class _PeakPickingPlot(silx.gui.plot.PlotWidget):
|
|||
if hasattr(self, "centralWidget"):
|
||||
self.centralWidget().installEventFilter(self)
|
||||
|
||||
def setInteractiveMode(self, mode, color='black',
|
||||
shape='polygon', label=None,
|
||||
zoomOnWheel=True, source=None, width=None):
|
||||
"""Override the function to allow to disable extrat interaction modes.
|
||||
"""
|
||||
self.setPeakInteractiveMode(self.PEAK_SELECTION_MODE)
|
||||
silx.gui.plot.PlotWidget.setInteractiveMode(self, mode, color=color, shape=shape, label=label, zoomOnWheel=zoomOnWheel, source=source, width=width)
|
||||
|
||||
def peakInteractiveMode(self):
|
||||
"""Returns the peak interactive mode selected."""
|
||||
return self.__mode
|
||||
|
||||
def setPeakInteractiveMode(self, mode):
|
||||
if self.__mode == mode:
|
||||
return
|
||||
self.__mode = mode
|
||||
|
||||
if mode == self.PEAK_SELECTION_MODE:
|
||||
self.setInteractiveMode('zoom')
|
||||
super(_PeakPickingPlot, self).setInteractiveMode('zoom')
|
||||
elif mode == self.ERASOR_MODE:
|
||||
color = "black"
|
||||
self.setInteractiveMode('draw', shape='rectangle', source=self, color=color)
|
||||
super(_PeakPickingPlot, self).setInteractiveMode('draw', shape='rectangle', source=self, color=color)
|
||||
elif mode == self.BRUSH_MODE:
|
||||
color = "black"
|
||||
self.setInteractiveMode('draw', shape='rectangle', source=self, color=color)
|
||||
super(_PeakPickingPlot, self).setInteractiveMode('draw', shape='rectangle', source=self, color=color)
|
||||
else:
|
||||
assert(False)
|
||||
|
||||
|
@ -1077,8 +1089,6 @@ class PeakPickingTask(AbstractCalibrationTask):
|
|||
self.addAction(action)
|
||||
|
||||
def __onPlotModeChanged(self, owner):
|
||||
if owner is None:
|
||||
return
|
||||
# TODO: This condition should not be reached like that
|
||||
if owner is not self.__plot:
|
||||
# Here a default plot tool is triggered
|
||||
|
|
|
@ -34,16 +34,14 @@ __authors__ = ["Jérôme Kieffer"]
|
|||
__contact__ = "jerome.kieffer@esrf.eu"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "01/03/2019"
|
||||
__date__ = "16/05/2019"
|
||||
|
||||
import sys
|
||||
import os
|
||||
import unittest
|
||||
|
||||
|
||||
from . import utilstest
|
||||
# not importing test_all here to prevent premature initialization of UtilsTest
|
||||
# and preventing the test skipping
|
||||
from pyFAI.test.utilstest import test_options
|
||||
|
||||
|
||||
# Issue https://github.com/silx-kit/fabio/pull/291
|
||||
|
@ -59,6 +57,8 @@ if fabio.hdf5image.Hdf5Image.close.__module__ != "fabio.hdf5image":
|
|||
|
||||
|
||||
def suite():
|
||||
# Importing locally to prevent premature initialization of UtilsTest
|
||||
# and preventing the test skipping
|
||||
from . import test_all
|
||||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(test_all.suite())
|
||||
|
@ -67,6 +67,7 @@ def suite():
|
|||
|
||||
def run_tests():
|
||||
"""Run test complete test_suite"""
|
||||
test_options.configure()
|
||||
runner = unittest.TextTestRunner()
|
||||
if not runner.run(suite()).wasSuccessful():
|
||||
print("Test suite failed")
|
||||
|
|
|
@ -34,7 +34,7 @@ __author__ = "Jérôme Kieffer"
|
|||
__contact__ = "Jerome.Kieffer@ESRF.eu"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "10/01/2018"
|
||||
__date__ = "16/05/2019"
|
||||
|
||||
|
||||
import unittest
|
||||
|
@ -100,6 +100,21 @@ class TestFIT2D(unittest.TestCase):
|
|||
res = testExport(tilt=20, tpr=580)
|
||||
self.assertFalse(res, res)
|
||||
|
||||
def test_ImageD11(self):
|
||||
ai = AzimuthalIntegrator()
|
||||
ai.setFit2D(100, centerX=900, centerY=1000, tilt=20, tiltPlanRotation=80, pixelX=50, pixelY=60)
|
||||
ai.wavelength = 1.234e-10
|
||||
param = ai.getImageD11()
|
||||
ai2 = AzimuthalIntegrator()
|
||||
ai2.setImageD11(param)
|
||||
for key in ["dist", "poni1", "poni2", "rot1", "rot2", "rot3", "pixel1", "pixel2", "splineFile", "wavelength"]:
|
||||
refv = ai.__getattribute__(key)
|
||||
obtv = ai2.__getattribute__(key)
|
||||
if refv is None:
|
||||
self.assertEqual(refv, obtv, "%s: %s != %s" % (key, refv, obtv))
|
||||
else:
|
||||
self.assertAlmostEqual(refv, obtv, 4, "%s: %s != %s" % (key, refv, obtv))
|
||||
|
||||
|
||||
class TestSPD(unittest.TestCase):
|
||||
poniFile = "Pilatus1M.poni"
|
||||
|
|
|
@ -29,7 +29,7 @@ __author__ = "Jérôme Kieffer"
|
|||
__contact__ = "jerome.kieffer@esrf.eu"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
||||
__date__ = "12/02/2019"
|
||||
__date__ = "16/05/2019"
|
||||
|
||||
PACKAGE = "pyFAI"
|
||||
|
||||
|
@ -133,11 +133,11 @@ class TestOptions(object):
|
|||
"""
|
||||
return
|
||||
|
||||
def configure(self, parsed_options):
|
||||
def configure(self, parsed_options=None):
|
||||
"""Configure the TestOptions class from the command line arguments and the
|
||||
environment variables
|
||||
"""
|
||||
if not parsed_options.gui:
|
||||
if parsed_options is not None and not parsed_options.gui:
|
||||
self.WITH_QT_TEST = False
|
||||
self.WITH_QT_TEST_REASON = "Skipped by command line"
|
||||
elif os.environ.get('WITH_QT_TEST', 'True') == 'False':
|
||||
|
@ -147,20 +147,27 @@ class TestOptions(object):
|
|||
self.WITH_QT_TEST = False
|
||||
self.WITH_QT_TEST_REASON = "DISPLAY env variable not set"
|
||||
|
||||
if not parsed_options.opencl or os.environ.get('PYFAI_OPENCL', 'True') == 'False':
|
||||
if parsed_options is not None and not parsed_options.opencl:
|
||||
self.WITH_OPENCL_TEST = False
|
||||
# That's an easy way to skip OpenCL tests
|
||||
# It disable the use of OpenCL on the full silx project
|
||||
os.environ['PYFAI_OPENCL'] = "False"
|
||||
elif os.environ.get('PYFAI_OPENCL', 'True') == 'False':
|
||||
self.WITH_OPENCL_TEST = False
|
||||
# That's an easy way to skip OpenCL tests
|
||||
# It disable the use of OpenCL on the full silx project
|
||||
os.environ['PYFAI_OPENCL'] = "False"
|
||||
|
||||
if not parsed_options.opengl:
|
||||
if parsed_options is not None and not parsed_options.opengl:
|
||||
self.WITH_GL_TEST = False
|
||||
self.WITH_GL_TEST_REASON = "Skipped by command line"
|
||||
elif os.environ.get('WITH_GL_TEST', 'True') == 'False':
|
||||
self.WITH_GL_TEST = False
|
||||
self.WITH_GL_TEST_REASON = "Skipped by WITH_GL_TEST env var"
|
||||
|
||||
if parsed_options.low_mem or os.environ.get('PYFAI_LOW_MEM', 'True') == 'False':
|
||||
if parsed_options is not None and parsed_options.low_mem:
|
||||
self.TEST_LOW_MEM = True
|
||||
elif os.environ.get('PYFAI_LOW_MEM', 'True') == 'False':
|
||||
self.TEST_LOW_MEM = True
|
||||
|
||||
def add_parser_argument(self, parser):
|
||||
|
|
Loading…
Reference in New Issue