diff --git a/doc/app/canvas.rst b/doc/app/canvas.rst new file mode 100644 index 0000000000000000000000000000000000000000..4da68318b630ec4da3de690ab5bcf71c098c68d3 --- /dev/null +++ b/doc/app/canvas.rst @@ -0,0 +1,26 @@ +canvas +====== + +Purpose +------- + +*est canvas* is the command to launch canvas used for defining workflows. +This is a proxy to *orange-canvas* command. + +.. image:: img/canvas.png + :width: 600 px + :align: center + + +Usage +----- + +:: + est canvas [[workflow-file]] + +Examples of usage +----------------- + +.. code-block:: bash + + est canvas my_workflow.ows diff --git a/doc/app/img/canvas.png b/doc/app/img/canvas.png new file mode 100644 index 0000000000000000000000000000000000000000..ed6991845ff5f0f2bd0362d09db5239879d9dacc Binary files /dev/null and b/doc/app/img/canvas.png differ diff --git a/doc/app/img/xas_viewer.png b/doc/app/img/xas_viewer.png new file mode 100644 index 0000000000000000000000000000000000000000..d3a4a387c24a46f17855075030dcd07d9bf2a54a Binary files /dev/null and b/doc/app/img/xas_viewer.png differ diff --git a/doc/app/index.rst b/doc/app/index.rst index cb26bc8ac1954831fc771fda700d65c21c7a11cf..251a7f62300f0a6f98823eed9a62ac25c41ed97d 100644 --- a/doc/app/index.rst +++ b/doc/app/index.rst @@ -6,5 +6,8 @@ Applications .. toctree:: :maxdepth: 1 + canvas + ows_to_script process reprocessing + xas_viewer diff --git a/doc/app/ows_to_script.rst b/doc/app/ows_to_script.rst new file mode 100644 index 0000000000000000000000000000000000000000..b48d6e6e9453c17a3fe076277c831a1d4b5b5d68 --- /dev/null +++ b/doc/app/ows_to_script.rst @@ -0,0 +1,25 @@ +ows-to-script +============= + +Purpose +------- + +*est ows-to-script* is the command to convert a .ows file (workflow file) to a python script + + +Usage +----- + +.. code-block:: bash + + est ows-to-script [ows-file.ows] [output-file.py] [[--overwrite]] + +Examples of usage +----------------- + +.. code-block:: bash + + # convert the file + est ows-to-script workflow-file.ows output_script.py + # execute the file + python output_script.py --input-spectra "silx:///[...]B33_test_1.h5?path=/data" --input-channel "silx:///[...]B33_test_1.h5?path=/energy" diff --git a/doc/app/process.rst b/doc/app/process.rst index 357a69a81793f96360be4ca801418a00fab3c0ab..2d858aa6e1ffb422cce7547d26f34e2190c57bc9 100644 --- a/doc/app/process.rst +++ b/doc/app/process.rst @@ -1,5 +1,5 @@ process -------- +======= You can use the workflow definition from a .ows (orange) file with it configuration to process different spectra. diff --git a/doc/app/reprocessing.rst b/doc/app/reprocessing.rst index 666addc3b55bbc9146e52c0edcf91a4c7fbaecb6..af9aa0cfca8d75d89bccaf23638420c174ce97ab 100644 --- a/doc/app/reprocessing.rst +++ b/doc/app/reprocessing.rst @@ -1,5 +1,5 @@ reprocessing ------------- +============ A file containing information about raw data and est process flow (output file generated by est output orange widget for example) can diff --git a/doc/app/xas_viewer.rst b/doc/app/xas_viewer.rst new file mode 100644 index 0000000000000000000000000000000000000000..da423efdebd1a3c7893049563be7e0a6611307f0 --- /dev/null +++ b/doc/app/xas_viewer.rst @@ -0,0 +1,32 @@ +xas-viewer +========== + +Purpose +------- + +*est xas-viewer* is the command to launch a simple viewer of spectroscopy data + +.. image:: img/xas_viewer.png + :width: 600 px + :align: center + + +Usage +----- + +.. code-block:: bash + + est xas-viewer [[--input --input-spectra-url]] + +Examples of usage +----------------- + +.. code-block:: bash + + # from a simple ASCII file: + est xas-viewer --input EXAFS_Cu.dat + # from a hdf5 file using the '@' syntax + est xas-viewer --input-spectra data@B33_test_1.h5 --input-channel energy@B33_test_1.h5 + # from a hdf5 file using silx DataUrl + est xas-viewer --input-spectra "silx:///[...]B33_test_1.h5?path=/data" --input-channel "silx:///[...]B33_test_1.h5?path=/energy" + diff --git a/est/__main__.py b/est/__main__.py index 6ead0dc43f8917dab122d3fa2646daaa6321f330..a5f987d6e51ac4d7363913df0bc6b3dc21f57cbd 100644 --- a/est/__main__.py +++ b/est/__main__.py @@ -80,6 +80,12 @@ def main(): launcher.add_command( "test", module_name="est.app.test_", description="Launch est unittest" ) + launcher.add_command( + "ows-to-script", + module_name="est.app.ows_to_script", + description="Convert a .ows file to python script", + ) + status = launcher.execute(sys.argv) return status diff --git a/est/app/ows_to_script.py b/est/app/ows_to_script.py new file mode 100644 index 0000000000000000000000000000000000000000..9281ce6bf32afeb5fab83609965db68476888043 --- /dev/null +++ b/est/app/ows_to_script.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import logging +import sys +import argparse +from pypushflow.representation.scheme.ows_parser import OwsParser +from pypushflow import Workflow +import est.version +import pypushflow.version +import os + +logging.basicConfig(level=logging.DEBUG) +_logger = logging.getLogger(__name__) + + +def _convert(scheme, output_file, overwrite): + """ + + :param scheme: + :param scan: + :param timeout: + :return: + """ + _logger.warning("translate {} to {}".format(scheme, output_file)) + + if os.path.exists(output_file): + if overwrite is True: + os.remove(output_file) + else: + raise ValueError("{} already exists.".format(output_file)) + + with open(output_file, "w+") as file_: + file_.write(_dump_info_generation()) + + workflow = Workflow.ProcessableWorkflow(scheme) + converter = Workflow.Converter(workflow=workflow, output_file=output_file) + converter.process() + + # set up workflow + with open(output_file, mode="a") as file_: + file_.write(_dump_executable_script_section()) + _logger.info( + "translation finished. You can execute python {} [[--input --input-spectra --input-spectra-dims --input-channel --input-energy-unit --input-dimensions]]".format( + output_file + ) + ) + + +def _dump_info_generation(): + return ( + "# This file has been generated automatically using \n" + "# pypushflow {} and est {}\n".format( + pypushflow.version.version, est.version.version + ) + ) + + +def _dump_executable_script_section(): + return """ + +from pypushflow.utils import IgnoreProcess + +if __name__ == '__main__': + import sys + import argparse + from est.app.utils import get_xas_obj + from est.app.utils import get_url + from est.app.utils import get_unit + from est.app.utils import convert_spectra_dims + from silx.io.url import DataUrl + + parser = argparse.ArgumentParser(description=__doc__) + + # single file input option + parser.add_argument( + "-i", + "--input", + dest="input_", + default=None, + help="Input of the workflow. Should be a path to a file", + ) + # input url option + parser.add_argument( + "--input-spectra", + dest="input_spectra", + default=None, + help="Input spectra url", + ) + parser.add_argument( + "--input-spectra-dims", + dest="input_spectra_dims", + default=None, + help="Input spectra dimension. Should be a tuple of three values: " + "(X,Y,channel). If None will take the default dimension " + "according to the input type.", + ) + parser.add_argument( + "--input-channel", + dest="input_channel", + default=None, + help="Input channel url (usually energy)", + ) + parser.add_argument( + "--input-configuration", + dest="input_configuration", + default=None, + help="Input configuration url", + ) + parser.add_argument( + "--input-energy-unit", + dest="input_energy_unit", + default="eV", + help="energy unit", + ) + parser.add_argument( + "--input-dimensions", + dest="input_dimensions", + default="None", + help="dimension of the input as (channel, Y, X) for example." + "If None will take default unit according to the input type", + ) + options = parser.parse_args(sys.argv[1:]) + + xas_obj = get_xas_obj(input_energy_unit=get_unit(options.input_energy_unit), + input_=options.input_, + input_spectra_url=get_url(options.input_spectra), + input_dims=convert_spectra_dims(options.input_spectra_dims), + input_channel_url=get_url(options.input_channel), + input_configuration_url=get_url(options.input_configuration) + ) + main(input_data=xas_obj, channel="xas_obj") + """ + + +def main(argv): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "workflow_file", + help="Path to the .ows file defining the workflow to process with the" + "provided scan", + ) + parser.add_argument("output_file", help="Output python file") + parser.add_argument( + "--overwrite", + help="Overwrite output file if exists", + default=False, + action="store_true", + ) + parser.add_argument( + "--debug", + dest="debug", + action="store_true", + default=False, + help="Set logging system in debug mode", + ) + options = parser.parse_args(argv[1:]) + if not options.output_file.lower().endswith(".py"): + options.output_file = options.output_file + ".py" + # tune the log level + log_level = logging.INFO + if options.debug is True: + log_level = logging.DEBUG + + for log_ in ("est", "pypushflow"): + logging.getLogger(log_).setLevel(log_level) + + scheme = OwsParser.scheme_load(options.workflow_file, load_handlers=True) + _convert( + scheme=scheme, output_file=options.output_file, overwrite=options.overwrite + ) + + +if __name__ == "__main__": + main(sys.argv) +# convert an ows file to a script calling est low level processes. diff --git a/est/app/process.py b/est/app/process.py index cd5885069db639bd0d798508665009a73fb4a0b6..f032cfb2539969d9465d100a0cc9c720ef31d487 100644 --- a/est/app/process.py +++ b/est/app/process.py @@ -2,16 +2,6 @@ import argparse import sys from pypushflow.Workflow import ProcessableWorkflow from pypushflow.representation.scheme.ows_parser import OwsParser - -try: - from est.io.utils.pymca import read_spectrum - - has_read_spectrum = True -except ImportError: - has_read_spectrum = False -from est.core.types import Spectrum, XASObject -from est.core.io import read_xas -from est.core.types import Dim import logging import signal from pypushflow.representation.scheme.scheme import Scheme @@ -19,7 +9,8 @@ from silx.io.url import DataUrl from est.units import ur from .utils import get_unit from .utils import get_url -from .utils import _convert_spectra_dims +from .utils import convert_spectra_dims +from .utils import get_xas_obj try: import h5py @@ -114,28 +105,14 @@ def exec_( signal.signal(signal.SIGINT, signal_handler) - if input_ is not None: - if input_dims is None: - input_dims = (Dim.X_DIM, Dim.Y_DIM) - if has_read_spectrum: - energy, mu = read_spectrum( - input_, energy_unit=input_energy_unit, dimensions=input_dims - ) - spectrum = Spectrum(energy=energy, mu=mu) - xas_obj = XASObject(energy=energy, spectra=(spectrum,), dim1=1, dim2=1) - else: - raise ValueError("Unable to read spectrum") - else: - if input_dims is None: - input_dims = (Dim.CHANNEL_ENERGY_DIM, Dim.Y_DIM, Dim.Y_DIM) - sp, en, conf = read_xas( - spectra_url=input_spectra_url, - channel_url=input_channel_url, - config_url=input_configuration_url, - dimensions=input_dims, - energy_unit=input_energy_unit, - ) - xas_obj = XASObject(spectra=sp, energy=en, configuration=conf) + xas_obj = get_xas_obj( + input_energy_unit=input_energy_unit, + input_=input_, + input_spectra_url=input_spectra_url, + input_dims=input_dims, + input_channel_url=input_channel_url, + input_configuration_url=input_configuration_url, + ) workflow._start_actor.trigger(("data", xas_obj.to_dict())) workflow._end_actor.join(timeout) @@ -215,7 +192,7 @@ def main(argv): scheme=scheme, input_=options.input_, input_spectra_url=get_url(options.input_spectra), - input_dims=_convert_spectra_dims(options.input_spectra_dims), + input_dims=convert_spectra_dims(options.input_spectra_dims), input_channel_url=get_url(options.input_channel), input_configuration_url=get_url(options.input_configuration), output_=options.output_, diff --git a/est/app/utils/__init__.py b/est/app/utils/__init__.py index c1f28ec6876f3790489d92a8fa8c90bd02bf11df..bdded6568d6b0f51741fd472d8694e4db8c644e8 100644 --- a/est/app/utils/__init__.py +++ b/est/app/utils/__init__.py @@ -31,9 +31,19 @@ __date__ = "10/12/2020" from silx.io.url import DataUrl from est.units import ur from est.core.types import Dim +from typing import Union +from est.core.types import Spectrum, XASObject +from est.core.io import read_xas +try: + from est.io.utils.pymca import read_spectrum -def _convert_spectra_dims(dims): + has_read_spectrum = True +except ImportError: + has_read_spectrum = False + + +def convert_spectra_dims(dims): """ Convert a tuple of dims that can be strings... to a tuple of est.core.types.Dim @@ -96,3 +106,36 @@ def get_url(my_str): else: return url raise ValueError("unrecognized url {}".format(my_str)) + + +def get_xas_obj( + input_energy_unit=ur.eV, + input_: Union[str, None, dict] = None, + input_spectra_url: Union[None, DataUrl] = None, + input_dims: Union[None, tuple] = None, + input_channel_url: Union[None, DataUrl] = None, + input_configuration_url: Union[None, DataUrl] = None, +): + """load xas object from command line input""" + if input_ is not None: + if input_dims is None: + input_dims = (Dim.X_DIM, Dim.Y_DIM) + if has_read_spectrum: + energy, mu = read_spectrum( + input_, energy_unit=input_energy_unit, dimensions=input_dims + ) + spectrum = Spectrum(energy=energy, mu=mu) + return XASObject(energy=energy, spectra=(spectrum,), dim1=1, dim2=1) + else: + raise ValueError("Unable to read spectrum") + else: + if input_dims is None: + input_dims = (Dim.CHANNEL_ENERGY_DIM, Dim.Y_DIM, Dim.Y_DIM) + sp, en, conf = read_xas( + spectra_url=input_spectra_url, + channel_url=input_channel_url, + config_url=input_configuration_url, + dimensions=input_dims, + energy_unit=input_energy_unit, + ) + return XASObject(spectra=sp, energy=en, configuration=conf) diff --git a/est/app/xas_viewer.py b/est/app/xas_viewer.py index 8d65b55ff2016ed538aefade129b04e08b94c381..a9b7eaa502d9c5f12225b695b18802b7c9c8d740 100644 --- a/est/app/xas_viewer.py +++ b/est/app/xas_viewer.py @@ -7,7 +7,7 @@ import sys from est.gui.xas_object_definition import XASObjectWindow from .utils import get_unit from .utils import get_url -from .utils import _convert_spectra_dims +from .utils import convert_spectra_dims from silx.gui import qt from est.core.types import Dim @@ -80,7 +80,7 @@ def main(argv): _plot( input_=options.input_, input_spectra_url=get_url(options.input_spectra), - input_spectra_dims=_convert_spectra_dims(options.input_spectra_dims), + input_spectra_dims=convert_spectra_dims(options.input_spectra_dims), input_channel_url=get_url(options.input_channel), input_energy_unit=get_unit(options.input_energy_unit), ) diff --git a/est/core/process/io.py b/est/core/process/io.py index 5ca7167626937f92a33aa808350420bfa40d300d..06f391ec2436687fd47960e094e318b012ab70ca 100644 --- a/est/core/process/io.py +++ b/est/core/process/io.py @@ -30,10 +30,21 @@ __date__ = "06/11/2019" from .process import Process from est.core.types import XASObject +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc import pkg_resources class DumpXasObject(Process): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): super().__init__(name="dump xas object") self._output_file = None diff --git a/est/core/process/larch/autobk.py b/est/core/process/larch/autobk.py index 22c5f42fc5b54110296fb22dc85e3b58e9292605..620d307b1d47c6c26b3118d9d06cbdbeaf09d59f 100644 --- a/est/core/process/larch/autobk.py +++ b/est/core/process/larch/autobk.py @@ -26,6 +26,8 @@ from est.core.types import Spectrum, XASObject from est.core.process.process import Process +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from larch.xafs.autobk import autobk import multiprocessing import functools @@ -134,6 +136,15 @@ _USE_MULTIPROCESSING_POOL = False class Larch_autobk(Process): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): Process.__init__(self, name="autobk") diff --git a/est/core/process/larch/mback.py b/est/core/process/larch/mback.py index a8e77ec11f45cf0ba76b0a76c1e6d82837ed3d59..e6f7be960046504d3367012bbb2341a23e5bff94 100644 --- a/est/core/process/larch/mback.py +++ b/est/core/process/larch/mback.py @@ -26,6 +26,8 @@ from est.core.types import Spectrum, XASObject from est.core.process.process import Process +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from larch.xafs.mback import mback import multiprocessing import functools @@ -123,6 +125,15 @@ _USE_MULTIPROCESSING_POOL = False class Larch_mback(Process): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): Process.__init__(self, name="mback") diff --git a/est/core/process/larch/mback_norm.py b/est/core/process/larch/mback_norm.py index c06f53b736dbb195bb1a8da67c7483f0b6553f62..b0ec3d8db41d0fa387dca1dc4bf748616ae212e3 100644 --- a/est/core/process/larch/mback_norm.py +++ b/est/core/process/larch/mback_norm.py @@ -26,6 +26,8 @@ from est.core.types import Spectrum, XASObject from est.core.process.process import Process +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from larch.xafs.mback import mback_norm from larch.xafs.pre_edge import preedge import multiprocessing @@ -132,6 +134,15 @@ _USE_MULTIPROCESSING_POOL = False class Larch_mback_norm(Process): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): Process.__init__(self, name="mback_norm") diff --git a/est/core/process/larch/pre_edge.py b/est/core/process/larch/pre_edge.py index 0d5aa6024521f718007a9ef85779f250548d3b00..f75d9c9a0661b6d58bdb04fe670c5e3d27b5a109 100644 --- a/est/core/process/larch/pre_edge.py +++ b/est/core/process/larch/pre_edge.py @@ -26,6 +26,8 @@ from est.core.types import Spectrum, XASObject from est.core.process.process import Process +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from larch.xafs.pre_edge import pre_edge import multiprocessing import functools @@ -121,6 +123,15 @@ _USE_MULTIPROCESSING_POOL = False class Larch_pre_edge(Process): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): Process.__init__(self, name="pre_edge") diff --git a/est/core/process/larch/xftf.py b/est/core/process/larch/xftf.py index f4c12b6c27603fb4137e3606c322a1abddb8ba23..dd6aab81c2a3a13b39f3e3e6479787f04b81ed0f 100644 --- a/est/core/process/larch/xftf.py +++ b/est/core/process/larch/xftf.py @@ -26,6 +26,8 @@ from est.core.types import Spectrum, XASObject from est.core.process.process import Process +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from larch.xafs.xafsft import xftf import multiprocessing import functools @@ -124,6 +126,15 @@ _USE_MULTIPROCESSING_POOL = False class Larch_xftf(Process): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): Process.__init__(self, name="xftf") diff --git a/est/core/process/process.py b/est/core/process/process.py index 1471b3cb2b9b5639c57faec62468f5461e4c29ea..ad24353e9a298c27d773ffdf1e161c91fcf52c47 100644 --- a/est/core/process/process.py +++ b/est/core/process/process.py @@ -32,16 +32,15 @@ __date__ = "07/08/2019" from .progress import Progress from est.core.types import XASObject import logging -import pint +from collections import namedtuple from typing import Iterable _logger = logging.getLogger(__name__) -_DEBUG = True -if _DEBUG: - from est.core.types import Spectrum - import numpy +_input_desc = namedtuple("_input_desc", ["name", "type", "handler", "doc"]) + +_output_desc = namedtuple("_output_desc", ["name", "type", "doc"]) class Process(object): diff --git a/est/core/process/pymca/exafs.py b/est/core/process/pymca/exafs.py index 2bdc57dd5e759e785719c6cc3882047c42cc7cc3..8ca2f8a6aae14799922edf19ff76d16f0f18f3a6 100644 --- a/est/core/process/pymca/exafs.py +++ b/est/core/process/pymca/exafs.py @@ -34,7 +34,8 @@ import multiprocessing import numpy from PyMca5.PyMcaPhysics.xas.XASClass import XASClass from PyMca5.PyMcaPhysics.xas.XASClass import e2k, k2e - +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from est.core.process.process import Process from est.core.types import XASObject, Spectrum @@ -147,6 +148,14 @@ class PyMca_exafs(Process): """Process spectra for exafs and get information about the processing advancement""" + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): Process.__init__(self, name="exafs") diff --git a/est/core/process/pymca/ft.py b/est/core/process/pymca/ft.py index a7dbd0519c4cd131ad647e241cfee6d04fe57f92..9f7799df2972f641748d9f9ad6e3a1e554ba0484 100644 --- a/est/core/process/pymca/ft.py +++ b/est/core/process/pymca/ft.py @@ -33,7 +33,8 @@ import multiprocessing import numpy from PyMca5.PyMcaPhysics.xas.XASClass import XASClass - +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from est.core.process.process import Process from est.core.types import XASObject, Spectrum @@ -149,6 +150,15 @@ _USE_MULTIPROCESSING_POOL = False class PyMca_ft(Process): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): Process.__init__(self, name="ft") diff --git a/est/core/process/pymca/k_weight.py b/est/core/process/pymca/k_weight.py index 10a7de2d7d7294de88f7b98e6c13667615a7f791..88b11671235cfb13dc4118787d12803a732bc1fc 100644 --- a/est/core/process/pymca/k_weight.py +++ b/est/core/process/pymca/k_weight.py @@ -32,7 +32,8 @@ import logging import multiprocessing from PyMca5.PyMcaPhysics.xas.XASClass import XASClass, e2k - +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from est.core.process.process import Process from est.core.process.pymca.exafs import process_spectr_exafs from est.core.types import XASObject, Spectrum @@ -139,6 +140,15 @@ _USE_MULTIPROCESSING_POOL = False class PyMca_k_weight(Process): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): Process.__init__(self, name="k weight") diff --git a/est/core/process/pymca/normalization.py b/est/core/process/pymca/normalization.py index 50e9dd01a4c67f6d122c4cc736590e6102373682..90cdc05c6ad5a81c16d3bd96f209d8f8850b52a9 100644 --- a/est/core/process/pymca/normalization.py +++ b/est/core/process/pymca/normalization.py @@ -31,9 +31,9 @@ __date__ = "06/11/2019" import functools import logging import multiprocessing - from PyMca5.PyMcaPhysics.xas.XASClass import XASClass - +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from est.core.process.process import Process, Progress from est.core.types import Spectrum, XASObject @@ -124,6 +124,15 @@ _USE_MULTIPROCESSING_POOL = False class PyMca_normalization(Process): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self): Process.__init__(self, "normalization") self._advancement = Progress(self.name) diff --git a/est/core/process/roi.py b/est/core/process/roi.py index 6b2d5023143439edf760a87e798aebb7bbab3642..9657d148475a12c73778854a55dc07af0dfdbb2e 100644 --- a/est/core/process/roi.py +++ b/est/core/process/roi.py @@ -30,6 +30,8 @@ __date__ = "06/11/2019" from est.core.types import XASObject from est.core.types import Spectrum from est.core.types import Spectra +from est.core.process.process import _input_desc +from est.core.process.process import _output_desc from .process import Process import logging import numpy @@ -53,6 +55,15 @@ def xas_roi(xas_obj): class _ROI(object): + + inputs = [ + _input_desc(name="xas_obj", type=XASObject, handler="process", doc=""), + ] + + outputs = [ + _output_desc(name="xas_obj", type=XASObject, doc=""), + ] + def __init__(self, origin, size): self.origin = origin self.size = size diff --git a/est/gui/XasObjectViewer.py b/est/gui/XasObjectViewer.py index e5288e5c55046e8e4bc90427cc553316207cec5d..bbe941f54c626776ae24bba1e3b4a315a54e58b8 100644 --- a/est/gui/XasObjectViewer.py +++ b/est/gui/XasObjectViewer.py @@ -241,10 +241,8 @@ class MapViewer(qt.QWidget): if self._xasObj is None: return # set the map view - spectra_volume = XASObject._spectra_volume( + spectra_volume = self._xasObj.spectra.map_to( spectra=self._xasObj.spectra, - dim_1=self._xasObj.dim1, - dim_2=self._xasObj.dim2, key=self.getActiveKey(), ) self._mainWindow.setStack(spectra_volume) @@ -321,7 +319,7 @@ class _RawDataList(qt.QTableWidget): for i_row, (x_value, y_value) in enumerate(zip(x, y)): x_item = qt.QTableWidgetItem() - x_item.setText(str(x_value.m)) + x_item.setText(str(x_value)) self.setItem(i_row, 0, x_item) y_item = qt.QTableWidgetItem() y_item.setText(str(y_value)) @@ -389,10 +387,10 @@ class SpectrumViewer(qt.QMainWindow): if self.xas_obj is None: self._plotWidget.clear() else: - assert self.xas_obj.dim1 >= 0 - assert self.xas_obj.dim2 >= 0 - self._dim1FrameBrowser.setRange(0, self.xas_obj.dim1 - 1) - self._dim2FrameBrowser.setRange(0, self.xas_obj.dim2 - 1) + assert self.xas_obj.spectra.shape[0] >= 0 + assert self.xas_obj.spectra.shape[1] >= 0 + self._dim1FrameBrowser.setRange(0, self.xas_obj.spectra.shape[0] - 1) + self._dim2FrameBrowser.setRange(0, self.xas_obj.spectra.shape[1] - 1) self._updateSpectrumDisplayed() def _updateSpectrumDisplayed(self, *args, **kwargs): diff --git a/orangecontrib/est/widgets/larch/autobk.py b/orangecontrib/est/widgets/larch/autobk.py index 523aa96c0b5ecd51740fceb4d6e937141a0d4b5e..133be259a7663912f2a0935a1bbb90362a662120 100644 --- a/orangecontrib/est/widgets/larch/autobk.py +++ b/orangecontrib/est/widgets/larch/autobk.py @@ -60,8 +60,10 @@ class AutobkWindow(qt.QMainWindow): # xas object viewer mapKeys = ["mu", "bkg", "chie", "k", "chi", "e0"] self.xasObjViewer = XasObjectViewer(mapKeys=mapKeys) - self.xasObjViewer._spectrumViews[0]._plot.getXAxis().setLabel("Energy (eV)") - self.xasObjViewer._spectrumViews[0]._plot.getYAxis().setLabel( + self.xasObjViewer._spectrumViews[0]._plotWidget.getXAxis().setLabel( + "Energy (eV)" + ) + self.xasObjViewer._spectrumViews[0]._plotWidget.getYAxis().setLabel( "Absorption (a.u.)" ) self.setCentralWidget(self.xasObjViewer) @@ -78,7 +80,7 @@ class AutobkWindow(qt.QMainWindow): # legend selector self.legendDockWidget = LegendSelector.LegendsDockWidget( - parent=self, plot=self.xasObjViewer._spectrumViews[0]._plot + parent=self, plot=self.xasObjViewer._spectrumViews[0]._plotWidget ) self.legendDockWidget.setAllowedAreas( qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea @@ -104,7 +106,7 @@ class AutobkWindow(qt.QMainWindow): self._updateLegendView() def getNCurves(self): - return len(self.xasObjViewer._spectrumViews[0]._plot.getAllCurves()) + return len(self.xasObjViewer._spectrumViews[0]._plotWidget.getAllCurves()) def _updateLegendView(self): index, viewType = self.xasObjViewer.getViewType() diff --git a/orangecontrib/est/widgets/larch/mback.py b/orangecontrib/est/widgets/larch/mback.py index 59de6e36113daf5061c569c6d64c7f2955a0d4bd..c930271729f5f82c61a3bf059a0e20069667d1cc 100644 --- a/orangecontrib/est/widgets/larch/mback.py +++ b/orangecontrib/est/widgets/larch/mback.py @@ -60,7 +60,9 @@ class MbackWindow(qt.QMainWindow): # xas object viewer mapKeys = ["mu", "fpp", "f2"] self.xasObjViewer = XasObjectViewer(mapKeys=mapKeys) - self.xasObjViewer._spectrumViews[0]._plot.getXAxis().setLabel("Energy (eV)") + self.xasObjViewer._spectrumViews[0]._plotWidget.getXAxis().setLabel( + "Energy (eV)" + ) self.setCentralWidget(self.xasObjViewer) self._parametersWindow = _ParameterWindowContainer( parent=self, parametersWindow=_MBackParameters @@ -75,7 +77,7 @@ class MbackWindow(qt.QMainWindow): # legend selector self.legendDockWidget = LegendSelector.LegendsDockWidget( - parent=self, plot=self.xasObjViewer._spectrumViews[0]._plot + parent=self, plot=self.xasObjViewer._spectrumViews[0]._plotWidget ) self.legendDockWidget.setAllowedAreas( qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea @@ -108,7 +110,7 @@ class MbackWindow(qt.QMainWindow): ) def getNCurves(self): - return len(self.xasObjViewer._spectrumViews[0]._plot.getAllCurves()) + return len(self.xasObjViewer._spectrumViews[0]._plotWidget.getAllCurves()) class MbackOW(_ProcessForOrangeMixIn, OWWidget): diff --git a/orangecontrib/est/widgets/larch/mback_norm.py b/orangecontrib/est/widgets/larch/mback_norm.py index e96cde36ceea1555bd6cccf8b09529fa8ed1cf1b..6868f2d1faa31285732174b92d1812849c508f40 100644 --- a/orangecontrib/est/widgets/larch/mback_norm.py +++ b/orangecontrib/est/widgets/larch/mback_norm.py @@ -60,7 +60,9 @@ class Mback_normWindow(qt.QMainWindow): # xas object viewer mapKeys = ["mu", "mback_mu", "norm"] self.xasObjViewer = XasObjectViewer(mapKeys=mapKeys) - self.xasObjViewer._spectrumViews[0]._plot.getXAxis().setLabel("Energy (eV)") + self.xasObjViewer._spectrumViews[0]._plotWidgetWidget.getXAxis().setLabel( + "Energy (eV)" + ) self.setCentralWidget(self.xasObjViewer) self._parametersWindow = _ParameterWindowContainer( parent=self, parametersWindow=_MBackParameters @@ -75,7 +77,7 @@ class Mback_normWindow(qt.QMainWindow): # legend selector self.legendDockWidget = LegendSelector.LegendsDockWidget( - parent=self, plot=self.xasObjViewer._spectrumViews[0]._plot + parent=self, plot=self.xasObjViewer._spectrumViews[0]._plotWidget ) self.legendDockWidget.setAllowedAreas( qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea @@ -108,7 +110,7 @@ class Mback_normWindow(qt.QMainWindow): ) def getNCurves(self): - return len(self.xasObjViewer._spectrumViews[0]._plot.getAllCurves()) + return len(self.xasObjViewer._spectrumViews[0]._plotWidget.getAllCurves()) class Mback_normOW(_ProcessForOrangeMixIn, OWWidget): diff --git a/orangecontrib/est/widgets/larch/pre_edge.py b/orangecontrib/est/widgets/larch/pre_edge.py index 369fdc6bf5473121b682380c6844330da507ec64..e290b54dabc6a118e9ed04e9416e6eb024dc2903 100644 --- a/orangecontrib/est/widgets/larch/pre_edge.py +++ b/orangecontrib/est/widgets/larch/pre_edge.py @@ -66,7 +66,9 @@ class _PreEdgeWindow(qt.QMainWindow): # xas object viewer mapKeys = ["mu", "norm", "norm_area"] self.xasObjViewer = XasObjectViewer(mapKeys=mapKeys) - self.xasObjViewer._spectrumViews[0]._plot.getXAxis().setLabel("Energy (eV)") + self.xasObjViewer._spectrumViews[0]._plotWidget.getXAxis().setLabel( + "Energy (eV)" + ) self.setCentralWidget(self.xasObjViewer) self._parametersWindow = _ParameterWindowContainer( parent=self, parametersWindow=_MPreEdgeParameters @@ -81,7 +83,7 @@ class _PreEdgeWindow(qt.QMainWindow): # legend selector self.legendDockWidget = LegendSelector.LegendsDockWidget( - parent=self, plot=self.xasObjViewer._spectrumViews[0]._plot + parent=self, plot=self.xasObjViewer._spectrumViews[0]._plotWidget ) self.legendDockWidget.setAllowedAreas( qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea @@ -120,7 +122,7 @@ class _PreEdgeWindow(qt.QMainWindow): ) def getNCurves(self): - return len(self.xasObjViewer._spectrumViews[0]._plot.getAllCurves()) + return len(self.xasObjViewer._spectrumViews[0]._plotWidget.getAllCurves()) class PreEdgeOW(_ProcessForOrangeMixIn, OWWidget): diff --git a/orangecontrib/est/widgets/larch/xftf.py b/orangecontrib/est/widgets/larch/xftf.py index 0116032634048fb3c10d8ef3adeb5c276f5cf6b3..06ecc6cc582d430324cb427c176934073022b5b9 100644 --- a/orangecontrib/est/widgets/larch/xftf.py +++ b/orangecontrib/est/widgets/larch/xftf.py @@ -83,7 +83,9 @@ class XFTFWindow(qt.QMainWindow): # xas object viewer mapKeys = ["mu", "chir", "chir_mag", "chir_re", "chir_im", "chir_pha"] self.xasObjViewer = XasObjectViewer(mapKeys=mapKeys) - self.xasObjViewer._spectrumViews[0]._plot.getXAxis().setLabel("Energy (eV)") + self.xasObjViewer._spectrumViews[0]._plotWidget.getXAxis().setLabel( + "Energy (eV)" + ) self.setCentralWidget(self.xasObjViewer) self._parametersWindow = _ParameterWindowContainer( parent=self, parametersWindow=_MXFTFParameters @@ -98,7 +100,7 @@ class XFTFWindow(qt.QMainWindow): # legend selector self.legendDockWidget = LegendSelector.LegendsDockWidget( - parent=self, plot=self.xasObjViewer._spectrumViews[0]._plot + parent=self, plot=self.xasObjViewer._spectrumViews[0]._plotWidget ) self.legendDockWidget.setAllowedAreas( qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea @@ -131,7 +133,7 @@ class XFTFWindow(qt.QMainWindow): ) def getNCurves(self): - return len(self.xasObjViewer._spectrumViews[0]._plot.getAllCurves()) + return len(self.xasObjViewer._spectrumViews[0]._plotWidget.getAllCurves()) def setKWeight(self, kweight): self._parametersWindow._mainwidget.setKWeight(kweight) diff --git a/orangecontrib/est/widgets/pymca/exafs.py b/orangecontrib/est/widgets/pymca/exafs.py index e660f7aea609c7483477c5493c8073e2ff96f5d5..c561a9d58b1d3664db6779535db78be873763dd4 100644 --- a/orangecontrib/est/widgets/pymca/exafs.py +++ b/orangecontrib/est/widgets/pymca/exafs.py @@ -62,8 +62,8 @@ class ExafsWindow(qt.QMainWindow): qt.QMainWindow.__init__(self, parent) mapKeys = ["mu", "EXAFS.EXAFSKValues", "EXAFS.EXAFSSignal", "EXAFS.PostEdgeB"] self.xasObjViewer = XasObjectViewer(mapKeys=mapKeys) - self.xasObjViewer._spectrumViews[0]._plot.getXAxis().setLabel("K") - self.xasObjViewer._spectrumViews[0]._plot.getYAxis().setLabel( + self.xasObjViewer._spectrumViews[0]._plotWidget.getXAxis().setLabel("K") + self.xasObjViewer._spectrumViews[0]._plotWidget.getYAxis().setLabel( "Normalized Units" ) self.setCentralWidget(self.xasObjViewer) @@ -81,7 +81,7 @@ class ExafsWindow(qt.QMainWindow): # legend selector self.legendDockWidget = LegendSelector.LegendsDockWidget( - parent=self, plot=self.xasObjViewer._spectrumViews[0]._plot + parent=self, plot=self.xasObjViewer._spectrumViews[0]._plotWidget ) self.legendDockWidget.setAllowedAreas( qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea @@ -156,8 +156,8 @@ class ExafsOW(_ProcessForOrangeMixIn, OWWidget): layout = gui.vBox(self.mainArea, "exafs").layout() layout.addWidget(self._window) - self._window.xasObjViewer._spectrumViews[0]._plot.getXAxis().setLabel("K") - self._window.xasObjViewer._spectrumViews[0]._plot.getYAxis().setLabel( + self._window.xasObjViewer._spectrumViews[0]._plotWidget.getXAxis().setLabel("K") + self._window.xasObjViewer._spectrumViews[0]._plotWidget.getYAxis().setLabel( "Normalized Units" ) diff --git a/orangecontrib/est/widgets/pymca/ft.py b/orangecontrib/est/widgets/pymca/ft.py index d76f9a1f3c72995355bf5c447bc70c66d4970d31..6a7aa48e49c74ed13dd265b75863954af3cffd08 100644 --- a/orangecontrib/est/widgets/pymca/ft.py +++ b/orangecontrib/est/widgets/pymca/ft.py @@ -64,10 +64,14 @@ class FTWindow(qt.QMainWindow): self.xasObjViewer = XasObjectViewer( mapKeys=["Mu"], spectrumPlots=("FTWindow", "FTIntensity") ) - self.xasObjViewer._spectrumViews[0]._plot.getXAxis().setLabel("K") + self.xasObjViewer._spectrumViews[0]._plotWidget.getXAxis().setLabel("K") - self.xasObjViewer._spectrumViews[1]._plot.getXAxis().setLabel("R (Angstrom)") - self.xasObjViewer._spectrumViews[1]._plot.getYAxis().setLabel("Arbitrary Units") + self.xasObjViewer._spectrumViews[1]._plotWidget.getXAxis().setLabel( + "R (Angstrom)" + ) + self.xasObjViewer._spectrumViews[1]._plotWidget.getYAxis().setLabel( + "Arbitrary Units" + ) self.setCentralWidget(self.xasObjViewer) self._pymcaWindow = _ParameterWindowContainer( parent=self, parametersWindow=XASFourierTransformParameters @@ -82,7 +86,7 @@ class FTWindow(qt.QMainWindow): # legend selectors self.legendDockWidget1 = LegendSelector.LegendsDockWidget( - parent=self, plot=self.xasObjViewer._spectrumViews[0]._plot + parent=self, plot=self.xasObjViewer._spectrumViews[0]._plotWidget ) self.legendDockWidget1.setAllowedAreas( qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea @@ -91,7 +95,7 @@ class FTWindow(qt.QMainWindow): self.addDockWidget(qt.Qt.RightDockWidgetArea, self.legendDockWidget1) self.legendDockWidget2 = LegendSelector.LegendsDockWidget( - parent=self, plot=self.xasObjViewer._spectrumViews[1]._plot + parent=self, plot=self.xasObjViewer._spectrumViews[1]._plotWidget ) self.legendDockWidget2.setAllowedAreas( qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea diff --git a/orangecontrib/est/widgets/pymca/normalization.py b/orangecontrib/est/widgets/pymca/normalization.py index 27345f577dfc5fcc50084d1f0c81ae123adfc739..69233ecf35966cd4f3c938bb71043496d00ef8e2 100644 --- a/orangecontrib/est/widgets/pymca/normalization.py +++ b/orangecontrib/est/widgets/pymca/normalization.py @@ -124,8 +124,10 @@ class NormalizationWindow(qt.QMainWindow): # xas object viewer mapKeys = ["mu", "NormalizedMu", "NormalizedSignal", "NormalizedBackground"] self.xasObjViewer = XasObjectViewer(mapKeys=mapKeys) - self.xasObjViewer._spectrumViews[0]._plot.getXAxis().setLabel("Energy (eV)") - self.xasObjViewer._spectrumViews[0]._plot.getYAxis().setLabel( + self.xasObjViewer._spectrumViews[0]._plotWidget.getXAxis().setLabel( + "Energy (eV)" + ) + self.xasObjViewer._spectrumViews[0]._plotWidget.getYAxis().setLabel( "Absorption (a.u.)" ) self.setCentralWidget(self.xasObjViewer) @@ -142,7 +144,7 @@ class NormalizationWindow(qt.QMainWindow): # legend selector self.legendDockWidget = LegendSelector.LegendsDockWidget( - parent=self, plot=self.xasObjViewer._spectrumViews[0]._plot + parent=self, plot=self.xasObjViewer._spectrumViews[0]._plotWidget ) self.legendDockWidget.setAllowedAreas( qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea diff --git a/orangecontrib/est/widgets/utils/xas_input.py b/orangecontrib/est/widgets/utils/xas_input.py index c7db8913bc7657da3ce060adbca6a1b452679843..fee0274a9267cc4704f5946eda0d3d573defe8da 100644 --- a/orangecontrib/est/widgets/utils/xas_input.py +++ b/orangecontrib/est/widgets/utils/xas_input.py @@ -161,10 +161,24 @@ class XASInputOW(OWWidget): self._inputDialog.setCurrentType(input_type) def _storeSettings(self): + # handle single file input self._input_file_setting = self._inputDialog.getDatFile() - self._spectra_url_setting = self._inputDialog.getSpectraUrl() - self._energy_url_setting = self._inputDialog.getEnergyUrl() - self._configuration_url_setting = self._inputDialog.getConfigurationUrl() + # handle spectra + spectra_url = self._inputDialog.getSpectraUrl() + if spectra_url is not None: + spectra_url = spectra_url.path() + self._spectra_url_setting = spectra_url + # handle energy + energy_url = self._inputDialog.getEnergyUrl() + if energy_url is not None: + assert energy_url.is_valid() + energy_url = energy_url.path() + self._energy_url_setting = energy_url + # handle configuration + configuration_url = self._inputDialog.getConfigurationUrl() + if configuration_url is not None: + configuration_url = configuration_url.path() + self._configuration_url_setting = configuration_url self._dimensions_setting = self._inputDialog.getDimensions() def sizeHint(self):