Commit 6c06b725 authored by payno's avatar payno

[metadata] use silx.io.fabioh5 module to get specific metadata values

parent 2337c8fb
......@@ -34,13 +34,28 @@ from id06workflow.core.geometry.TwoThetaGeometry import TwoThetaGeometry
from id06workflow.core.experiment.operation import _BaseOperation
from id06workflow.core.experiment.operation.roi import RoiOperation
from id06workflow.core.experiment.operation.datareduction import DataReduction
from collections import OrderedDict
from collections import OrderedDict, namedtuple
from silx.io.fabioh5 import FabioReader
from silx.io import fabioh5
import numpy
import logging
_logger = logging.getLogger(__file__)
_Dim = namedtuple('_Dim', ['name', 'size'])
# TODO: define dimension of the Experiment, with a get dim...
DEFAULT_METADATA = FabioReader.DEFAULT
COUNTER_METADATA = FabioReader.COUNTER
POSITIONER_METADATA = FabioReader.POSITIONER
_METADATA_TYPES = (DEFAULT_METADATA, COUNTER_METADATA, POSITIONER_METADATA)
class Experiment(object):
"""
Define all component of an experiment:
......@@ -95,6 +110,8 @@ class Experiment(object):
@property
def metadata(self):
if self.__metadata is None:
self.data
return self.__metadata
@property
......@@ -139,13 +156,14 @@ class Experiment(object):
return data_with_z_reduction[:, ::steps[1], ::steps[0]]
def _loadFileSeries(self, fileseries, z_step):
"""This will only deal with .edf file for now"""
data = []
headers = []
for iFrame in numpy.arange(start=0, stop=fileseries.nframes, step=z_step):
# TODO: deal with motors
frame = fileseries.getframe(iFrame)
data.append(frame.data)
headers.append(frame.header)
headers.append(fabioh5.EdfFabioReader(fabio_image=frame))
return numpy.asarray(data), headers
@property
......
......@@ -30,11 +30,13 @@ __date__ = "03/10/2018"
import unittest
from id06workflow.core.experiment.operation import OverwritingOperation, AdditiveOperation, shift
from id06workflow.core.experiment import Experiment, Dataset
from id06workflow.core.experiment import Experiment, Dataset, POSITIONER_METADATA
from id06workflow.core.utils import metadata as metadatautils
from id06workflow.test import utils
import shutil
import numpy
import tempfile
import os
class TestOperation(unittest.TestCase):
......@@ -123,7 +125,31 @@ class TestShift(unittest.TestCase):
class TestOperationStream(unittest.TestCase):
"""Test some default operation streaming"""
pass
def setUp(self):
unittest.TestCase.setUp(self)
root_folder = '/nobackup/linazimov/payno/datasets/id06/strain_scan'
data_file_pattern = os.path.join(root_folder, 'reduced_strain/strain_0000.edf')
data_bb_files = []
bb_folder = os.path.join(root_folder, 'bg_ff_5s_1x1')
for _file in os.listdir(bb_folder):
data_bb_files.append(os.path.join(bb_folder, _file))
self.dataset = Dataset(data_files_pattern=data_file_pattern,
ff_files=data_bb_files)
self.experiment = Experiment(dataset=self.dataset, geometry=None)
def applyGeometry(self):
"""Apply some geometry"""
pass
def testGeomtry(self):
"""Make sure geometry is well applied"""
self.assertTrue(len(metadatautils.getUnique(self.experiment,
kind=POSITIONER_METADATA,
key='diffry')) is 30)
self.assertTrue(len(metadatautils.getUnique(self.experiment,
kind=POSITIONER_METADATA,
key='obpitch')) is 4)
def suite():
......
# 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__ = ["H. Payno"]
__license__ = "MIT"
__date__ = "21/11/2018"
from id06workflow.core.experiment import Experiment
import numpy
import logging
_logger = logging.getLogger(__file__)
def getUnique(experiment, key, kind):
"""Return the set of (unique) value in all the headers
:param str key: the type of value we want
:param Dataset dataset: the dataset to treat
:return set: set of value
"""
assert isinstance(experiment, Experiment)
metadata = experiment.metadata
if metadata is None:
_logger.warning('no metadata found in the given experiment, unable to '
'unique value of %s' % key)
return set()
res = set()
for metadata_slice in experiment.metadata:
try:
value = metadata_slice.get_value(kind=kind, name=key)
assert isinstance(value, numpy.ndarray)
assert value.size is 1
res.add(value[0])
except Exception as e:
_logger.error("fail to load %s, %s cause %s" % (kind, key, e))
return res
......@@ -77,8 +77,13 @@ class DatasetSelection(qt.QTabWidget):
# expose API
self.getDataFilesPattern = self._dataFiles.getPattern
self.setDataFilesPattern = self._dataFiles.setPattern
self.getDarkFiles = self._darkFiles.getFiles
self.setDarkFiles = self._darkFiles.setFiles
self.addDarkFile = self._darkFiles.addFile
self.getFlatFieldFiles = self._ffFiles.getFiles
self.setFlatFieldFiles = self._ffFiles.setFiles
self.addFlatFieldFile = self._ffFiles.addFile
def getDataset(self):
"""
......@@ -144,6 +149,7 @@ class DataListWidget(qt.QWidget):
# expose API
self.getFiles = self.datalist.getFiles
self.setFiles = self.datalist.setFiles
self.addFile = self.datalist.add
def __getAddAndRmButtons(self):
lLayout = qt.QHBoxLayout()
......
......@@ -32,6 +32,9 @@ from silx.gui import qt
from id06workflow.core.geometry.TwoThetaGeometry import TwoThetaGeometry
from id06workflow.gui.utils import _IllustrationWidget
from id06workflow.core.utils.char import THETA_CHAR
import logging
_logger = logging.getLogger(__file__)
class GeometryMainWidget(qt.QWidget):
......@@ -81,6 +84,19 @@ class TwoThetaGeometryWidget(TwoThetaGeometry, qt.QWidget):
"""
Widget used to defined a TwoTheta experimental setup
"""
class DimensionComboBox(qt.QComboBox):
def __init__(self, parent, default=None, locked=None):
qt.QComboBox.__init__(self, parent)
for itemName in ('diffry', 'obpitch'):
self.addItem(itemName)
if default is not None:
idx = self.findText(default)
if idx >= 0:
self.setCurrentIndex(idx)
else:
_logger.warning('requested default value %s is not recognized' % default)
self.setEnabled(not locked)
def __init__(self, parent):
qt.QWidget.__init__(self, parent)
self.setLayout(qt.QGridLayout())
......@@ -113,6 +129,15 @@ class TwoThetaGeometryWidget(TwoThetaGeometry, qt.QWidget):
self.layout().addWidget(self._orientationCB, 4, 1)
# TODO: user should be able to save the configuration of the geometry
self.layout().addWidget(qt.QLabel('dim 1'), 5, 0)
self._dim1 = self.DimensionComboBox(parent=self, default='diffry',
locked=True)
self.layout().addWidget(self._dim1, 5, 1)
self.layout().addWidget(qt.QLabel('dim 2'), 6, 0)
self._dim2 = self.DimensionComboBox(parent=self, default='obpitch',
locked=True)
self.layout().addWidget(self._dim2, 6, 1)
def getSetupGeometry(self):
orientation = self._orientationCB.currentText()
assert orientation in TwoThetaGeometry.ORIENTATIONS
......
......@@ -33,7 +33,9 @@ from Orange.widgets.widget import OWWidget
from Orange.canvas.registry.description import OutputSignal
from id06workflow.gui.datasetselection import DatasetSelection
from id06workflow.core.experiment import Experiment
from Orange.widgets.settings import Setting
from silx.gui import qt
import os
import logging
_logger = logging.getLogger(__file__)
......@@ -56,6 +58,10 @@ class DataSelectionOW(OWWidget):
resizing_enabled = True
compress_signal = False
_data_file_pattern = Setting(str())
_flat_field_files = Setting(list())
_dark_files = Setting(list())
def __init__(self):
# TODO: add drag and drop stuff on it
super().__init__()
......@@ -77,6 +83,15 @@ class DataSelectionOW(OWWidget):
# expose API
self.setDataset = self._widget.setDataset
if os.path.isfile(self._data_file_pattern):
self._widget.setDataFilesPattern(self._data_file_pattern)
for _file in self._flat_field_files:
if os.path.isfile(_file):
self._widget.addFlatFieldFile(_file)
for _file in self._dark_files:
if os.path.isfile(_file):
self._widget.addDarkFile(_file)
def _process(self):
"""
Code executed when the dataset has been validated
......
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