sigima 0.0.1.dev0__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sigima/__init__.py +142 -2
- sigima/client/__init__.py +105 -0
- sigima/client/base.py +780 -0
- sigima/client/remote.py +469 -0
- sigima/client/stub.py +814 -0
- sigima/client/utils.py +90 -0
- sigima/config.py +444 -0
- sigima/data/logo/Sigima.svg +135 -0
- sigima/data/tests/annotations.json +798 -0
- sigima/data/tests/curve_fitting/exponential_fit.txt +511 -0
- sigima/data/tests/curve_fitting/gaussian_fit.txt +100 -0
- sigima/data/tests/curve_fitting/piecewiseexponential_fit.txt +1022 -0
- sigima/data/tests/curve_fitting/polynomial_fit.txt +100 -0
- sigima/data/tests/curve_fitting/twohalfgaussian_fit.txt +1000 -0
- sigima/data/tests/curve_formats/bandwidth.txt +201 -0
- sigima/data/tests/curve_formats/boxcar.npy +0 -0
- sigima/data/tests/curve_formats/datetime.txt +1001 -0
- sigima/data/tests/curve_formats/dynamic_parameters.txt +4000 -0
- sigima/data/tests/curve_formats/fw1e2.txt +301 -0
- sigima/data/tests/curve_formats/fwhm.txt +319 -0
- sigima/data/tests/curve_formats/multiple_curves.csv +29 -0
- sigima/data/tests/curve_formats/noised_saw.mat +0 -0
- sigima/data/tests/curve_formats/oscilloscope.csv +111 -0
- sigima/data/tests/curve_formats/other/other2/recursive2.txt +5 -0
- sigima/data/tests/curve_formats/other/recursive1.txt +5 -0
- sigima/data/tests/curve_formats/paracetamol.npy +0 -0
- sigima/data/tests/curve_formats/paracetamol.txt +1010 -0
- sigima/data/tests/curve_formats/paracetamol_dx_dy.csv +1000 -0
- sigima/data/tests/curve_formats/paracetamol_dy.csv +1001 -0
- sigima/data/tests/curve_formats/pulse1.npy +0 -0
- sigima/data/tests/curve_formats/pulse2.npy +0 -0
- sigima/data/tests/curve_formats/simple.txt +5 -0
- sigima/data/tests/curve_formats/spectrum.mca +2139 -0
- sigima/data/tests/curve_formats/square2.npy +0 -0
- sigima/data/tests/curve_formats/step.npy +0 -0
- sigima/data/tests/fabry-perot1.jpg +0 -0
- sigima/data/tests/fabry-perot2.jpg +0 -0
- sigima/data/tests/flower.npy +0 -0
- sigima/data/tests/image_formats/NF 180338201.scor-data +11003 -0
- sigima/data/tests/image_formats/binary_image.npy +0 -0
- sigima/data/tests/image_formats/binary_image.png +0 -0
- sigima/data/tests/image_formats/centroid_test.npy +0 -0
- sigima/data/tests/image_formats/coordinated_text/complex_image.txt +10011 -0
- sigima/data/tests/image_formats/coordinated_text/complex_ref_image.txt +10010 -0
- sigima/data/tests/image_formats/coordinated_text/image.txt +15 -0
- sigima/data/tests/image_formats/coordinated_text/image2.txt +14 -0
- sigima/data/tests/image_formats/coordinated_text/image_no_unit_no_label.txt +14 -0
- sigima/data/tests/image_formats/coordinated_text/image_with_nan.txt +15 -0
- sigima/data/tests/image_formats/coordinated_text/image_with_unit.txt +14 -0
- sigima/data/tests/image_formats/fiber.csv +480 -0
- sigima/data/tests/image_formats/fiber.jpg +0 -0
- sigima/data/tests/image_formats/fiber.png +0 -0
- sigima/data/tests/image_formats/fiber.txt +480 -0
- sigima/data/tests/image_formats/gaussian_spot_with_noise.npy +0 -0
- sigima/data/tests/image_formats/mr-brain.dcm +0 -0
- sigima/data/tests/image_formats/noised_gaussian.mat +0 -0
- sigima/data/tests/image_formats/sif_reader/nd_lum_image_no_glue.sif +0 -0
- sigima/data/tests/image_formats/sif_reader/raman1.sif +0 -0
- sigima/data/tests/image_formats/tiling.txt +10 -0
- sigima/data/tests/image_formats/uint16.tiff +0 -0
- sigima/data/tests/image_formats/uint8.tiff +0 -0
- sigima/data/tests/laser_beam/TEM00_z_13.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_18.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_23.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_30.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_35.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_40.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_45.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_50.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_55.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_60.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_65.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_70.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_75.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_80.jpg +0 -0
- sigima/enums.py +195 -0
- sigima/io/__init__.py +123 -0
- sigima/io/base.py +311 -0
- sigima/io/common/__init__.py +5 -0
- sigima/io/common/basename.py +164 -0
- sigima/io/common/converters.py +189 -0
- sigima/io/common/objmeta.py +181 -0
- sigima/io/common/textreader.py +58 -0
- sigima/io/convenience.py +157 -0
- sigima/io/enums.py +17 -0
- sigima/io/ftlab.py +395 -0
- sigima/io/image/__init__.py +9 -0
- sigima/io/image/base.py +177 -0
- sigima/io/image/formats.py +1016 -0
- sigima/io/image/funcs.py +414 -0
- sigima/io/signal/__init__.py +9 -0
- sigima/io/signal/base.py +129 -0
- sigima/io/signal/formats.py +290 -0
- sigima/io/signal/funcs.py +723 -0
- sigima/objects/__init__.py +260 -0
- sigima/objects/base.py +937 -0
- sigima/objects/image/__init__.py +88 -0
- sigima/objects/image/creation.py +556 -0
- sigima/objects/image/object.py +524 -0
- sigima/objects/image/roi.py +904 -0
- sigima/objects/scalar/__init__.py +57 -0
- sigima/objects/scalar/common.py +215 -0
- sigima/objects/scalar/geometry.py +502 -0
- sigima/objects/scalar/table.py +784 -0
- sigima/objects/shape.py +290 -0
- sigima/objects/signal/__init__.py +133 -0
- sigima/objects/signal/constants.py +27 -0
- sigima/objects/signal/creation.py +1428 -0
- sigima/objects/signal/object.py +444 -0
- sigima/objects/signal/roi.py +274 -0
- sigima/params.py +405 -0
- sigima/proc/__init__.py +96 -0
- sigima/proc/base.py +381 -0
- sigima/proc/decorator.py +330 -0
- sigima/proc/image/__init__.py +513 -0
- sigima/proc/image/arithmetic.py +335 -0
- sigima/proc/image/base.py +260 -0
- sigima/proc/image/detection.py +519 -0
- sigima/proc/image/edges.py +329 -0
- sigima/proc/image/exposure.py +406 -0
- sigima/proc/image/extraction.py +458 -0
- sigima/proc/image/filtering.py +219 -0
- sigima/proc/image/fourier.py +147 -0
- sigima/proc/image/geometry.py +661 -0
- sigima/proc/image/mathops.py +340 -0
- sigima/proc/image/measurement.py +195 -0
- sigima/proc/image/morphology.py +155 -0
- sigima/proc/image/noise.py +107 -0
- sigima/proc/image/preprocessing.py +182 -0
- sigima/proc/image/restoration.py +235 -0
- sigima/proc/image/threshold.py +217 -0
- sigima/proc/image/transformations.py +393 -0
- sigima/proc/signal/__init__.py +376 -0
- sigima/proc/signal/analysis.py +206 -0
- sigima/proc/signal/arithmetic.py +551 -0
- sigima/proc/signal/base.py +262 -0
- sigima/proc/signal/extraction.py +60 -0
- sigima/proc/signal/features.py +310 -0
- sigima/proc/signal/filtering.py +484 -0
- sigima/proc/signal/fitting.py +276 -0
- sigima/proc/signal/fourier.py +259 -0
- sigima/proc/signal/mathops.py +420 -0
- sigima/proc/signal/processing.py +580 -0
- sigima/proc/signal/stability.py +175 -0
- sigima/proc/title_formatting.py +227 -0
- sigima/proc/validation.py +272 -0
- sigima/tests/__init__.py +7 -0
- sigima/tests/common/__init__.py +0 -0
- sigima/tests/common/arithmeticparam_unit_test.py +26 -0
- sigima/tests/common/basename_unit_test.py +126 -0
- sigima/tests/common/client_unit_test.py +412 -0
- sigima/tests/common/converters_unit_test.py +77 -0
- sigima/tests/common/decorator_unit_test.py +176 -0
- sigima/tests/common/examples_unit_test.py +104 -0
- sigima/tests/common/kernel_normalization_unit_test.py +242 -0
- sigima/tests/common/roi_basic_unit_test.py +73 -0
- sigima/tests/common/roi_geometry_unit_test.py +171 -0
- sigima/tests/common/scalar_builder_unit_test.py +142 -0
- sigima/tests/common/scalar_unit_test.py +991 -0
- sigima/tests/common/shape_unit_test.py +183 -0
- sigima/tests/common/stat_unit_test.py +138 -0
- sigima/tests/common/title_formatting_unit_test.py +338 -0
- sigima/tests/common/tools_coordinates_unit_test.py +60 -0
- sigima/tests/common/transformations_unit_test.py +178 -0
- sigima/tests/common/validation_unit_test.py +205 -0
- sigima/tests/conftest.py +129 -0
- sigima/tests/data.py +998 -0
- sigima/tests/env.py +280 -0
- sigima/tests/guiutils.py +163 -0
- sigima/tests/helpers.py +532 -0
- sigima/tests/image/__init__.py +28 -0
- sigima/tests/image/binning_unit_test.py +128 -0
- sigima/tests/image/blob_detection_unit_test.py +312 -0
- sigima/tests/image/centroid_unit_test.py +170 -0
- sigima/tests/image/check_2d_array_unit_test.py +63 -0
- sigima/tests/image/contour_unit_test.py +172 -0
- sigima/tests/image/convolution_unit_test.py +178 -0
- sigima/tests/image/datatype_unit_test.py +67 -0
- sigima/tests/image/edges_unit_test.py +155 -0
- sigima/tests/image/enclosingcircle_unit_test.py +88 -0
- sigima/tests/image/exposure_unit_test.py +223 -0
- sigima/tests/image/fft2d_unit_test.py +189 -0
- sigima/tests/image/filtering_unit_test.py +166 -0
- sigima/tests/image/geometry_unit_test.py +654 -0
- sigima/tests/image/hough_circle_unit_test.py +147 -0
- sigima/tests/image/imageobj_unit_test.py +737 -0
- sigima/tests/image/morphology_unit_test.py +71 -0
- sigima/tests/image/noise_unit_test.py +57 -0
- sigima/tests/image/offset_correction_unit_test.py +72 -0
- sigima/tests/image/operation_unit_test.py +518 -0
- sigima/tests/image/peak2d_limits_unit_test.py +41 -0
- sigima/tests/image/peak2d_unit_test.py +133 -0
- sigima/tests/image/profile_unit_test.py +159 -0
- sigima/tests/image/projections_unit_test.py +121 -0
- sigima/tests/image/restoration_unit_test.py +141 -0
- sigima/tests/image/roi2dparam_unit_test.py +53 -0
- sigima/tests/image/roi_advanced_unit_test.py +588 -0
- sigima/tests/image/roi_grid_unit_test.py +279 -0
- sigima/tests/image/spectrum2d_unit_test.py +40 -0
- sigima/tests/image/threshold_unit_test.py +91 -0
- sigima/tests/io/__init__.py +0 -0
- sigima/tests/io/addnewformat_unit_test.py +125 -0
- sigima/tests/io/convenience_funcs_unit_test.py +470 -0
- sigima/tests/io/coordinated_text_format_unit_test.py +495 -0
- sigima/tests/io/datetime_csv_unit_test.py +198 -0
- sigima/tests/io/imageio_formats_test.py +41 -0
- sigima/tests/io/ioregistry_unit_test.py +69 -0
- sigima/tests/io/objmeta_unit_test.py +87 -0
- sigima/tests/io/readobj_unit_test.py +130 -0
- sigima/tests/io/readwriteobj_unit_test.py +67 -0
- sigima/tests/signal/__init__.py +0 -0
- sigima/tests/signal/analysis_unit_test.py +135 -0
- sigima/tests/signal/check_1d_arrays_unit_test.py +169 -0
- sigima/tests/signal/convolution_unit_test.py +404 -0
- sigima/tests/signal/datetime_unit_test.py +176 -0
- sigima/tests/signal/fft1d_unit_test.py +303 -0
- sigima/tests/signal/filters_unit_test.py +403 -0
- sigima/tests/signal/fitting_unit_test.py +929 -0
- sigima/tests/signal/fwhm_unit_test.py +111 -0
- sigima/tests/signal/noise_unit_test.py +128 -0
- sigima/tests/signal/offset_correction_unit_test.py +34 -0
- sigima/tests/signal/operation_unit_test.py +489 -0
- sigima/tests/signal/peakdetection_unit_test.py +145 -0
- sigima/tests/signal/processing_unit_test.py +657 -0
- sigima/tests/signal/pulse/__init__.py +112 -0
- sigima/tests/signal/pulse/crossing_times_unit_test.py +123 -0
- sigima/tests/signal/pulse/plateau_detection_unit_test.py +102 -0
- sigima/tests/signal/pulse/pulse_unit_test.py +1824 -0
- sigima/tests/signal/roi_advanced_unit_test.py +392 -0
- sigima/tests/signal/signalobj_unit_test.py +603 -0
- sigima/tests/signal/stability_unit_test.py +431 -0
- sigima/tests/signal/uncertainty_unit_test.py +611 -0
- sigima/tests/vistools.py +1030 -0
- sigima/tools/__init__.py +59 -0
- sigima/tools/checks.py +290 -0
- sigima/tools/coordinates.py +308 -0
- sigima/tools/datatypes.py +26 -0
- sigima/tools/image/__init__.py +97 -0
- sigima/tools/image/detection.py +451 -0
- sigima/tools/image/exposure.py +77 -0
- sigima/tools/image/extraction.py +48 -0
- sigima/tools/image/fourier.py +260 -0
- sigima/tools/image/geometry.py +190 -0
- sigima/tools/image/preprocessing.py +165 -0
- sigima/tools/signal/__init__.py +86 -0
- sigima/tools/signal/dynamic.py +254 -0
- sigima/tools/signal/features.py +135 -0
- sigima/tools/signal/filtering.py +171 -0
- sigima/tools/signal/fitting.py +1171 -0
- sigima/tools/signal/fourier.py +466 -0
- sigima/tools/signal/interpolation.py +70 -0
- sigima/tools/signal/peakdetection.py +126 -0
- sigima/tools/signal/pulse.py +1626 -0
- sigima/tools/signal/scaling.py +50 -0
- sigima/tools/signal/stability.py +258 -0
- sigima/tools/signal/windowing.py +90 -0
- sigima/worker.py +79 -0
- sigima-1.0.0.dist-info/METADATA +233 -0
- sigima-1.0.0.dist-info/RECORD +262 -0
- {sigima-0.0.1.dev0.dist-info → sigima-1.0.0.dist-info}/licenses/LICENSE +29 -29
- sigima-0.0.1.dev0.dist-info/METADATA +0 -60
- sigima-0.0.1.dev0.dist-info/RECORD +0 -6
- {sigima-0.0.1.dev0.dist-info → sigima-1.0.0.dist-info}/WHEEL +0 -0
- {sigima-0.0.1.dev0.dist-info → sigima-1.0.0.dist-info}/top_level.txt +0 -0
sigima/proc/__init__.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Computation (:mod:`sigima.proc`)
|
|
3
|
+
--------------------------------
|
|
4
|
+
|
|
5
|
+
This package contains the Sigima computation functions that implement processing
|
|
6
|
+
features for signal, image and scalar objects. These functions are designed to operate
|
|
7
|
+
directly on :class:`sigima.objects.SignalObj`, :class:`sigima.objects.ImageObj`,
|
|
8
|
+
:class:`sigima.objects.GeometryResult` and :class:`sigima.objects.TableResult` objects,
|
|
9
|
+
which are defined in the :mod:`sigima.objects` package.
|
|
10
|
+
|
|
11
|
+
Even though these functions are primarily designed to be used in the Sigima pipeline,
|
|
12
|
+
they can also be used independently.
|
|
13
|
+
|
|
14
|
+
.. seealso::
|
|
15
|
+
|
|
16
|
+
See the :mod:`sigima.tools` package for some algorithms that operate directly on
|
|
17
|
+
NumPy arrays.
|
|
18
|
+
|
|
19
|
+
Each computation module defines a set of computation objects, that is, functions
|
|
20
|
+
that implement processing features and classes that implement the corresponding
|
|
21
|
+
parameters (in the form of :py:class:`guidata.dataset.datatypes.Dataset` subclasses).
|
|
22
|
+
The computation functions takes a signal or image object
|
|
23
|
+
(e.g. :py:class:`sigima.objects.SignalObj`)
|
|
24
|
+
and a parameter object (e.g. :py:class:`sigima.params.MovingAverageParam`) as input
|
|
25
|
+
and return a signal or image object as output (the result of the computation).
|
|
26
|
+
The parameter object is used to configure the computation function
|
|
27
|
+
(e.g. the size of the moving average window).
|
|
28
|
+
|
|
29
|
+
In Sigima overall architecture, the purpose of this package is to provide the
|
|
30
|
+
computation functions that are used by DataLab processor modules,
|
|
31
|
+
based on the algorithms defined in the :mod:`sigima.tools` module and on the
|
|
32
|
+
data model defined in the :mod:`sigima.objects` module.
|
|
33
|
+
|
|
34
|
+
The computation modules are organized in subpackages according to their purpose.
|
|
35
|
+
The following subpackages are available:
|
|
36
|
+
|
|
37
|
+
- :mod:`sigima.proc.base`: Common processing features
|
|
38
|
+
- :mod:`sigima.proc.signal`: Signal processing features
|
|
39
|
+
- :mod:`sigima.proc.image`: Image processing features (including transformations)
|
|
40
|
+
|
|
41
|
+
Common processing features
|
|
42
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
43
|
+
|
|
44
|
+
.. automodule:: sigima.proc.base
|
|
45
|
+
:members:
|
|
46
|
+
|
|
47
|
+
Signal processing features
|
|
48
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
49
|
+
|
|
50
|
+
.. automodule:: sigima.proc.signal
|
|
51
|
+
:members:
|
|
52
|
+
|
|
53
|
+
Image processing features
|
|
54
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
55
|
+
|
|
56
|
+
.. automodule:: sigima.proc.image
|
|
57
|
+
:members:
|
|
58
|
+
|
|
59
|
+
Decorators and utilities
|
|
60
|
+
^^^^^^^^^^^^^^^^^^^^^^^^
|
|
61
|
+
|
|
62
|
+
This package also provides some utility functions to help with the creation and
|
|
63
|
+
introspection of computation functions:
|
|
64
|
+
|
|
65
|
+
.. autofunction:: sigima.proc.decorator.computation_function
|
|
66
|
+
.. autofunction:: sigima.proc.decorator.is_computation_function
|
|
67
|
+
.. autofunction:: sigima.proc.decorator.get_computation_metadata
|
|
68
|
+
.. autofunction:: sigima.proc.decorator.find_computation_functions
|
|
69
|
+
|
|
70
|
+
Title Formatting System
|
|
71
|
+
^^^^^^^^^^^^^^^^^^^^^^^
|
|
72
|
+
|
|
73
|
+
The title formatting system provides configurable title generation for computation
|
|
74
|
+
results, enabling different applications (Sigima standalone vs DataLab integration)
|
|
75
|
+
to use different title formatting strategies:
|
|
76
|
+
|
|
77
|
+
.. automodule:: sigima.proc.title_formatting
|
|
78
|
+
:members:
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
# Import title formatting components for easy access
|
|
82
|
+
from sigima.proc.title_formatting import (
|
|
83
|
+
PlaceholderTitleFormatter,
|
|
84
|
+
SimpleTitleFormatter,
|
|
85
|
+
TitleFormatter,
|
|
86
|
+
get_default_title_formatter,
|
|
87
|
+
set_default_title_formatter,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
__all__ = [
|
|
91
|
+
"PlaceholderTitleFormatter",
|
|
92
|
+
"SimpleTitleFormatter",
|
|
93
|
+
"TitleFormatter",
|
|
94
|
+
"get_default_title_formatter",
|
|
95
|
+
"set_default_title_formatter",
|
|
96
|
+
]
|
sigima/proc/base.py
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
.. Common computation objects (see parent package :mod:`sigima.computation`)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
8
|
+
|
|
9
|
+
# Note:
|
|
10
|
+
# ----
|
|
11
|
+
# All dataset classes must also be imported in the sigima.params module.
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from typing import TypeVar, cast
|
|
16
|
+
|
|
17
|
+
import guidata.dataset as gds
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
from sigima import ImageObj, SignalObj, create_signal
|
|
21
|
+
from sigima.config import _, options
|
|
22
|
+
from sigima.enums import (
|
|
23
|
+
AngleUnit,
|
|
24
|
+
FilterMode,
|
|
25
|
+
MathOperator,
|
|
26
|
+
NormalizationMethod,
|
|
27
|
+
SignalsToImageOrientation,
|
|
28
|
+
)
|
|
29
|
+
from sigima.proc.title_formatting import get_default_title_formatter
|
|
30
|
+
|
|
31
|
+
# NOTE: This module is a shared utilities library that defines common parameter classes
|
|
32
|
+
# used by multiple other modules (signal processing, image processing, etc.).
|
|
33
|
+
# Unlike other modules, the parameter classes DEFINED in this module should NOT be
|
|
34
|
+
# included in __all__ because they are imported and re-exported by the modules that
|
|
35
|
+
# use them, and including them here would create Sphinx cross-reference conflicts.
|
|
36
|
+
# The sigima.params module serves as the central API point that imports and re-exports
|
|
37
|
+
# all parameter classes from their canonical locations.
|
|
38
|
+
__all__ = [
|
|
39
|
+
"dst_1_to_1",
|
|
40
|
+
"dst_2_to_1",
|
|
41
|
+
"dst_n_to_1",
|
|
42
|
+
"new_signal_result",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ArithmeticParam(gds.DataSet, title=_("Arithmetic")):
|
|
47
|
+
"""Arithmetic parameters"""
|
|
48
|
+
|
|
49
|
+
def get_operation(self) -> str:
|
|
50
|
+
"""Return the operation string"""
|
|
51
|
+
o, a, b = self.operator, self.factor, self.constant
|
|
52
|
+
b_added = False
|
|
53
|
+
if a == 0.0:
|
|
54
|
+
if o in ("+", "-"):
|
|
55
|
+
txt = "obj3 = obj1"
|
|
56
|
+
elif b == 0.0:
|
|
57
|
+
txt = "obj3 = 0"
|
|
58
|
+
else:
|
|
59
|
+
txt = f"obj3 = {b}"
|
|
60
|
+
b_added = True
|
|
61
|
+
elif a == 1.0:
|
|
62
|
+
txt = f"obj3 = obj1 {o} obj2"
|
|
63
|
+
else:
|
|
64
|
+
txt = f"obj3 = (obj1 {o} obj2) × {a}"
|
|
65
|
+
if b != 0.0 and not b_added:
|
|
66
|
+
txt += f" + {b}"
|
|
67
|
+
return txt
|
|
68
|
+
|
|
69
|
+
def update_operation(self, _item, _value): # pylint: disable=unused-argument
|
|
70
|
+
"""Update the operation item"""
|
|
71
|
+
self.operation = self.get_operation()
|
|
72
|
+
|
|
73
|
+
operator = gds.ChoiceItem(
|
|
74
|
+
_("Operator"), MathOperator, default=MathOperator.ADD
|
|
75
|
+
).set_prop("display", callback=update_operation)
|
|
76
|
+
factor = (
|
|
77
|
+
gds.FloatItem(_("Factor"), default=1.0)
|
|
78
|
+
.set_pos(col=1)
|
|
79
|
+
.set_prop("display", callback=update_operation)
|
|
80
|
+
)
|
|
81
|
+
constant = (
|
|
82
|
+
gds.FloatItem(_("Constant"), default=0.0)
|
|
83
|
+
.set_pos(col=1)
|
|
84
|
+
.set_prop("display", callback=update_operation)
|
|
85
|
+
)
|
|
86
|
+
operation = gds.StringItem(_("Operation"), default="").set_prop(
|
|
87
|
+
"display", active=False
|
|
88
|
+
)
|
|
89
|
+
restore_dtype = gds.BoolItem(
|
|
90
|
+
_("Convert to `obj1` data type"), label=_("Result"), default=True
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class GaussianParam(gds.DataSet, title=_("Gaussian filter")):
|
|
95
|
+
"""Gaussian filter parameters."""
|
|
96
|
+
|
|
97
|
+
sigma = gds.FloatItem(
|
|
98
|
+
"σ",
|
|
99
|
+
default=1.0,
|
|
100
|
+
min=0.0,
|
|
101
|
+
help=_("Standard deviation of the Gaussian filter"),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
HELP_MODE = _("""Mode of the filter:
|
|
106
|
+
- 'reflect': Reflect the data at the boundary
|
|
107
|
+
- 'constant': Pad with a constant value
|
|
108
|
+
- 'nearest': Pad with the nearest value
|
|
109
|
+
- 'mirror': Reflect the data at the boundary with the data itself
|
|
110
|
+
- 'wrap': Circular boundary""")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class MovingAverageParam(gds.DataSet, title=_("Moving average")):
|
|
114
|
+
"""Moving average parameters"""
|
|
115
|
+
|
|
116
|
+
n = gds.IntItem(_("Size of the moving window"), default=3, min=1)
|
|
117
|
+
mode = gds.ChoiceItem(
|
|
118
|
+
_("Mode"), FilterMode, default=FilterMode.REFLECT, help=HELP_MODE
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class MovingMedianParam(gds.DataSet, title=_("Moving median")):
|
|
123
|
+
"""Moving median parameters"""
|
|
124
|
+
|
|
125
|
+
n = gds.IntItem(_("Size of the moving window"), default=3, min=1, even=False)
|
|
126
|
+
mode = gds.ChoiceItem(
|
|
127
|
+
_("Mode"), FilterMode, default=FilterMode.NEAREST, help=HELP_MODE
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class ClipParam(gds.DataSet, title=_("Clip")):
|
|
132
|
+
"""Data clipping parameters"""
|
|
133
|
+
|
|
134
|
+
lower = gds.FloatItem(_("Lower clipping value"), check=False)
|
|
135
|
+
upper = gds.FloatItem(_("Upper clipping value"), check=False)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class NormalizeParam(gds.DataSet, title=_("Normalize")):
|
|
139
|
+
"""Normalize parameters"""
|
|
140
|
+
|
|
141
|
+
method = gds.ChoiceItem(_("Normalize with respect to"), NormalizationMethod)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class HistogramParam(gds.DataSet, title=_("Histogram")):
|
|
145
|
+
"""Histogram parameters"""
|
|
146
|
+
|
|
147
|
+
def get_suffix(self, data: np.ndarray) -> str:
|
|
148
|
+
"""Return suffix for the histogram computation
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
data: data array
|
|
152
|
+
"""
|
|
153
|
+
suffix = f"bins={self.bins:d}"
|
|
154
|
+
if self.lower is not None:
|
|
155
|
+
suffix += f", ymin={self.lower:.3f}"
|
|
156
|
+
else:
|
|
157
|
+
self.lower = np.min(data)
|
|
158
|
+
if self.upper is not None:
|
|
159
|
+
suffix += f", ymax={self.upper:.3f}"
|
|
160
|
+
else:
|
|
161
|
+
self.upper = np.max(data)
|
|
162
|
+
return suffix
|
|
163
|
+
|
|
164
|
+
bins = gds.IntItem(_("Number of bins"), default=256, min=1)
|
|
165
|
+
lower = gds.FloatItem(_("Lower limit"), default=None, check=False)
|
|
166
|
+
upper = gds.FloatItem(_("Upper limit"), default=None, check=False)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class FFTParam(gds.DataSet, title=_("FFT")):
|
|
170
|
+
"""FFT parameters"""
|
|
171
|
+
|
|
172
|
+
shift = gds.BoolItem(_("Shift"), help=_("Shift zero frequency to center"))
|
|
173
|
+
|
|
174
|
+
def __init__(self, *args, **kwargs):
|
|
175
|
+
super().__init__(*args, **kwargs)
|
|
176
|
+
self.shift = options.fft_shift_enabled.get()
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class SpectrumParam(gds.DataSet, title=_("Spectrum")):
|
|
180
|
+
"""Spectrum parameters."""
|
|
181
|
+
|
|
182
|
+
decibel = gds.BoolItem(_("Output in decibel (dB)"), default=False)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class ConstantParam(gds.DataSet, title=_("Constant")):
|
|
186
|
+
"""Parameter used to set a constant value to used in operations"""
|
|
187
|
+
|
|
188
|
+
value = gds.FloatItem(_("Constant value"))
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class AngleUnitParam(gds.DataSet, title=_("Angle unit")):
|
|
192
|
+
"""Choice of angle unit."""
|
|
193
|
+
|
|
194
|
+
unit = gds.ChoiceItem(
|
|
195
|
+
_("Angle unit"),
|
|
196
|
+
AngleUnit,
|
|
197
|
+
default=AngleUnit.RADIAN,
|
|
198
|
+
help=_("Unit of angle measurement"),
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class PhaseParam(gds.DataSet, title=_("Phase")):
|
|
203
|
+
"""Parameters for phase computation."""
|
|
204
|
+
|
|
205
|
+
unwrap = gds.BoolItem(
|
|
206
|
+
"unwrap", default=True, help=_("Unwrapping removes discontinuities in phase")
|
|
207
|
+
)
|
|
208
|
+
unit = gds.ChoiceItem(
|
|
209
|
+
_("Unit"),
|
|
210
|
+
AngleUnit,
|
|
211
|
+
default=AngleUnit.DEGREE,
|
|
212
|
+
help=_("Unit of angle measurement"),
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class SignalsToImageParam(gds.DataSet):
|
|
217
|
+
"""Parameters for combining signals into an image."""
|
|
218
|
+
|
|
219
|
+
orientation = gds.ChoiceItem(
|
|
220
|
+
_("Orientation"),
|
|
221
|
+
SignalsToImageOrientation,
|
|
222
|
+
default=SignalsToImageOrientation.ROWS,
|
|
223
|
+
help=_("How to arrange signals: as rows or as columns"),
|
|
224
|
+
)
|
|
225
|
+
_prop = gds.GetAttrProp("normalize")
|
|
226
|
+
normalize = gds.BoolItem(
|
|
227
|
+
_("Normalize"),
|
|
228
|
+
default=False,
|
|
229
|
+
help=_("Normalize each signal before combining"),
|
|
230
|
+
)
|
|
231
|
+
normalize_method = gds.ChoiceItem(
|
|
232
|
+
_("Normalization method"),
|
|
233
|
+
NormalizationMethod,
|
|
234
|
+
default=NormalizationMethod.MAXIMUM,
|
|
235
|
+
help=_("Method used for normalization"),
|
|
236
|
+
).set_prop("display", active=_prop)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# MARK: Helper functions for creating result objects -----------------------------------
|
|
240
|
+
|
|
241
|
+
Obj = TypeVar("Obj", bound="SignalObj | ImageObj")
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def dst_1_to_1(src: Obj, name: str, suffix: str | None = None) -> Obj:
|
|
245
|
+
"""Create a result object, for processing functions that take a single
|
|
246
|
+
signal or image object as input and return a single signal or image object (1-to-1).
|
|
247
|
+
|
|
248
|
+
.. note::
|
|
249
|
+
|
|
250
|
+
Data of the result object is copied from the source object (`src`).
|
|
251
|
+
This initial data is usually replaced by the processing function, but it may
|
|
252
|
+
also be used to initialize the result object as part of the processing function.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
src: source signal or image object
|
|
256
|
+
name: name of the function. The title format depends on the configured
|
|
257
|
+
title formatter (SimpleTitleFormatter creates readable titles,
|
|
258
|
+
PlaceholderTitleFormatter creates DataLab-compatible placeholder titles).
|
|
259
|
+
suffix: suffix to add to the title. Optional.
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
Result signal or image object
|
|
263
|
+
"""
|
|
264
|
+
formatter = get_default_title_formatter()
|
|
265
|
+
title = formatter.format_1_to_1_title(name, suffix)
|
|
266
|
+
dst = src.copy(title=title)
|
|
267
|
+
return cast(Obj, dst)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def dst_n_to_1(src_list: list[Obj], name: str, suffix: str | None = None) -> Obj:
|
|
271
|
+
"""Create a result object, for processing functions that take a list of signal or
|
|
272
|
+
image objects as input and return a single signal or image object (n-to-1).
|
|
273
|
+
|
|
274
|
+
.. note::
|
|
275
|
+
|
|
276
|
+
Data of the result object is copied from the first source object
|
|
277
|
+
(`src_list[0]`). This initial data is usually replaced by the processing
|
|
278
|
+
function, but it may also be used to initialize the result object as part
|
|
279
|
+
of the processing function.
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
src_list: list of input signal or image objects
|
|
283
|
+
name: name of the processing function. The title format depends on the
|
|
284
|
+
configured title formatter (SimpleTitleFormatter creates readable titles,
|
|
285
|
+
PlaceholderTitleFormatter creates DataLab-compatible placeholder titles).
|
|
286
|
+
suffix: suffix to add to the title
|
|
287
|
+
|
|
288
|
+
Returns:
|
|
289
|
+
Result signal or image object
|
|
290
|
+
"""
|
|
291
|
+
if not isinstance(src_list, list) or len(src_list) <= 1:
|
|
292
|
+
raise ValueError("src_list must be a list of at least 2 objects")
|
|
293
|
+
all_sigs = all(isinstance(obj, SignalObj) for obj in src_list)
|
|
294
|
+
all_imgs = all(isinstance(obj, ImageObj) for obj in src_list)
|
|
295
|
+
if not (all_sigs or all_imgs):
|
|
296
|
+
raise ValueError("src_list must be a list of SignalObj or ImageObj objects")
|
|
297
|
+
|
|
298
|
+
formatter = get_default_title_formatter()
|
|
299
|
+
title = formatter.format_n_to_1_title(name, len(src_list), suffix)
|
|
300
|
+
|
|
301
|
+
if any(np.issubdtype(obj.data.dtype, complex) for obj in src_list):
|
|
302
|
+
dst_dtype = complex
|
|
303
|
+
else:
|
|
304
|
+
dst_dtype = float
|
|
305
|
+
dst = src_list[0].copy(title=title, dtype=dst_dtype)
|
|
306
|
+
dst.roi = None
|
|
307
|
+
for src_obj in src_list:
|
|
308
|
+
if src_obj.roi is not None:
|
|
309
|
+
if dst.roi is None:
|
|
310
|
+
dst.roi = src_obj.roi.copy()
|
|
311
|
+
else:
|
|
312
|
+
dst.roi.add_roi(src_obj.roi)
|
|
313
|
+
return dst
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
# Note about `src2` parameter:
|
|
317
|
+
# ----------------------------
|
|
318
|
+
# The `src2` parameter is currently not used in the function, but it is included
|
|
319
|
+
# to maintain a consistent interface with other similar functions (e.g., `dst_n_to_1`).
|
|
320
|
+
# This may be useful in the future if we want to extend the functionality.
|
|
321
|
+
#
|
|
322
|
+
# pylint: disable=unused-argument
|
|
323
|
+
def dst_2_to_1(src1: Obj, src2: Obj, name: str, suffix: str | None = None) -> Obj:
|
|
324
|
+
"""Create a result object, for processing functions that take two signal or
|
|
325
|
+
image objects as input and return a single signal or image object (2-to-1).
|
|
326
|
+
|
|
327
|
+
.. note::
|
|
328
|
+
|
|
329
|
+
Data of the result object is copied from the first source object (`src1`).
|
|
330
|
+
This initial data is usually replaced by the processing function, but it may
|
|
331
|
+
also be used to initialize the result object as part of the processing function.
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
src1: input signal or image object
|
|
335
|
+
src2: input signal or image object
|
|
336
|
+
name: name of the processing function. The title format depends on the
|
|
337
|
+
configured title formatter (SimpleTitleFormatter creates readable titles,
|
|
338
|
+
PlaceholderTitleFormatter creates DataLab-compatible placeholder titles).
|
|
339
|
+
suffix: suffix to add to the title
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
Output signal or image object
|
|
343
|
+
"""
|
|
344
|
+
formatter = get_default_title_formatter()
|
|
345
|
+
title = formatter.format_2_to_1_title(name, suffix)
|
|
346
|
+
dst = src1.copy(title=title)
|
|
347
|
+
return dst
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def new_signal_result(
|
|
351
|
+
src: SignalObj | ImageObj,
|
|
352
|
+
name: str,
|
|
353
|
+
suffix: str | None = None,
|
|
354
|
+
units: tuple[str, str] | None = None,
|
|
355
|
+
labels: tuple[str, str] | None = None,
|
|
356
|
+
) -> SignalObj:
|
|
357
|
+
"""Create new signal object as a result of a `compute_1_to_1` function
|
|
358
|
+
|
|
359
|
+
As opposed to the `dst_1_to_1` functions, this function creates a new signal object
|
|
360
|
+
without copying the original object metadata, except for the "source" entry.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
src: input signal or image object
|
|
364
|
+
name: name of the processing function. The title format depends on the
|
|
365
|
+
configured title formatter (SimpleTitleFormatter creates readable titles,
|
|
366
|
+
PlaceholderTitleFormatter creates DataLab-compatible placeholder titles).
|
|
367
|
+
suffix: suffix to add to the title
|
|
368
|
+
units: units of the output signal
|
|
369
|
+
labels: labels of the output signal
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
Output signal object
|
|
373
|
+
"""
|
|
374
|
+
formatter = get_default_title_formatter()
|
|
375
|
+
title = formatter.format_1_to_1_title(name, suffix)
|
|
376
|
+
dst = create_signal(title=title, units=units, labels=labels)
|
|
377
|
+
if suffix is not None:
|
|
378
|
+
dst.title += "|" + suffix
|
|
379
|
+
if (source := src.metadata.get("source")) is not None:
|
|
380
|
+
dst.metadata["source"] = source
|
|
381
|
+
return dst
|