Commit a5e92a11 authored by Carsten Richter's avatar Carsten Richter

Merge branch 'maxipix-correction' into 'master'

Maxipix correction

See merge request !69
parents d384e98b 8108b99f
Pipeline #4422 passed with stages
in 4 minutes and 41 seconds
......@@ -23,13 +23,6 @@ conversion from real space to qspace.
+--------------------+--------------------------------------------------------+
| Parameter / option |
+====================+========================================================+
| ``Binning`` | If checked and set to anything different that [1, 1] |
| | a binning will be applied to all images before |
| | conversion. |
| | |
| | This is the nav argument passed to |
| | xrayutilies' |xray_init_area|_ |
+--------------------+--------------------------------------------------------+
| ``Median filter`` | If checked and set to anything else than [1, 1] then a |
| | median filter will be applied to all images before |
| | conversion. |
......
......@@ -19,9 +19,6 @@ qspace_dims = (28, 154, 60)
# set disp_times to True if you want to output some info in stdout
QSpaceConverter.disp_times = True
# size of the averaging window to use when downsampling
image_binning = [4, 4]
# positions (on the sample) to convert to qspace
# if pos_indices will be ignored if rect_roi is provided
# rect_roi = [x_min, x_max, y_min, y_max] (sample positions)
......@@ -38,7 +35,6 @@ n_proc = None
kmap_2_qspace(xsocs_h5,
output_f,
qspace_dims,
image_binning=image_binning,
roi=roi,
n_proc=n_proc,
overwrite=overwrite)
......@@ -190,7 +190,6 @@ class XsocsGui(Qt.QMainWindow):
widget = QSpaceWidget(self.__project.xsocsFile,
outQSpaceH5=output_f,
qspaceDims=None,
imageBinning=None,
roi=event.roi,
entries=event.entries,
parent=self.sender(),
......
......@@ -53,12 +53,10 @@ class ConversionParamsWidget(Qt.QWidget):
"""
Widget for conversion parameters input :
- normalization counter
- image binning size
- median filter
- qspace dimensions
"""
def __init__(self,
imgBinning=None,
medfiltDims=None,
normalizers=None,
beamEnergy=None,
......@@ -69,7 +67,6 @@ class ConversionParamsWidget(Qt.QWidget):
layout = Qt.QGridLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
# imgBinning = np.array(imgBinning, ndmin=1)
# medfiltDims = np.array(medfiltDims, ndmin=1)
self.__mask = None # Currently selected mask array
......@@ -112,8 +109,13 @@ class ConversionParamsWidget(Qt.QWidget):
checkBox.setChecked(False)
return checkBox
# Maxipix correction
self.__maxipixCorrection = createCheckBox('1. Maxipix correction')
imgGboxLayout.addRow(self.__maxipixCorrection)
# Mask
self.__imgMaskCBox = createCheckBox('1. Mask')
self.__imgMaskCBox = createCheckBox('2. Mask')
self.__maskFileLineEdit = StyledLineEdit()
self.__maskFileLineEdit.setAlignment(Qt.Qt.AlignLeft)
......@@ -134,7 +136,7 @@ class ConversionParamsWidget(Qt.QWidget):
imgGboxLayout.addRow(self.__imgMaskCBox, maskLayout)
# Normalization
self.__imgNormCBox = createCheckBox('2. Normalization')
self.__imgNormCBox = createCheckBox('3. Normalization')
self.__normalizationComboBox = Qt.QComboBox()
self.__normalizationComboBox.setEnabled(False)
......@@ -145,34 +147,6 @@ class ConversionParamsWidget(Qt.QWidget):
self.__normalizationComboBox.addItems(normalizers)
imgGboxLayout.addRow(self.__imgNormCBox, self.__normalizationComboBox)
# Binnning
self.__imgBinCBox = createCheckBox('3. Binning')
inputBase = Qt.QWidget()
inputBase.setEnabled(False)
inputBase.setContentsMargins(0, 0, 0, 0)
imgBinLayout = Qt.QHBoxLayout(inputBase)
imgBinLayout.setContentsMargins(0, 0, 0, 0)
self.__imgBinCBox.toggled.connect(inputBase.setEnabled)
imgBinHEdit = StyledLineEdit(nChar=5)
imgBinHEdit.setValidator(Qt.QIntValidator(imgBinHEdit))
imgBinHEdit.setAlignment(Qt.Qt.AlignRight)
# imgBinHEdit.setText(str(imgBinning[0]))
imgBinVEdit = StyledLineEdit(nChar=5)
imgBinVEdit.setValidator(Qt.QIntValidator(imgBinVEdit))
imgBinVEdit.setAlignment(Qt.Qt.AlignRight)
# imgBinVEdit.setText(str(imgBinning[1]))
imgBinLayout.addWidget(Qt.QLabel('w='))
imgBinLayout.addWidget(imgBinHEdit)
imgBinLayout.addWidget(Qt.QLabel('h='))
imgBinLayout.addWidget(imgBinVEdit)
imgGboxLayout.addRow(self.__imgBinCBox, inputBase)
# Median filter
self.__medfiltCBox = createCheckBox('4. Median filter')
......@@ -201,10 +175,6 @@ class ConversionParamsWidget(Qt.QWidget):
imgGboxLayout.addRow(self.__medfiltCBox, inputBase)
# Mask and binning mutually exclusive
self.__imgMaskCBox.toggled.connect(self.__imgBinCBox.setDisabled)
self.__imgBinCBox.toggled.connect(self.__imgMaskCBox.setDisabled)
layout.addWidget(imageGbox)
# ===========
......@@ -236,8 +206,6 @@ class ConversionParamsWidget(Qt.QWidget):
dimLayout.addWidget(qDimsZEdit)
dimLayout.addStretch(1)
self.__imgBinHEdit = imgBinHEdit
self.__imgBinVEdit = imgBinVEdit
self.__medfiltHEdit = medfiltHEdit
self.__medfiltVEdit = medfiltVEdit
self.__qDimsXEdit = qDimsXEdit
......@@ -246,7 +214,6 @@ class ConversionParamsWidget(Qt.QWidget):
layout.addWidget(qspaceGbox)
self.setImageBinning(imgBinning)
self.setMedfiltDims(medfiltDims)
# ===========
......@@ -273,6 +240,13 @@ class ConversionParamsWidget(Qt.QWidget):
self.__maskFileLineEdit.setText(dialog.selectedUrl())
self.__mask = dialog.selectedImage()
def isMaxipixCorrectionEnabled(self):
"""Returns whether Maxipix correction is enabled or not.
:rtype: bool
"""
return self.__maxipixCorrection.isChecked()
def getMask(self):
"""Returns the selected mask image or None if not set
......@@ -348,41 +322,6 @@ class ConversionParamsWidget(Qt.QWidget):
self.__medfiltVEdit.setText(str(medfiltDims[1]))
self.__medfiltCBox.setChecked(not equal)
def getImageBinning(self):
"""
Returns the image binning dimensions, a 2 integers array, or None if
the image binning is not enabled.
:return:
"""
if not self.__imgBinCBox.isChecked():
return None
h_bin = self.__imgBinHEdit.text()
if len(h_bin) == 0:
h_bin = None
else:
h_bin = int(h_bin)
v_bin = self.__imgBinVEdit.text()
if len(v_bin) == 0:
v_bin = None
else:
v_bin = int(v_bin)
return [h_bin, v_bin]
def setImageBinning(self, imageBinning):
"""
Sets the image binning dimensions.
:param imageBinning: a 2 integers array.
:return:
"""
if imageBinning is None:
imageBinning = (1, 1)
imgBinning = np.array(imageBinning, ndmin=1)
equal = np.array_equal(imgBinning, [1, 1])
self.__imgBinHEdit.setText(str(imageBinning[0]))
self.__imgBinVEdit.setText(str(imageBinning[1]))
self.__imgBinCBox.setChecked(not equal)
def getQspaceDims(self):
"""
Returns the qspace dimensions, a 3 integers (> 1) array if set,
......@@ -452,7 +391,6 @@ class QSpaceWidget(Qt.QDialog):
xsocH5File,
outQSpaceH5,
qspaceDims=None,
imageBinning=None,
medfiltDims=None,
roi=None,
entries=None,
......@@ -465,10 +403,8 @@ class QSpaceWidget(Qt.QDialog):
:param xsocH5File: name of the input XsocsH5 file.
:param outQSpaceH5: name of the output hdf5 file
:param qspaceDims: dimensions of the qspace volume
:param imageBinning: binning to apply to the images before conversion.
Default : (1, 1)
:param medfiltDims: dimensions of the kernel used when applying a
a median filter to the images (after the binning, if any).
a median filter to the images (after the mask, if any).
Set to None or (1, 1) to disable the median filter.
:param roi: Roi in sample coordinates (xMin, xMax, yMin, yMax)
:param entries: a list of entry names to convert to qspace. If None,
......@@ -499,7 +435,6 @@ class QSpaceWidget(Qt.QDialog):
self.__converter = QSpaceConverter(xsocH5File,
output_f=outQSpaceH5,
qspace_dims=qspaceDims,
img_binning=imageBinning,
medfilt_dims=medfiltDims,
roi=roi,
entries=entries,
......@@ -622,7 +557,6 @@ class QSpaceWidget(Qt.QDialog):
channelsPerDegree = '', ''
self.__paramsWid = ConversionParamsWidget(
imgBinning=self.__converter.image_binning,
medfiltDims=self.__converter.medfilt_dims,
normalizers=xsocsH5.normalizers(),
beamEnergy=beamEnergy,
......@@ -696,23 +630,23 @@ class QSpaceWidget(Qt.QDialog):
return
normalizer = self.__paramsWid.getNormalizer()
imageBinning = self.__paramsWid.getImageBinning()
medfiltDims = self.__paramsWid.getMedfiltDims()
qspaceDims = self.__paramsWid.getQspaceDims()
beamEnergy = self.__paramsWid.getBeamEnergy()
directBeam = self.__paramsWid.getDirectBeam()
channelsPerDegree = self.__paramsWid.getChannelsPerDegree()
mask = self.__paramsWid.getMask()
maxipixCorrection = self.__paramsWid.isMaxipixCorrectionEnabled()
try:
converter.normalizer = normalizer
converter.image_binning = imageBinning
converter.medfilt_dims = medfiltDims
converter.qspace_dims = qspaceDims
converter.beam_energy = beamEnergy
converter.direct_beam = directBeam
converter.channels_per_degree = channelsPerDegree
converter.mask = mask
converter.maxipix_correction = maxipixCorrection
except ValueError as ex:
Qt.QMessageBox.critical(self, 'Error',
str(ex))
......
......@@ -368,6 +368,15 @@ class QSpaceInfoNode(Node):
children.append(roiNode)
##################################################
# Adding maxipix correction
##################################################
node = Node(nodeName='Maxipix correction')
node._setDataInternal(
ModelColumns.ValueColumn,
'Enabled' if qspaceH5.maxipix_correction else 'Disabled')
children.append(node)
##################################################
# Adding image normalization.
##################################################
......@@ -380,18 +389,15 @@ class QSpaceInfoNode(Node):
children.append(node)
##################################################
# Adding image binning.
# Adding image binning if available (deprecated)
##################################################
node = Node(nodeName='Image binning')
imageBinning = qspaceH5.image_binning
# support for previous versions
# TODO : remove eventualy
if imageBinning is None:
text = 'unavailable'
else:
if imageBinning is not None:
node = Node(nodeName='Image binning')
text = '{0}x{1}'.format(*imageBinning)
node._setDataInternal(ModelColumns.ValueColumn, text)
children.append(node)
node._setDataInternal(ModelColumns.ValueColumn, text)
children.append(node)
##################################################
# Adding medfilt.
......
......@@ -181,7 +181,7 @@ class QSpaceH5(XsocsH5Base):
Non-zero value means that the pixel is masked.
:rtype: Union[numpy.ndarray, None]
:rtype: Union[numpy.ndarray,None]
"""
return self._get_array_data(self.params_path + '/image_mask')
......@@ -189,15 +189,25 @@ class QSpaceH5(XsocsH5Base):
def image_normalizer(self):
"""Returns the image normalizer used when converting to q space.
:rtype: Union[str, None]
:rtype: Union[str,None]
"""
return self._get_array_data(self.params_path + '/image_normalizer')
@property
def image_binning(self):
def maxipix_correction(self):
"""Returns whether maxipix correction was enabled or not.
:rtype: Union[int,None]
"""
Returns the image binning used when converting to q space.
:return:
return self._get_scalar_data(self.params_path + '/maxipix_correction')
@property
def image_binning(self):
"""Returns the image binning used when converting to q space.
This is deprecated as no more created during conversion.
It is kept for displaying the information for files
produced with older version of xsocs.
"""
path = self.params_path + '/image_binning'
return self._get_array_data(path)
......@@ -205,9 +215,8 @@ class QSpaceH5(XsocsH5Base):
@property
def medfilt_dims(self):
"""
Returns the dimensions of the median filter applied after the image
binning when converting to q space.
:return:
Returns the dimensions of the median filter applied when
converting to q space.
"""
path = self.params_path + '/medfilt_dims'
return self._get_array_data(path)
......@@ -429,24 +438,12 @@ class QSpaceH5Writer(QSpaceH5):
path = self.params_path + '/image_normalizer'
self._create_dataset(path, data=text_type(normalizer))
def set_image_binning(self, image_binning):
"""
Stores the image binning used when converting to q space
:param image_binning: a 2 elements array.
:return:
"""
path = self.params_path + '/image_binning'
if image_binning is None or len(image_binning) != 2:
raise ValueError('image_binning must be a 2 elements array : '
'{0}.'.format(image_binning))
self._set_array_data(path, _np.array(image_binning))
def set_medfilt_dims(self, medfilt_dims):
"""
Stores the dimensions of the median filter applied after the image
binning when converting to q space.
Stores the dimensions of the median filter applied when
converting to q space.
:param medfilt_dims: a 2 elements array.
:return:
"""
path = self.params_path + '/medfilt_dims'
if medfilt_dims is None or len(medfilt_dims) != 2:
......@@ -497,6 +494,10 @@ class QSpaceH5Writer(QSpaceH5):
'{0}.'.format(channels_per_degree))
self._set_array_data(path, _np.array(channels_per_degree))
def set_maxipix_correction(self, enabled):
"""Stores whether maxipix correction was used or not
if __name__ == '__main__':
pass
:param bool enabled:
"""
path = self.params_path + '/maxipix_correction'
self._set_scalar_data(path, int(1 if enabled else 0))
This diff is collapsed.
......@@ -36,7 +36,6 @@ from .QSpaceConverter import QSpaceConverter
def kmap_2_qspace(xsocsH5_f,
output_f,
qspace_dims,
image_binning=(4, 4),
roi=None,
n_proc=None,
overwrite=False):
......@@ -56,10 +55,6 @@ def kmap_2_qspace(xsocsH5_f,
named 'qspace.h5'. This file will be overwritten if it already exists.
:type output_f: *optional* str
:param image_binning: size of the averaging window to use when downsampling
the images (TODO : rephrase)
:type image_binning: *optional* `array_like`
:param roi: rectangular region which will be converted to qspace.
This must be a four elements array containing x_min, x_max, y_min,
y_max.
......@@ -75,14 +70,11 @@ def kmap_2_qspace(xsocsH5_f,
"""
converter = QSpaceConverter(xsocsH5_f,
qspace_dims,
img_binning=image_binning,
output_f=output_f)
if roi is not None:
converter.roi = roi
converter.image_binning = image_binning
converter.n_proc = n_proc
converter.convert(overwrite=overwrite)
......
......@@ -77,13 +77,11 @@ class TestQSpace(ParametricTestCase):
master_f = manager.get_file('merged/test.h5')
keys = ['output_f', 'img_binning', 'medfilt_dims', 'mask']
keys = ['output_f', 'medfilt_dims', 'mask']
parameters = [
('qspace_1.h5', None, None, None),
('qspace_2.h5', [4, 4], None, None),
('qspace_3.h5', None, [3, 3], None),
('qspace_4.h5', [4, 4], [3, 3], None),
('qspace_5.h5', None, None, 'mask.npy')
('qspace_1.h5', None, None),
('qspace_3.h5', [3, 3], None),
('qspace_5.h5', None, 'mask.npy')
]
param_dicts = [dict(zip(keys, params)) for params in parameters]
......@@ -93,7 +91,6 @@ class TestQSpace(ParametricTestCase):
converter = QSpaceConverter(master_f,
qspace_dims=[28, 154, 60],
img_binning=params['img_binning'],
medfilt_dims=params['medfilt_dims'],
output_f=output_f)
self.assertEqual(converter.status, converter.READY)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment