Commit f6ea0bec authored by Julia Garriga Ferrer's avatar Julia Garriga Ferrer
Browse files

Merge branch 'magnification'

parents cd7fc36a ef969c11
Pipeline #48611 passed with stage
in 2 minutes and 6 seconds
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
__authors__ = ["J. Garriga"] __authors__ = ["J. Garriga"]
__license__ = "MIT" __license__ = "MIT"
__date__ = "26/05/2021" __date__ = "07/06/2021"
import copy import copy
import glob import glob
...@@ -46,14 +46,14 @@ from silx.io import utils ...@@ -46,14 +46,14 @@ from silx.io import utils
from silx.io import fabioh5 from silx.io import fabioh5
from silx.io.url import DataUrl from silx.io.url import DataUrl
from darfix.core.dimension import AcquisitionDims, Dimension from darfix.core.dimension import AcquisitionDims, Dimension, POSITIONER_METADATA
from darfix.core.imageOperations import img2img_mean, chunk_image from darfix.core.imageOperations import img2img_mean, chunk_image
from darfix.core.imageOperations import background_subtraction, background_subtraction_2D from darfix.core.imageOperations import background_subtraction, background_subtraction_2D
from darfix.core.imageOperations import hot_pixel_removal_3D, hot_pixel_removal_2D from darfix.core.imageOperations import hot_pixel_removal_3D, hot_pixel_removal_2D
from darfix.core.imageOperations import threshold_removal from darfix.core.imageOperations import threshold_removal
from darfix.core.imageOperations import Method from darfix.core.imageOperations import Method
from darfix.core.imageRegistration import shift_detection, apply_shift from darfix.core.imageRegistration import shift_detection, apply_shift
from darfix.core.mapping import fit_data, compute_moments from darfix.core.mapping import fit_data, compute_moments, compute_rsm, compute_magnification
from darfix.core.roi import apply_2D_ROI, apply_3D_ROI from darfix.core.roi import apply_2D_ROI, apply_3D_ROI
from darfix.core.utils import wrapTo2pi from darfix.core.utils import wrapTo2pi
from darfix.decomposition.ipca import IPCA from darfix.decomposition.ipca import IPCA
...@@ -100,7 +100,7 @@ class Dataset(): ...@@ -100,7 +100,7 @@ class Dataset():
""" """
def __init__(self, _dir, data=None, first_filename=None, filenames=None, def __init__(self, _dir, data=None, first_filename=None, filenames=None,
dims=None, in_memory=True, copy_files=False): dims=None, transformation=None, in_memory=True, copy_files=False):
self._data = None self._data = None
self._frames_intensity = [] self._frames_intensity = []
...@@ -109,6 +109,7 @@ class Dataset(): ...@@ -109,6 +109,7 @@ class Dataset():
self.moments_dims = {} self.moments_dims = {}
self.operations_state = numpy.zeros(len(Operation)) self.operations_state = numpy.zeros(len(Operation))
self._dir = _dir self._dir = _dir
self._transformation = transformation
if copy_files: if copy_files:
self._dir += "/treated" self._dir += "/treated"
if not os.path.isdir(self._dir): if not os.path.isdir(self._dir):
...@@ -164,6 +165,14 @@ class Dataset(): ...@@ -164,6 +165,14 @@ class Dataset():
if self.running_data is not None: if self.running_data is not None:
self.running_data.stop_operation(operation) self.running_data.stop_operation(operation)
@property
def transformation(self):
return self._transformation
@transformation.setter
def transformation(self, value):
self._transformation = value
@property @property
def dir(self): def dir(self):
return self._dir return self._dir
...@@ -396,6 +405,10 @@ class Dataset(): ...@@ -396,6 +405,10 @@ class Dataset():
_logger.info("Dimension {} of size {} has been added for reshaping" _logger.info("Dimension {} of size {} has been added for reshaping"
.format(dimension.name, dimension.size)) .format(dimension.name, dimension.size))
def get_metadata_values(self, kind, key):
return numpy.unique([data.get_value(kind=kind, name=key)[0] for data
in self.get_data().metadata])
def __compute_changing_value(self, values, changing_value=1): def __compute_changing_value(self, values, changing_value=1):
""" """
Recursive method used to calculate how fast is a dimension. The speed of a dimension is the number of Recursive method used to calculate how fast is a dimension. The speed of a dimension is the number of
...@@ -582,7 +595,8 @@ class Dataset(): ...@@ -582,7 +595,8 @@ class Dataset():
new_data = Data(urls.reshape(self.data.urls.shape), self.data.metadata, new_data = Data(urls.reshape(self.data.urls.shape), self.data.metadata,
self._in_memory) self._in_memory)
return Dataset(_dir=_dir, data=new_data, dims=self.__dims, in_memory=self._in_memory) return Dataset(_dir=_dir, data=new_data, dims=self.__dims, transformation=self.transformation,
in_memory=self._in_memory)
def apply_hot_pixel_removal(self, kernel=3, indices=None, _dir=None): def apply_hot_pixel_removal(self, kernel=3, indices=None, _dir=None):
""" """
...@@ -627,7 +641,8 @@ class Dataset(): ...@@ -627,7 +641,8 @@ class Dataset():
new_data = Data(urls.reshape(self.data.urls.shape), self.data.metadata, new_data = Data(urls.reshape(self.data.urls.shape), self.data.metadata,
self._in_memory) self._in_memory)
return Dataset(_dir=_dir, data=new_data, dims=self.__dims, in_memory=self._in_memory) return Dataset(_dir=_dir, data=new_data, dims=self.__dims, transformation=self.transformation,
in_memory=self._in_memory)
def apply_threshold_removal(self, bottom=None, top=None, indices=None, _dir=None): def apply_threshold_removal(self, bottom=None, top=None, indices=None, _dir=None):
""" """
...@@ -672,7 +687,8 @@ class Dataset(): ...@@ -672,7 +687,8 @@ class Dataset():
new_data = Data(urls.reshape(self.data.urls.shape), self.data.metadata, new_data = Data(urls.reshape(self.data.urls.shape), self.data.metadata,
self._in_memory) self._in_memory)
return Dataset(_dir=_dir, data=new_data, dims=self.__dims, in_memory=self._in_memory) return Dataset(_dir=_dir, data=new_data, dims=self.__dims, transformation=self.transformation,
in_memory=self._in_memory)
def apply_roi(self, origin=None, size=None, center=None, indices=None, roi_dir=None): def apply_roi(self, origin=None, size=None, center=None, indices=None, roi_dir=None):
""" """
...@@ -710,12 +726,16 @@ class Dataset(): ...@@ -710,12 +726,16 @@ class Dataset():
if urls is None: if urls is None:
return return
new_data = Data(urls, self.running_data.metadata, self._in_memory) new_data = Data(urls, self.running_data.metadata, self._in_memory)
transformation = ([apply_2D_ROI(axis, origin, size, center) for axis in self.transformation]
if self.transformation else None)
if indices is None: if indices is None:
shape = list(self.data.shape)[:-2] shape = list(self.data.shape)[:-2]
shape.append(new_data.shape[-2]) shape.append(new_data.shape[-2])
shape.append(new_data.shape[-1]) shape.append(new_data.shape[-1])
new_data = new_data.reshape(shape) new_data = new_data.reshape(shape)
return Dataset(_dir=roi_dir, data=new_data, dims=self.__dims, in_memory=self._in_memory) return Dataset(_dir=roi_dir, data=new_data, dims=self.__dims, transformation=transformation,
in_memory=self._in_memory)
def find_shift(self, dimension=None, h_max=0.5, h_step=0.01, indices=None): def find_shift(self, dimension=None, h_max=0.5, h_step=0.01, indices=None):
""" """
...@@ -823,7 +843,8 @@ class Dataset(): ...@@ -823,7 +843,8 @@ class Dataset():
self._lock.release() self._lock.release()
data = Data(new_urls.reshape(self.data.urls.shape), self.data.metadata, in_memory=self._in_memory) data = Data(new_urls.reshape(self.data.urls.shape), self.data.metadata, in_memory=self._in_memory)
return Dataset(_dir=_dir, data=data, dims=self.__dims, in_memory=self._in_memory) return Dataset(_dir=_dir, data=data, dims=self.__dims, transformation=self.transformation,
in_memory=self._in_memory)
def find_and_apply_shift(self, dimension=None, h_max=0.5, h_step=0.01, shift_approach="fft", def find_and_apply_shift(self, dimension=None, h_max=0.5, h_step=0.01, shift_approach="fft",
indices=None, callback=None): indices=None, callback=None):
...@@ -1256,7 +1277,22 @@ class Dataset(): ...@@ -1256,7 +1277,22 @@ class Dataset():
else: else:
new_urls = numpy.array(urls) new_urls = numpy.array(urls)
data = Data(new_urls.reshape(self.data.urls.shape), self.data.metadata, in_memory=True) # to modify data = Data(new_urls.reshape(self.data.urls.shape), self.data.metadata, in_memory=True) # to modify
return Dataset(_dir=_dir, data=data, dims=self.__dims, in_memory=True) return Dataset(_dir=_dir, data=data, dims=self.__dims, transformation=self.transformation, in_memory=True)
def compute_transformation(self, d, rotate=False):
H, W = self.get_data(0).shape
if self.dims.ndim == 1:
ffz = self.get_metadata_values(POSITIONER_METADATA, "ffz")[0]
mainx = -self.get_metadata_values(POSITIONER_METADATA, "mainx")[0]
self.transformation = compute_rsm(H, W, d, ffz, mainx)
else:
obx = self.get_metadata_values(POSITIONER_METADATA, "obx")[0]
obpitch = self.get_metadata_values(POSITIONER_METADATA, "obpitch")
obpitch = obpitch[len(obpitch) // 2]
mainx = -self.get_metadata_values(POSITIONER_METADATA, "mainx")[0]
self.transformation = compute_magnification(H, W, d, obx, obpitch, mainx)
def __deepcopy__(self, memo): def __deepcopy__(self, memo):
""" """
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
__authors__ = ["J. Garriga"] __authors__ = ["J. Garriga"]
__license__ = "MIT" __license__ = "MIT"
__date__ = "22/02/2020" __date__ = "04/06/2021"
import numpy import numpy
try: try:
...@@ -138,13 +138,35 @@ def compute_moments(values, data): ...@@ -138,13 +138,35 @@ def compute_moments(values, data):
stack = [values[i] * data[i] for i in range(len(data))] stack = [values[i] * data[i] for i in range(len(data))]
zsum = numpy.sum(data, axis=0) zsum = numpy.sum(data, axis=0)
com = numpy.sum(stack, axis=0) / zsum com = numpy.sum(stack, axis=0) / zsum
com = medfilt2d(com) com = medfilt2d(com.astype(numpy.float64))
com[numpy.isnan(com)] = numpy.min(com[~numpy.isnan(com)]) com[numpy.isnan(com)] = numpy.min(com[~numpy.isnan(com)])
repeat_values = numpy.repeat(values, com.shape[0] * com.shape[1]).reshape(len(values), com.shape[0], com.shape[1]) repeat_values = numpy.repeat(values, com.shape[0] * com.shape[1]).reshape(len(values), com.shape[0], com.shape[1])
std = numpy.sqrt(numpy.sum((data[i] * ((repeat_values[i] - com)**2) for i in range(len(data))), axis=0)) / zsum std = numpy.sqrt(numpy.sum((data[i] * ((repeat_values[i] - com)**2) for i in range(len(data))), axis=0)) / zsum
std = medfilt2d(std) std = medfilt2d(std.astype(numpy.float64))
std[numpy.isnan(std)] = numpy.min(std[~numpy.isnan(std)]) std[numpy.isnan(std)] = numpy.min(std[~numpy.isnan(std)])
skews = skew(stack, axis=0) skews = skew(stack, axis=0)
kurt = kurtosis(stack, axis=0) kurt = kurtosis(stack, axis=0)
return com, std, skews, kurt return com, std, skews, kurt
def compute_rsm(H, W, d, ffz, mainx):
pix_arr = numpy.meshgrid(numpy.arange(H), numpy.arange(W))
pix_arr[0] = (pix_arr[0] - W / 2) * d
pix_arr[1] = (H / 2 - pix_arr[1]) * d
pix_arr[0] = numpy.arctan2((ffz - W / 2) * pix_arr[0], mainx)
pix_arr[1] = numpy.arctan2(pix_arr[1], numpy.sqrt(ffz * ffz + mainx * mainx))
return pix_arr
def compute_magnification(H, W, d, obx, obpitch, mainx):
pix_arr = numpy.meshgrid(numpy.arange(H), numpy.arange(W))
d1 = obx / numpy.cos(obpitch)
d2 = mainx / numpy.cos(obpitch) - d1
M = d2 / d1
d /= M
pix_arr[0] = (pix_arr[0] - W / 2) * d
pix_arr[1] = (H / 2 - pix_arr[1]) * d
return pix_arr
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
__authors__ = ["J. Garriga"] __authors__ = ["J. Garriga"]
__license__ = "MIT" __license__ = "MIT"
__date__ = "22/02/2021" __date__ = "07/06/2021"
from matplotlib.colors import hsv_to_rgb from matplotlib.colors import hsv_to_rgb
import numpy import numpy
...@@ -111,22 +111,32 @@ class GrainPlotWidget(qt.QMainWindow): ...@@ -111,22 +111,32 @@ class GrainPlotWidget(qt.QMainWindow):
self.indices = indices self.indices = indices
self.bg_indices = bg_indices self.bg_indices = bg_indices
self.bg_dataset = bg_dataset self.bg_dataset = bg_dataset
for i in range(len(Method)):
self._methodCB.model().item(i).setEnabled(False)
scale = 100 scale = 100
self.ori_dist, self.hsv_key = self.dataset.compute_mosaicity_colorkey() if self.dataset.transformation:
xdim = self.dataset.dims.get(1) px = self.dataset.transformation[0][0][0]
ydim = self.dataset.dims.get(0) py = self.dataset.transformation[1][0][0]
xscale = (xdim.unique_values[-1] - xdim.unique_values[0]) / (xdim.size - 1) xscale = (self.dataset.transformation[0][-1][-1] - px) / len(self.dataset.transformation[0][0])
yscale = (ydim.unique_values[-1] - ydim.unique_values[0]) / (ydim.size - 1) yscale = (self.dataset.transformation[1][-1][-1] - py) / len(self.dataset.transformation[1][0])
self.origin = (px, py)
self._contoursPlot.addImage(hsv_to_rgb(self.hsv_key), xlabel=xdim.name, self.scale = (xscale, yscale)
ylabel=ydim.name, scale=(xscale / scale, yscale / scale)) if self.dataset.dims.ndim > 1:
self._contoursPlot.getColorBarWidget().hide() self.ori_dist, self.hsv_key = self.dataset.compute_mosaicity_colorkey()
self._methodCB.model().item(4).setEnabled(True) xdim = self.dataset.dims.get(1)
self._methodCB.setCurrentIndex(4) ydim = self.dataset.dims.get(0)
self._curvesColormap = Colormap(name='temperature', xscale = (xdim.unique_values[-1] - xdim.unique_values[0]) / (xdim.size - 1)
vmin=numpy.min(self.ori_dist), yscale = (ydim.unique_values[-1] - ydim.unique_values[0]) / (ydim.size - 1)
vmax=numpy.max(self.ori_dist))
self._computeContoursB.clicked.connect(self._computeContours) self._contoursPlot.addImage(hsv_to_rgb(self.hsv_key), xlabel=xdim.name,
ylabel=ydim.name, scale=(xscale / scale, yscale / scale))
self._contoursPlot.getColorBarWidget().hide()
self._curvesColormap = Colormap(name='temperature',
vmin=numpy.min(self.ori_dist),
vmax=numpy.max(self.ori_dist))
self._computeContoursB.clicked.connect(self._computeContours)
self._methodCB.model().item(4).setEnabled(True)
self._methodCB.setCurrentIndex(4)
self._thread = OperationThread(self, self.dataset.apply_moments) self._thread = OperationThread(self, self.dataset.apply_moments)
self._thread.setArgs(self.indices) self._thread.setArgs(self.indices)
self._thread.finished.connect(self._updateData) self._thread.finished.connect(self._updateData)
...@@ -140,7 +150,6 @@ class GrainPlotWidget(qt.QMainWindow): ...@@ -140,7 +150,6 @@ class GrainPlotWidget(qt.QMainWindow):
self._plots[-1].setGraphTitle(dim.name) self._plots[-1].setGraphTitle(dim.name)
self._plots[-1].setDefaultColormap(Colormap(name='viridis')) self._plots[-1].setDefaultColormap(Colormap(name='viridis'))
self._plotWidget.layout().addWidget(self._plots[-1]) self._plotWidget.layout().addWidget(self._plots[-1])
self._updatePlot(self._methodCB.currentText())
def _updateData(self): def _updateData(self):
""" """
...@@ -149,8 +158,11 @@ class GrainPlotWidget(qt.QMainWindow): ...@@ -149,8 +158,11 @@ class GrainPlotWidget(qt.QMainWindow):
self._thread.finished.disconnect(self._updateData) self._thread.finished.disconnect(self._updateData)
if self._thread.data is not None: if self._thread.data is not None:
self._moments = self._thread.data self._moments = self._thread.data
for i in range(len(Method)): self._updatePlot(self._methodCB.currentText())
rg = len(Method) if self.dataset.dims.ndim > 1 else 4
for i in range(rg):
self._methodCB.model().item(i).setEnabled(True) self._methodCB.model().item(i).setEnabled(True)
self._methodCB.setCurrentIndex(0)
else: else:
print("\nComputation aborted") print("\nComputation aborted")
...@@ -226,8 +238,12 @@ class GrainPlotWidget(qt.QMainWindow): ...@@ -226,8 +238,12 @@ class GrainPlotWidget(qt.QMainWindow):
plot.addImage(darfix.config.FWHM_VAL * self._moments[i][1]) plot.addImage(darfix.config.FWHM_VAL * self._moments[i][1])
elif method == Method.COM: elif method == Method.COM:
self._plotWidget.show() self._plotWidget.show()
for i, plot in enumerate(self._plots): if self.dataset.transformation is not None:
plot.addImage(self._moments[i][0]) for i, plot in enumerate(self._plots):
plot.addImage(self._moments[i][0], origin=self.origin, scale=self.scale, xlabel='µm', ylabel='µm')
else:
for i, plot in enumerate(self._plots):
plot.addImage(self._moments[i][0], xlabel='pixels', ylabel='pixels')
elif method == Method.SKEWNESS: elif method == Method.SKEWNESS:
self._plotWidget.show() self._plotWidget.show()
for i, plot in enumerate(self._plots): for i, plot in enumerate(self._plots):
...@@ -238,7 +254,13 @@ class GrainPlotWidget(qt.QMainWindow): ...@@ -238,7 +254,13 @@ class GrainPlotWidget(qt.QMainWindow):
plot.addImage(self._moments[i][3]) plot.addImage(self._moments[i][3])
elif method == Method.MOSAICITY: elif method == Method.MOSAICITY:
self._plotWidget.hide() self._plotWidget.hide()
self._mosaicityPlot.addImage(hsv_to_rgb(self._computeMosaicity())) if self.dataset.transformation:
self._mosaicityPlot.addImage(hsv_to_rgb(self._computeMosaicity()),
origin=self.origin, scale=self.scale,
xlabel='µm', ylabel='µm')
else:
self._mosaicityPlot.addImage(hsv_to_rgb(self._computeMosaicity()))
self._mosaicityPlot.show() self._mosaicityPlot.show()
def _opticolor(self, img, minc, maxc): def _opticolor(self, img, minc, maxc):
......
# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/
__authors__ = ["J. Garriga"]
__license__ = "MIT"
__date__ = "04/06/2021"
from silx.gui import qt
class MagnificationWidget(qt.QMainWindow):
"""
Widget to apply magnification transformation to the data axes.
"""
sigComputed = qt.Signal()
def __init__(self, parent=None):
qt.QWidget.__init__(self, parent)
widget = qt.QWidget()
layout = qt.QVBoxLayout()
self._checkbox2x = qt.QCheckBox("2x magnification")
self._checkbox10x = qt.QCheckBox("10x magnification")
self._checkboxManual = qt.QCheckBox("Manual magnification:")
self._manualLE = qt.QLineEdit(parent=self)
self._manualLE.setEnabled(False)
validator = qt.QDoubleValidator()
validator.setBottom(0)
self._manualLE.setValidator(validator)
self._okButton = qt.QPushButton("Ok")
self._okButton.setEnabled(False)
self._okButton.pressed.connect(self._saveMagnification)
layout.addWidget(self._checkbox2x)
layout.addWidget(self._checkbox10x)
layout.addWidget(self._checkboxManual)
layout.addWidget(self._manualLE)
layout.addWidget(self._okButton)
# self._okButton.pressed.connect(self._saveMagnification)
self._checkbox2x.stateChanged.connect(self._check2x)
self._checkbox10x.stateChanged.connect(self._check10x)
self._checkboxManual.stateChanged.connect(self._checkManual)
self._checkbox2x.setChecked(True)
widget.setLayout(layout)
self.setCentralWidget(widget)
def setDataset(self, dataset, indices=None, bg_indices=None, bg_dataset=None):
"""
Dataset setter.
:param Dataset dataset: dataset
"""
self.dataset = dataset
self.indices = indices
self.bg_indices = bg_indices
self.bg_dataset = bg_dataset
if not self.dataset.dims:
msg = qt.QMessageBox()
msg.setIcon(qt.QMessageBox.Warning)
msg.setText("This widget has to be used before selecting any region of \
interest and after selecting the dimensions")
msg.exec_()
else:
self._okButton.setEnabled(True)
def getDataset(self):
return self.dataset, self.indices, self.bg_indices, self.bg_dataset
def _checkManual(self, checked):
if checked:
self._checkbox2x.setChecked(False)
self._checkbox10x.setChecked(False)
self._manualLE.setEnabled(True)
else:
self._manualLE.setEnabled(False)
def _check2x(self, checked):
if checked:
self._checkbox10x.setChecked(False)
self._checkboxManual.setChecked(False)
self._manualLE.setEnabled(False)
def _check10x(self, checked):
if checked:
self._checkbox2x.setChecked(False)
self._checkboxManual.setChecked(False)
self._manualLE.setEnabled(False)
def _saveMagnification(self):
if self._checkbox2x.isChecked():
d = 3.75
elif self._checkbox10x.isChecked():
d = 0.75
else:
magnification = self._manualLE.text()
if magnification == "":
msg = qt.QMessageBox()
msg.setIcon(qt.QMessageBox.Warning)
msg.setText("Magnification value has to be entered when choosing manual")
msg.exec_()
return
self.dataset.compute_transformation(d)
self.sigComputed.emit()
# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/
__authors__ = ["J. Garriga"]
__license__ = "MIT"
__date__ = "04/06/2021"
from silx.gui import qt
from silx.utils.enum import Enum as _Enum
class PixelSize(_Enum):
"""
Different pixel sizes
"""
Basler = 0.051
PcoEdge_2x = 0.00375
PcoEdge_10x = 0.00075
class RSMWidget(qt.QMainWindow):
"""
Widget to compute Reciprocal Space Map