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
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
I/O signal formats
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
import pandas as pd
|
|
11
|
+
import scipy.io as sio
|
|
12
|
+
from guidata.io import HDF5Reader, HDF5Writer
|
|
13
|
+
|
|
14
|
+
from sigima.config import _
|
|
15
|
+
from sigima.io import ftlab
|
|
16
|
+
from sigima.io.base import FormatInfo
|
|
17
|
+
from sigima.io.common.converters import convert_array_to_valid_dtype
|
|
18
|
+
from sigima.io.signal import funcs
|
|
19
|
+
from sigima.io.signal.base import SignalFormatBase
|
|
20
|
+
from sigima.objects.signal import SignalObj
|
|
21
|
+
from sigima.objects.signal.constants import (
|
|
22
|
+
DATETIME_X_FORMAT_KEY,
|
|
23
|
+
DEFAULT_DATETIME_FORMAT,
|
|
24
|
+
)
|
|
25
|
+
from sigima.worker import CallbackWorkerProtocol
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class HDF5SignalFormat(SignalFormatBase):
|
|
29
|
+
"""Object representing a HDF5 signal file type"""
|
|
30
|
+
|
|
31
|
+
FORMAT_INFO = FormatInfo(
|
|
32
|
+
name=_("HDF5 files"),
|
|
33
|
+
extensions="*.h5sig",
|
|
34
|
+
readable=True,
|
|
35
|
+
writeable=True,
|
|
36
|
+
)
|
|
37
|
+
GROUP_NAME = "signal"
|
|
38
|
+
|
|
39
|
+
def read(
|
|
40
|
+
self, filename: str, worker: CallbackWorkerProtocol | None = None
|
|
41
|
+
) -> list[SignalObj]:
|
|
42
|
+
"""Read list of signal objects from file
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
filename: File name
|
|
46
|
+
worker: Callback worker object
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
List of signal objects
|
|
50
|
+
"""
|
|
51
|
+
reader = HDF5Reader(filename)
|
|
52
|
+
try:
|
|
53
|
+
with reader.group(self.GROUP_NAME):
|
|
54
|
+
obj = SignalObj()
|
|
55
|
+
obj.deserialize(reader)
|
|
56
|
+
except ValueError as exc:
|
|
57
|
+
raise ValueError("No valid signal data found") from exc
|
|
58
|
+
except Exception as exc: # pylint: disable=broad-except
|
|
59
|
+
raise RuntimeError(
|
|
60
|
+
f"Unexpected error reading HDF5 signal from {filename}"
|
|
61
|
+
) from exc
|
|
62
|
+
finally:
|
|
63
|
+
reader.close()
|
|
64
|
+
return [obj]
|
|
65
|
+
|
|
66
|
+
def write(self, filename: str, obj: SignalObj) -> None:
|
|
67
|
+
"""Write data to file
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
filename: Name of file to write
|
|
71
|
+
obj: Signal object to read data from
|
|
72
|
+
"""
|
|
73
|
+
assert isinstance(obj, SignalObj), "Object is not a signal"
|
|
74
|
+
writer = HDF5Writer(filename)
|
|
75
|
+
with writer.group(self.GROUP_NAME):
|
|
76
|
+
obj.serialize(writer)
|
|
77
|
+
writer.close()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class CSVSignalFormat(SignalFormatBase):
|
|
81
|
+
"""Object representing a CSV signal file type"""
|
|
82
|
+
|
|
83
|
+
FORMAT_INFO = FormatInfo(
|
|
84
|
+
name=_("CSV files"),
|
|
85
|
+
extensions="*.csv *.txt",
|
|
86
|
+
readable=True,
|
|
87
|
+
writeable=True,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def read(
|
|
91
|
+
self, filename: str, worker: CallbackWorkerProtocol | None = None
|
|
92
|
+
) -> list[SignalObj]:
|
|
93
|
+
"""Read list of signal objects from file
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
filename: File name
|
|
97
|
+
worker: Callback worker object
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
List of signal objects
|
|
101
|
+
"""
|
|
102
|
+
csv_data = funcs.read_csv(filename, worker)
|
|
103
|
+
|
|
104
|
+
if csv_data.ylabels:
|
|
105
|
+
# If y labels are present, we are sure that the data contains at least
|
|
106
|
+
# two columns (x and y)
|
|
107
|
+
objs = []
|
|
108
|
+
for i, (ylabel, yunit) in enumerate(zip(csv_data.ylabels, csv_data.yunits)):
|
|
109
|
+
obj = self.create_object(
|
|
110
|
+
filename, i if len(csv_data.ylabels) > 1 else None
|
|
111
|
+
)
|
|
112
|
+
obj.set_xydata(csv_data.xydata[:, 0], csv_data.xydata[:, i + 1])
|
|
113
|
+
obj.xlabel = csv_data.xlabel or ""
|
|
114
|
+
# Set xunit, defaulting to 's' if datetime signal and no unit specified
|
|
115
|
+
if csv_data.datetime_metadata and not csv_data.xunit:
|
|
116
|
+
obj.xunit = "s" # Default unit for datetime signals
|
|
117
|
+
else:
|
|
118
|
+
obj.xunit = csv_data.xunit or ""
|
|
119
|
+
obj.ylabel = ylabel or ""
|
|
120
|
+
obj.yunit = yunit or ""
|
|
121
|
+
if csv_data.header:
|
|
122
|
+
obj.metadata[self.HEADER_KEY] = csv_data.header
|
|
123
|
+
# Add datetime metadata if detected
|
|
124
|
+
if csv_data.datetime_metadata:
|
|
125
|
+
obj.metadata.update(csv_data.datetime_metadata)
|
|
126
|
+
# Add column metadata (constant-value columns like serial numbers)
|
|
127
|
+
if csv_data.column_metadata:
|
|
128
|
+
obj.metadata.update(csv_data.column_metadata)
|
|
129
|
+
objs.append(obj)
|
|
130
|
+
return objs
|
|
131
|
+
return self.create_signals_from(csv_data.xydata, filename)
|
|
132
|
+
|
|
133
|
+
def write(self, filename: str, obj: SignalObj) -> None:
|
|
134
|
+
"""Write data to file
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
filename: Name of file to write
|
|
138
|
+
obj: Signal object to read data from
|
|
139
|
+
"""
|
|
140
|
+
# If X is datetime, convert back to datetime strings for CSV
|
|
141
|
+
if obj.is_x_datetime():
|
|
142
|
+
datetime_values = obj.get_x_as_datetime()
|
|
143
|
+
# Convert to strings with appropriate format
|
|
144
|
+
datetime_format = obj.metadata.get(
|
|
145
|
+
DATETIME_X_FORMAT_KEY, DEFAULT_DATETIME_FORMAT
|
|
146
|
+
)
|
|
147
|
+
x_data = pd.to_datetime(datetime_values).strftime(datetime_format).values
|
|
148
|
+
# Create modified xydata with datetime strings in X column
|
|
149
|
+
# We'll write manually with pandas to preserve datetime strings
|
|
150
|
+
data_dict = {obj.xlabel or "Time": x_data, obj.ylabel or "Y": obj.y}
|
|
151
|
+
df = pd.DataFrame(data_dict)
|
|
152
|
+
df.to_csv(filename, index=False)
|
|
153
|
+
else:
|
|
154
|
+
funcs.write_csv(
|
|
155
|
+
filename,
|
|
156
|
+
obj.xydata,
|
|
157
|
+
obj.xlabel,
|
|
158
|
+
obj.xunit,
|
|
159
|
+
[obj.ylabel],
|
|
160
|
+
[obj.yunit],
|
|
161
|
+
obj.metadata.get(self.HEADER_KEY, ""),
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class NumPySignalFormat(SignalFormatBase):
|
|
166
|
+
"""Object representing a NumPy signal file type"""
|
|
167
|
+
|
|
168
|
+
FORMAT_INFO = FormatInfo(
|
|
169
|
+
name=_("NumPy binary files"),
|
|
170
|
+
extensions="*.npy",
|
|
171
|
+
readable=True,
|
|
172
|
+
writeable=True,
|
|
173
|
+
) # pylint: disable=duplicate-code
|
|
174
|
+
|
|
175
|
+
def read_xydata(self, filename: str) -> np.ndarray:
|
|
176
|
+
"""Read data and metadata from file, write metadata to object, return xydata
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
filename: Name of file to read
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
NumPy array xydata
|
|
183
|
+
"""
|
|
184
|
+
return convert_array_to_valid_dtype(np.load(filename), SignalObj.VALID_DTYPES)
|
|
185
|
+
|
|
186
|
+
def write(self, filename: str, obj: SignalObj) -> None:
|
|
187
|
+
"""Write data to file
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
filename: Name of file to write
|
|
191
|
+
obj: Signal object to read data from
|
|
192
|
+
"""
|
|
193
|
+
np.save(filename, obj.xydata.T)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
class MatSignalFormat(SignalFormatBase):
|
|
197
|
+
"""Object representing a MAT-File .mat signal file type"""
|
|
198
|
+
|
|
199
|
+
FORMAT_INFO = FormatInfo(
|
|
200
|
+
name=_("MAT-Files"),
|
|
201
|
+
extensions="*.mat",
|
|
202
|
+
readable=True,
|
|
203
|
+
writeable=True,
|
|
204
|
+
) # pylint: disable=duplicate-code
|
|
205
|
+
|
|
206
|
+
def read(
|
|
207
|
+
self, filename: str, worker: CallbackWorkerProtocol | None = None
|
|
208
|
+
) -> list[SignalObj]:
|
|
209
|
+
"""Read data and metadata from file, write metadata to object, return xydata
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
filename: Name of file to read
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
NumPy array xydata
|
|
216
|
+
"""
|
|
217
|
+
mat = sio.loadmat(filename)
|
|
218
|
+
allsig: list[SignalObj] = []
|
|
219
|
+
for dname, data in mat.items():
|
|
220
|
+
if dname.startswith("__") or not isinstance(data, np.ndarray):
|
|
221
|
+
continue
|
|
222
|
+
for sig in self.create_signals_from(data.squeeze(), filename):
|
|
223
|
+
if dname != "sig":
|
|
224
|
+
sig.title += f" ({dname})"
|
|
225
|
+
allsig.append(sig)
|
|
226
|
+
return allsig
|
|
227
|
+
|
|
228
|
+
def write(self, filename: str, obj: SignalObj) -> None:
|
|
229
|
+
"""Write data to file
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
filename: Name of file to write
|
|
233
|
+
obj: Signal object to read data from
|
|
234
|
+
"""
|
|
235
|
+
# metadata cannot be saved as such as their type will be lost and
|
|
236
|
+
# cause problems when reading the file back
|
|
237
|
+
sio.savemat(filename, {"sig": obj.xydata.T})
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class FTLabSignalFormat(SignalFormatBase):
|
|
241
|
+
"""FT-Lab signal file."""
|
|
242
|
+
|
|
243
|
+
FORMAT_INFO = FormatInfo(
|
|
244
|
+
name=_("FT-Lab"),
|
|
245
|
+
extensions="*.sig",
|
|
246
|
+
readable=True,
|
|
247
|
+
writeable=False,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
def read_xydata(self, filename: str) -> np.ndarray:
|
|
251
|
+
"""Read data and metadata from file, populate metadata, return xydata.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
filename: Path to FT-Lab file.
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
Signal data.
|
|
258
|
+
"""
|
|
259
|
+
return ftlab.sigread_ftlabsig(filename)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class MCASignalFormat(SignalFormatBase):
|
|
263
|
+
"""Object representing a MCA signal file type"""
|
|
264
|
+
|
|
265
|
+
FORMAT_INFO = FormatInfo(
|
|
266
|
+
name=_("MCA files"),
|
|
267
|
+
extensions="*.mca",
|
|
268
|
+
readable=True,
|
|
269
|
+
writeable=False,
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
def read(
|
|
273
|
+
self, filename: str, worker: CallbackWorkerProtocol | None = None
|
|
274
|
+
) -> list[SignalObj]:
|
|
275
|
+
"""Read list of signal objects from file
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
filename: File name
|
|
279
|
+
worker: Callback worker object
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
List of signal objects
|
|
283
|
+
"""
|
|
284
|
+
mca = funcs.MCAFile(filename)
|
|
285
|
+
mca.read()
|
|
286
|
+
obj = self.create_object(filename)
|
|
287
|
+
obj.set_xydata(mca.x, mca.y)
|
|
288
|
+
obj.xlabel = mca.xlabel or ""
|
|
289
|
+
obj.metadata = mca.metadata
|
|
290
|
+
return [obj]
|