dclab 0.67.0__cp314-cp314-macosx_10_13_x86_64.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.
Potentially problematic release.
This version of dclab might be problematic. Click here for more details.
- dclab/__init__.py +41 -0
- dclab/_version.py +34 -0
- dclab/cached.py +97 -0
- dclab/cli/__init__.py +10 -0
- dclab/cli/common.py +237 -0
- dclab/cli/task_compress.py +126 -0
- dclab/cli/task_condense.py +223 -0
- dclab/cli/task_join.py +229 -0
- dclab/cli/task_repack.py +98 -0
- dclab/cli/task_split.py +154 -0
- dclab/cli/task_tdms2rtdc.py +186 -0
- dclab/cli/task_verify_dataset.py +75 -0
- dclab/definitions/__init__.py +79 -0
- dclab/definitions/feat_const.py +202 -0
- dclab/definitions/feat_logic.py +182 -0
- dclab/definitions/meta_const.py +252 -0
- dclab/definitions/meta_logic.py +111 -0
- dclab/definitions/meta_parse.py +94 -0
- dclab/downsampling.cpython-314-darwin.so +0 -0
- dclab/downsampling.pyx +230 -0
- dclab/external/__init__.py +4 -0
- dclab/external/packaging/LICENSE +3 -0
- dclab/external/packaging/LICENSE.APACHE +177 -0
- dclab/external/packaging/LICENSE.BSD +23 -0
- dclab/external/packaging/__init__.py +6 -0
- dclab/external/packaging/_structures.py +61 -0
- dclab/external/packaging/version.py +505 -0
- dclab/external/skimage/LICENSE +28 -0
- dclab/external/skimage/__init__.py +2 -0
- dclab/external/skimage/_find_contours.py +216 -0
- dclab/external/skimage/_find_contours_cy.cpython-314-darwin.so +0 -0
- dclab/external/skimage/_find_contours_cy.pyx +188 -0
- dclab/external/skimage/_pnpoly.cpython-314-darwin.so +0 -0
- dclab/external/skimage/_pnpoly.pyx +99 -0
- dclab/external/skimage/_shared/__init__.py +1 -0
- dclab/external/skimage/_shared/geometry.cpython-314-darwin.so +0 -0
- dclab/external/skimage/_shared/geometry.pxd +6 -0
- dclab/external/skimage/_shared/geometry.pyx +55 -0
- dclab/external/skimage/measure.py +7 -0
- dclab/external/skimage/pnpoly.py +53 -0
- dclab/external/statsmodels/LICENSE +35 -0
- dclab/external/statsmodels/__init__.py +6 -0
- dclab/external/statsmodels/nonparametric/__init__.py +1 -0
- dclab/external/statsmodels/nonparametric/_kernel_base.py +203 -0
- dclab/external/statsmodels/nonparametric/kernel_density.py +165 -0
- dclab/external/statsmodels/nonparametric/kernels.py +36 -0
- dclab/features/__init__.py +9 -0
- dclab/features/bright.py +81 -0
- dclab/features/bright_bc.py +93 -0
- dclab/features/bright_perc.py +63 -0
- dclab/features/contour.py +161 -0
- dclab/features/emodulus/__init__.py +339 -0
- dclab/features/emodulus/load.py +252 -0
- dclab/features/emodulus/lut_HE-2D-FEM-22.txt +16432 -0
- dclab/features/emodulus/lut_HE-3D-FEM-22.txt +1276 -0
- dclab/features/emodulus/lut_LE-2D-FEM-19.txt +13082 -0
- dclab/features/emodulus/pxcorr.py +135 -0
- dclab/features/emodulus/scale_linear.py +247 -0
- dclab/features/emodulus/viscosity.py +260 -0
- dclab/features/fl_crosstalk.py +95 -0
- dclab/features/inert_ratio.py +377 -0
- dclab/features/volume.py +242 -0
- dclab/http_utils.py +322 -0
- dclab/isoelastics/__init__.py +468 -0
- dclab/isoelastics/iso_HE-2D-FEM-22-area_um-deform.txt +2440 -0
- dclab/isoelastics/iso_HE-2D-FEM-22-volume-deform.txt +2635 -0
- dclab/isoelastics/iso_HE-3D-FEM-22-area_um-deform.txt +1930 -0
- dclab/isoelastics/iso_HE-3D-FEM-22-volume-deform.txt +2221 -0
- dclab/isoelastics/iso_LE-2D-FEM-19-area_um-deform.txt +2151 -0
- dclab/isoelastics/iso_LE-2D-FEM-19-volume-deform.txt +2250 -0
- dclab/isoelastics/iso_LE-2D-ana-18-area_um-deform.txt +1266 -0
- dclab/kde/__init__.py +1 -0
- dclab/kde/base.py +459 -0
- dclab/kde/contours.py +222 -0
- dclab/kde/methods.py +313 -0
- dclab/kde_contours.py +10 -0
- dclab/kde_methods.py +11 -0
- dclab/lme4/__init__.py +5 -0
- dclab/lme4/lme4_template.R +94 -0
- dclab/lme4/rsetup.py +204 -0
- dclab/lme4/wrapr.py +386 -0
- dclab/polygon_filter.py +398 -0
- dclab/rtdc_dataset/__init__.py +15 -0
- dclab/rtdc_dataset/check.py +902 -0
- dclab/rtdc_dataset/config.py +533 -0
- dclab/rtdc_dataset/copier.py +353 -0
- dclab/rtdc_dataset/core.py +896 -0
- dclab/rtdc_dataset/export.py +867 -0
- dclab/rtdc_dataset/feat_anc_core/__init__.py +24 -0
- dclab/rtdc_dataset/feat_anc_core/af_basic.py +75 -0
- dclab/rtdc_dataset/feat_anc_core/af_emodulus.py +160 -0
- dclab/rtdc_dataset/feat_anc_core/af_fl_max_ctc.py +133 -0
- dclab/rtdc_dataset/feat_anc_core/af_image_contour.py +113 -0
- dclab/rtdc_dataset/feat_anc_core/af_ml_class.py +102 -0
- dclab/rtdc_dataset/feat_anc_core/ancillary_feature.py +320 -0
- dclab/rtdc_dataset/feat_anc_ml/__init__.py +32 -0
- dclab/rtdc_dataset/feat_anc_plugin/__init__.py +3 -0
- dclab/rtdc_dataset/feat_anc_plugin/plugin_feature.py +329 -0
- dclab/rtdc_dataset/feat_basin.py +762 -0
- dclab/rtdc_dataset/feat_temp.py +102 -0
- dclab/rtdc_dataset/filter.py +263 -0
- dclab/rtdc_dataset/fmt_dcor/__init__.py +7 -0
- dclab/rtdc_dataset/fmt_dcor/access_token.py +52 -0
- dclab/rtdc_dataset/fmt_dcor/api.py +173 -0
- dclab/rtdc_dataset/fmt_dcor/base.py +299 -0
- dclab/rtdc_dataset/fmt_dcor/basin.py +73 -0
- dclab/rtdc_dataset/fmt_dcor/logs.py +26 -0
- dclab/rtdc_dataset/fmt_dcor/tables.py +66 -0
- dclab/rtdc_dataset/fmt_dict.py +103 -0
- dclab/rtdc_dataset/fmt_hdf5/__init__.py +6 -0
- dclab/rtdc_dataset/fmt_hdf5/base.py +192 -0
- dclab/rtdc_dataset/fmt_hdf5/basin.py +30 -0
- dclab/rtdc_dataset/fmt_hdf5/events.py +276 -0
- dclab/rtdc_dataset/fmt_hdf5/feat_defect.py +164 -0
- dclab/rtdc_dataset/fmt_hdf5/logs.py +33 -0
- dclab/rtdc_dataset/fmt_hdf5/tables.py +60 -0
- dclab/rtdc_dataset/fmt_hierarchy/__init__.py +11 -0
- dclab/rtdc_dataset/fmt_hierarchy/base.py +278 -0
- dclab/rtdc_dataset/fmt_hierarchy/events.py +146 -0
- dclab/rtdc_dataset/fmt_hierarchy/hfilter.py +140 -0
- dclab/rtdc_dataset/fmt_hierarchy/mapper.py +134 -0
- dclab/rtdc_dataset/fmt_http.py +102 -0
- dclab/rtdc_dataset/fmt_s3.py +354 -0
- dclab/rtdc_dataset/fmt_tdms/__init__.py +476 -0
- dclab/rtdc_dataset/fmt_tdms/event_contour.py +264 -0
- dclab/rtdc_dataset/fmt_tdms/event_image.py +220 -0
- dclab/rtdc_dataset/fmt_tdms/event_mask.py +62 -0
- dclab/rtdc_dataset/fmt_tdms/event_trace.py +146 -0
- dclab/rtdc_dataset/fmt_tdms/exc.py +37 -0
- dclab/rtdc_dataset/fmt_tdms/naming.py +151 -0
- dclab/rtdc_dataset/load.py +77 -0
- dclab/rtdc_dataset/meta_table.py +25 -0
- dclab/rtdc_dataset/writer.py +1019 -0
- dclab/statistics.py +226 -0
- dclab/util.py +176 -0
- dclab/warn.py +15 -0
- dclab-0.67.0.dist-info/METADATA +153 -0
- dclab-0.67.0.dist-info/RECORD +142 -0
- dclab-0.67.0.dist-info/WHEEL +6 -0
- dclab-0.67.0.dist-info/entry_points.txt +8 -0
- dclab-0.67.0.dist-info/licenses/LICENSE +283 -0
- dclab-0.67.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import atexit
|
|
4
|
+
from contextlib import ExitStack
|
|
5
|
+
import copy
|
|
6
|
+
import functools
|
|
7
|
+
import json
|
|
8
|
+
import pathlib
|
|
9
|
+
# replace this import when dropping support for Python 3.8
|
|
10
|
+
# from importlib import resources as importlib_resources
|
|
11
|
+
import importlib_resources
|
|
12
|
+
import warnings
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
from ... import definitions as dfn
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
_file_manager = ExitStack()
|
|
20
|
+
atexit.register(_file_manager.close)
|
|
21
|
+
|
|
22
|
+
#: Dictionary of look-up tables that the user added via :func:`register_lut`.
|
|
23
|
+
EXTERNAL_LUTS = {}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@functools.lru_cache()
|
|
27
|
+
def get_internal_lut_names_dict():
|
|
28
|
+
"""Return list of internal lut names"""
|
|
29
|
+
lutfiles = {}
|
|
30
|
+
for pp in importlib_resources.files('dclab.features.emodulus').iterdir():
|
|
31
|
+
name = pp.name
|
|
32
|
+
if name.startswith("lut_") and name.endswith(".txt"):
|
|
33
|
+
lutfiles[name[4:-4]] = name
|
|
34
|
+
return lutfiles
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_lut_path(path_or_id):
|
|
38
|
+
"""Find the path to a LUT
|
|
39
|
+
|
|
40
|
+
path_or_id: str or pathlib.Path
|
|
41
|
+
Identifier of a LUT. This can be either an existing path
|
|
42
|
+
(checked first), or an internal identifier (see
|
|
43
|
+
:func:`get_internal_lut_names_dict`).
|
|
44
|
+
"""
|
|
45
|
+
internal_dict = get_internal_lut_names_dict()
|
|
46
|
+
if path_or_id == "FEM-2Daxis":
|
|
47
|
+
# backwards compatibility
|
|
48
|
+
warnings.warn("'FEM-2Daxis' is deprecated. Please use 'LE-2D-FEM-19'!",
|
|
49
|
+
DeprecationWarning)
|
|
50
|
+
path_or_id = "LE-2D-FEM-19"
|
|
51
|
+
if pathlib.Path(path_or_id).exists():
|
|
52
|
+
lut_path = pathlib.Path(path_or_id)
|
|
53
|
+
elif path_or_id in internal_dict:
|
|
54
|
+
ref = importlib_resources.files(
|
|
55
|
+
"dclab.features.emodulus") / internal_dict[path_or_id]
|
|
56
|
+
lut_path = _file_manager.enter_context(
|
|
57
|
+
importlib_resources.as_file(ref))
|
|
58
|
+
elif path_or_id in EXTERNAL_LUTS:
|
|
59
|
+
lut_path = EXTERNAL_LUTS[path_or_id]
|
|
60
|
+
else:
|
|
61
|
+
raise ValueError("File or LUT identifier does not exist: "
|
|
62
|
+
+ "'{}'".format(path_or_id))
|
|
63
|
+
return lut_path
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def load_lut(lut_data: str | pathlib.Path | np.ndarray = "LE-2D-FEM-19"):
|
|
67
|
+
"""Load LUT data from disk
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
lut_data: path, str, or tuple of (np.ndarray of shape (N, 3), dict)
|
|
72
|
+
The LUT data to use. If it is in :func:`get_internal_lut_names_dict()`,
|
|
73
|
+
then the respective LUT will be used. Otherwise, a path to a
|
|
74
|
+
file on disk or a tuple (LUT array, metadata) is possible.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
lut: np.ndarray of shape (N, 3)
|
|
79
|
+
The LUT data for interpolation
|
|
80
|
+
meta: dict
|
|
81
|
+
The LUT metadata
|
|
82
|
+
|
|
83
|
+
Notes
|
|
84
|
+
-----
|
|
85
|
+
If lut_data is a tuple of (lut, meta), then nothing is actually
|
|
86
|
+
done (this is implemented for user convenience).
|
|
87
|
+
"""
|
|
88
|
+
if isinstance(lut_data, tuple):
|
|
89
|
+
lut, meta = lut_data
|
|
90
|
+
lut = np.array(lut, copy=True) # copy, because of normalization
|
|
91
|
+
meta = copy.deepcopy(meta) # copy, for the sake of consistency
|
|
92
|
+
elif isinstance(lut_data, (str, pathlib.Path)):
|
|
93
|
+
lut_path = get_lut_path(lut_data)
|
|
94
|
+
lut, meta = load_mtext(lut_path)
|
|
95
|
+
else:
|
|
96
|
+
raise ValueError("`name_path_arr` must be path, identifier, or tuple "
|
|
97
|
+
f"of (array, dict), got '{lut_data}'!")
|
|
98
|
+
return lut, meta
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def load_mtext(path):
|
|
102
|
+
"""Load column-based data from text files with metadata
|
|
103
|
+
|
|
104
|
+
This file format is used for isoelasticity lines and look-up
|
|
105
|
+
table data in dclab.
|
|
106
|
+
|
|
107
|
+
The text file is loaded with `numpy.loadtxt`. The metadata
|
|
108
|
+
are stored as a json string between the "BEGIN METADATA" and
|
|
109
|
+
the "END METADATA" tags. The last comment (#) line before the
|
|
110
|
+
actual data defines the features with units in square
|
|
111
|
+
brackets and tab-separated. For instance:
|
|
112
|
+
|
|
113
|
+
# [...]
|
|
114
|
+
#
|
|
115
|
+
# BEGIN METADATA
|
|
116
|
+
# {
|
|
117
|
+
# "authors": "A. Mietke, C. Herold, J. Guck",
|
|
118
|
+
# "channel_width": 20.0,
|
|
119
|
+
# "channel_width_unit": "um",
|
|
120
|
+
# "date": "2018-01-30",
|
|
121
|
+
# "dimensionality": "2Daxis",
|
|
122
|
+
# "flow_rate": 0.04,
|
|
123
|
+
# "flow_rate_unit": "uL/s",
|
|
124
|
+
# "fluid_viscosity": 15.0,
|
|
125
|
+
# "fluid_viscosity_unit": "mPa s",
|
|
126
|
+
# "identifier": "LE-2D-ana-18",
|
|
127
|
+
# "method": "analytical",
|
|
128
|
+
# "model": "linear elastic",
|
|
129
|
+
# "publication": "https://doi.org/10.1016/j.bpj.2015.09.006",
|
|
130
|
+
# "software": "custom Matlab code",
|
|
131
|
+
# "summary": "2D-axis-symmetric analytical solution"
|
|
132
|
+
# }
|
|
133
|
+
# END METADATA
|
|
134
|
+
#
|
|
135
|
+
# [...]
|
|
136
|
+
#
|
|
137
|
+
# area_um [um^2] deform emodulus [kPa]
|
|
138
|
+
3.75331e+00 5.14496e-03 9.30000e-01
|
|
139
|
+
4.90368e+00 6.72683e-03 9.30000e-01
|
|
140
|
+
6.05279e+00 8.30946e-03 9.30000e-01
|
|
141
|
+
7.20064e+00 9.89298e-03 9.30000e-01
|
|
142
|
+
[...]
|
|
143
|
+
"""
|
|
144
|
+
path = pathlib.Path(path).resolve()
|
|
145
|
+
|
|
146
|
+
# Parse metadata
|
|
147
|
+
size = path.stat().st_size
|
|
148
|
+
dump = []
|
|
149
|
+
injson = False
|
|
150
|
+
prev_line = ""
|
|
151
|
+
with path.open("r", errors='replace') as fd:
|
|
152
|
+
while True:
|
|
153
|
+
line = fd.readline()
|
|
154
|
+
if fd.tell() == size:
|
|
155
|
+
# something went wrong
|
|
156
|
+
raise ValueError("EOF: Could not parse '{}'!".format(path))
|
|
157
|
+
elif len(line.strip()) == 0:
|
|
158
|
+
# ignore empty lines
|
|
159
|
+
continue
|
|
160
|
+
elif not line.strip().startswith("#"):
|
|
161
|
+
# we are done here
|
|
162
|
+
if prev_line == "":
|
|
163
|
+
raise ValueError("No column header in '{}'!".format(
|
|
164
|
+
path))
|
|
165
|
+
break
|
|
166
|
+
elif line.startswith("# BEGIN METADATA"):
|
|
167
|
+
injson = True
|
|
168
|
+
continue
|
|
169
|
+
elif line.startswith("# END METADATA"):
|
|
170
|
+
injson = False
|
|
171
|
+
if injson:
|
|
172
|
+
dump.append(line.strip("#").strip())
|
|
173
|
+
else:
|
|
174
|
+
# remember last line for header
|
|
175
|
+
prev_line = line
|
|
176
|
+
# metadata
|
|
177
|
+
if dump:
|
|
178
|
+
meta = json.loads("\n".join(dump))
|
|
179
|
+
else:
|
|
180
|
+
raise ValueError("No metadata json dump in '{}'!".format(path))
|
|
181
|
+
# header
|
|
182
|
+
feats = []
|
|
183
|
+
units = []
|
|
184
|
+
for hh in prev_line.strip("# ").split("\t"):
|
|
185
|
+
if hh.count(" "):
|
|
186
|
+
ft, un = hh.strip().split(" ")
|
|
187
|
+
un = un.strip("[]")
|
|
188
|
+
else:
|
|
189
|
+
ft = hh
|
|
190
|
+
un = ""
|
|
191
|
+
if not dfn.scalar_feature_exists(ft):
|
|
192
|
+
raise ValueError("Scalar feature not known: '{}'".format(ft))
|
|
193
|
+
feats.append(ft)
|
|
194
|
+
units.append(un)
|
|
195
|
+
# data
|
|
196
|
+
data = np.loadtxt(path)
|
|
197
|
+
|
|
198
|
+
meta["column features"] = feats
|
|
199
|
+
meta["column units"] = units
|
|
200
|
+
|
|
201
|
+
# sanity checks
|
|
202
|
+
assert meta["channel_width_unit"] == "um"
|
|
203
|
+
assert meta["flow_rate_unit"] == "uL/s"
|
|
204
|
+
assert meta["fluid_viscosity_unit"] == "mPa s"
|
|
205
|
+
for ft, un in zip(feats, units):
|
|
206
|
+
if ft == "deform":
|
|
207
|
+
assert un == ""
|
|
208
|
+
elif ft == "area_um":
|
|
209
|
+
assert un == "um^2"
|
|
210
|
+
elif ft == "emodulus":
|
|
211
|
+
assert un == "kPa"
|
|
212
|
+
elif ft == "volume":
|
|
213
|
+
assert un == "um^3"
|
|
214
|
+
else:
|
|
215
|
+
assert False, "Please add sanity check for {}!".format(ft)
|
|
216
|
+
|
|
217
|
+
return data, meta
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def register_lut(path, identifier=None):
|
|
221
|
+
"""Register an external LUT file in dclab
|
|
222
|
+
|
|
223
|
+
This will add it to :const:`EXTERNAL_LUTS`, which is required
|
|
224
|
+
for emodulus computation as an ancillary feature.
|
|
225
|
+
|
|
226
|
+
Parameters
|
|
227
|
+
----------
|
|
228
|
+
path: str or pathlib.Path
|
|
229
|
+
Path to the external LUT file
|
|
230
|
+
identifier: str or None
|
|
231
|
+
The identifier is used for ancillary emodulus computation
|
|
232
|
+
via the [calculation]: "emodulus lut" key. It is also used as
|
|
233
|
+
the key in :const:`EXTERNAL_LUTS` during registration. If not
|
|
234
|
+
specified, (default) then the identifier given as JSON metadata
|
|
235
|
+
in `path` is used.
|
|
236
|
+
"""
|
|
237
|
+
if identifier is None:
|
|
238
|
+
_, md = load_mtext(path)
|
|
239
|
+
try:
|
|
240
|
+
identifier = md["identifier"]
|
|
241
|
+
except KeyError:
|
|
242
|
+
raise ValueError("The given LUT file '{}' does ".format(path)
|
|
243
|
+
+ "not contain the 'identifier' keyword. You may "
|
|
244
|
+
+ "specify it via the `identifier` keyword to "
|
|
245
|
+
+ "this function.")
|
|
246
|
+
if identifier in EXTERNAL_LUTS:
|
|
247
|
+
raise ValueError("A LUT with an identifier '{}' ".format(identifier)
|
|
248
|
+
+ "has already been registered!")
|
|
249
|
+
elif identifier in get_internal_lut_names_dict():
|
|
250
|
+
raise ValueError("The identifier '{}' is already ".format(identifier)
|
|
251
|
+
+ "in use by an internal LUT!")
|
|
252
|
+
EXTERNAL_LUTS[identifier] = path
|