Skip to content

Commit 9e89d21

Browse files
committed
Merge remote-tracking branch 'upstream/master' into 1088_numpy_1.16
2 parents f4c53e2 + 1b560c9 commit 9e89d21

25 files changed

+715
-340
lines changed

foo-mask.edf

-64.5 KB
Binary file not shown.

pyFAI/app/integrate.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
__contact__ = "[email protected]"
3535
__license__ = "MIT"
3636
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
37-
__date__ = "07/01/2019"
37+
__date__ = "15/01/2019"
3838
__satus__ = "production"
3939
import sys
4040
import logging
@@ -65,10 +65,21 @@ def integrate_gui(options, args):
6565
from silx.gui import qt
6666
from pyFAI.gui.IntegrationDialog import IntegrationDialog
6767
app = qt.QApplication([])
68-
window = IntegrationDialog(args, options.output, json_file=options.json)
68+
69+
from pyFAI.gui.ApplicationContext import ApplicationContext
70+
settings = qt.QSettings(qt.QSettings.IniFormat,
71+
qt.QSettings.UserScope,
72+
"pyfai",
73+
"pyfai-integrate",
74+
None)
75+
context = ApplicationContext(settings)
76+
77+
window = IntegrationDialog(args, options.output, json_file=options.json, context=context)
6978
window.set_input_data(args)
7079
window.show()
71-
return app.exec_()
80+
result = app.exec_()
81+
context.saveSettings()
82+
return result
7283

7384

7485
def get_monitor_value(image, monitor_key):

pyFAI/azimuthalIntegrator.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
__contact__ = "[email protected]"
3333
__license__ = "MIT"
3434
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
35-
__date__ = "03/01/2019"
35+
__date__ = "14/01/2019"
3636
__status__ = "stable"
3737
__docformat__ = 'restructuredtext'
3838

@@ -172,8 +172,9 @@
172172
# Register splitPixelFullCSR integrators
173173
IntegrationMethod(1, "full", "CSR", "cython", old_method="full_csr",
174174
class_funct=(splitPixelFullCSR.FullSplitCSR_1d, splitPixelFullCSR.FullSplitCSR_1d.integrate))
175-
IntegrationMethod(2, "full", "CSR", "cython", old_method="full_csr",
176-
class_funct=(splitPixelFullCSR.FullSplitCSR_2d, splitPixelFullCSR.FullSplitCSR_2d.integrate))
175+
# FIXME: The implementation is there but the routing have to be fixed
176+
# IntegrationMethod(2, "full", "CSR", "cython", old_method="full_csr",
177+
# class_funct=(splitPixelFullCSR.FullSplitCSR_2d, splitPixelFullCSR.FullSplitCSR_2d.integrate))
177178

178179
from .opencl import ocl
179180
if ocl:

pyFAI/detectors/_imxpad.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
__contact__ = "[email protected]"
3737
__license__ = "MIT"
3838
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
39-
__date__ = "16/10/2018"
39+
__date__ = "18/01/2019"
4040
__status__ = "production"
4141

4242
import functools
@@ -535,16 +535,15 @@ def _calc_pixels_size(self, length, module_size, pixel_size):
535535

536536
def _passage(self, corners, rot):
537537
shape = corners.shape
538-
origine = corners[0][0][0, :]
538+
deltaX, deltaY = 0.0, 0.0
539539
nmd = self._rotation(corners, rot)
540-
u = corners[shape[0] - 1][0][1, :] - corners[0][0][0, :]
541-
u = u / numpy.linalg.norm(u)
542-
s = self._rotation(u, rot)
543-
s = s / numpy.linalg.norm(s)
544-
v = numpy.array([-u[1], u[0], u[2]])
545-
r = origine - nmd[0][0][0, :]
546-
w = (0.1e-3 + 0.24e-3 + 75.14e-3) * u + (0.8e-3) * v + (0.55e-3) * s + r
547-
return self._translation(nmd, w)
540+
# Size in mm of the chip in the Y direction (including 10px gap)
541+
size_Y = ((560.0 + 3 * 6 + 20)*0.13/1000)
542+
for i in range(1, int(round(numpy.abs(rot[2])/6.74))):
543+
deltaX = deltaX + numpy.sin(numpy.deg2rad(-rot[2] -6.74*(i)))
544+
for i in range(int(round(numpy.abs(rot[2])/6.74))):
545+
deltaY = deltaY + numpy.cos(numpy.deg2rad(-rot[2] - 6.74*(i+1)))
546+
return self._translation(nmd, [size_Y*deltaX,size_Y*deltaY, 0])
548547

549548
def _get_pixel_corners(self):
550549
pixel_size1 = self._calc_pixels_size(self.MEDIUM_MODULE_SIZE[0],
@@ -581,13 +580,15 @@ def _get_pixel_corners(self):
581580
corners[:, :, 3, 1] = pixel_center1 - pixel_size1 / 2.0
582581
corners[:, :, 3, 2] = pixel_center2 + pixel_size2 / 2.0
583582

584-
modules = [self._passage(corners, [self.ROT[0], self.ROT[1], self.ROT[2]*i]) for i in range(20)]
585-
return numpy.concatenate(modules, axis=0)
583+
modules = [self._passage(corners, [self.ROT[0], self.ROT[1], self.ROT[2] * i]) for i in range(20)]
584+
result = numpy.concatenate(modules, axis=0)
585+
result = numpy.ascontiguousarray(result, result.dtype)
586+
return result
586587

587588
def get_pixel_corners(self):
588589
if self._pixel_corners is None:
589590
with self._sem:
590-
if self._pixel_corners is None:
591+
if self._pixel_corners is None:
591592
self._pixel_corners = self._get_pixel_corners()
592593
return self._pixel_corners
593594

pyFAI/geometryRefinement.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
__contact__ = "[email protected]"
3636
__license__ = "MIT"
3737
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
38-
__date__ = "27/11/2018"
38+
__date__ = "11/01/2019"
3939
__status__ = "development"
4040

4141
import os
@@ -331,9 +331,6 @@ def refine2(self, maxiter=1000000, fix=None):
331331
bounds.append((getattr(self, "_%s_min" % i), getattr(self, "_%s_max" % i)))
332332
self.param = numpy.array(param)
333333

334-
print(self.data)
335-
print(self.param, fix, bounds, self.chi2(param) / self.data.shape[0])
336-
337334
if self.data.shape[-1] == 3:
338335
pos0 = self.data[:, 0]
339336
pos1 = self.data[:, 1]
@@ -360,8 +357,6 @@ def refine2(self, maxiter=1000000, fix=None):
360357
logger.info("Constrained Least square %s --> %s",
361358
oldDeltaSq, newDeltaSq)
362359

363-
print(new_param, fix, bounds, self.chi2(new_param) / self.data.shape[0])
364-
365360
if newDeltaSq < oldDeltaSq:
366361
i = abs(self.param - new_param).argmax()
367362

@@ -519,8 +514,13 @@ def curve_fit(self, with_rot=True):
519514
size = d1.size
520515
x = d1, d2
521516
rings = self.data[:, 2].astype(numpy.int32)
522-
f_with_rot = lambda x, *param: self.tth(x[0], x[1], numpy.concatenate((param, [self.rot3])))
523-
f_no_rot = lambda x, *param: self.tth(x[0], x[1], numpy.concatenate((param, [self.rot1, self.rot2, self.rot3])))
517+
518+
def f_with_rot(x, *param):
519+
return self.tth(x[0], x[1], numpy.concatenate((param, [self.rot3])))
520+
521+
def f_no_rot(x, *param):
522+
return self.tth(x[0], x[1], numpy.concatenate((param, [self.rot1, self.rot2, self.rot3])))
523+
524524
y = self.calc_2th(rings, self.wavelength)
525525
param0 = numpy.array([self.dist, self.poni1, self.poni2, self.rot1, self.rot2, self.rot3], dtype=numpy.float64)
526526
ref = self.residu2(param0, d1, d2, rings)

pyFAI/gui/ApplicationContext.py

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# coding: utf-8
2+
# /*##########################################################################
3+
# Copyright (C) 2016-2018 European Synchrotron Radiation Facility
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
# THE SOFTWARE.
22+
#
23+
# ############################################################################*/
24+
"""Context shared through all the application"""
25+
26+
__authors__ = ["V. Valls"]
27+
__license__ = "MIT"
28+
__date__ = "15/01/2019"
29+
30+
import weakref
31+
import logging
32+
import functools
33+
import os
34+
35+
from silx.gui import qt
36+
37+
from ..utils import stringutil
38+
39+
40+
_logger = logging.getLogger(__name__)
41+
42+
43+
class ApplicationContext(object):
44+
45+
__instance = None
46+
47+
@staticmethod
48+
def _releaseSingleton():
49+
ApplicationContext.__instance = None
50+
51+
@staticmethod
52+
def instance():
53+
"""
54+
:rtype: CalibrationContext
55+
"""
56+
assert(ApplicationContext.__instance is not None)
57+
return ApplicationContext.__instance
58+
59+
def __init__(self, settings=None):
60+
assert(ApplicationContext.__instance is None)
61+
self.__parent = None
62+
self.__dialogState = None
63+
self.__settings = settings
64+
ApplicationContext.__instance = self
65+
66+
def saveSettings(self):
67+
"""Save the settings of all the application"""
68+
# Synchronize the file storage
69+
self.__settings.sync()
70+
71+
def restoreWindowLocationSettings(self, groupName, window):
72+
"""Restore the window settings using this settings object
73+
74+
:param qt.QSettings settings: Initialized settings
75+
"""
76+
settings = self.__settings
77+
if settings is None:
78+
_logger.debug("Settings not set")
79+
return
80+
81+
settings.beginGroup(groupName)
82+
size = settings.value("size", qt.QSize())
83+
pos = settings.value("pos", qt.QPoint())
84+
isFullScreen = settings.value("full-screen", False)
85+
try:
86+
if not isinstance(isFullScreen, bool):
87+
isFullScreen = stringutil.to_bool(isFullScreen)
88+
except ValueError:
89+
isFullScreen = False
90+
settings.endGroup()
91+
92+
if not pos.isNull():
93+
window.move(pos)
94+
if not size.isNull():
95+
window.resize(size)
96+
if isFullScreen:
97+
window.showFullScreen()
98+
99+
def saveWindowLocationSettings(self, groupName, window):
100+
"""Save the window settings to this settings object
101+
102+
:param qt.QSettings settings: Initialized settings
103+
"""
104+
settings = self.__settings
105+
if settings is None:
106+
_logger.debug("Settings not set")
107+
return
108+
109+
isFullScreen = bool(window.windowState() & qt.Qt.WindowFullScreen)
110+
if isFullScreen:
111+
# show in normal to catch the normal geometry
112+
window.showNormal()
113+
114+
settings.beginGroup(groupName)
115+
settings.setValue("size", window.size())
116+
settings.setValue("pos", window.pos())
117+
settings.setValue("full-screen", isFullScreen)
118+
settings.endGroup()
119+
120+
if isFullScreen:
121+
window.showFullScreen()
122+
123+
def setParent(self, parent):
124+
self.__parent = weakref.ref(parent)
125+
126+
def parent(self):
127+
if self.__parent is None:
128+
return None
129+
return self.__parent()
130+
131+
def createFileDialog(self, parent, previousFile=None):
132+
"""Create a file dialog configured with a default path.
133+
134+
:rtype: qt.QFileDialog
135+
"""
136+
dialog = qt.QFileDialog(parent)
137+
dialog.finished.connect(functools.partial(self.__saveDialogState, dialog))
138+
if self.__dialogState is None:
139+
currentDirectory = os.getcwd()
140+
dialog.setDirectory(currentDirectory)
141+
else:
142+
dialog.restoreState(self.__dialogState)
143+
144+
if previousFile is not None:
145+
if os.path.exists(previousFile):
146+
if os.path.isdir(previousFile):
147+
directory = previousFile
148+
else:
149+
directory = os.path.dirname(previousFile)
150+
dialog.setDirectory(directory)
151+
152+
return dialog
153+
154+
def __saveDialogState(self, dialog):
155+
self.__dialogState = dialog.saveState()

0 commit comments

Comments
 (0)