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,468 @@
|
|
|
1
|
+
"""Isoelastics management"""
|
|
2
|
+
import collections
|
|
3
|
+
from contextlib import ExitStack
|
|
4
|
+
import functools
|
|
5
|
+
# replace this import when dropping support for Python 3.8
|
|
6
|
+
# from importlib import resources as importlib_resources
|
|
7
|
+
import importlib_resources
|
|
8
|
+
import warnings
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
from .. import definitions as dfn
|
|
13
|
+
from ..features import emodulus as feat_emod
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class IsoelasticsEmodulusMeaninglessWarning(UserWarning):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Isoelastics(object):
|
|
21
|
+
def __init__(self, paths=None):
|
|
22
|
+
"""Isoelasticity line management
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
paths: list of pathlib.Path or list of str
|
|
27
|
+
list of paths to files containing isoelasticity lines
|
|
28
|
+
|
|
29
|
+
.. versionchanged:: 0.24.0
|
|
30
|
+
The isoelasticity lines of the analytical model
|
|
31
|
+
:cite:`Mietke2015` and the linear-elastic numerical
|
|
32
|
+
model :cite:`Mokbel2017` were recomputed with an
|
|
33
|
+
equidistant spacing. The metadata section of the text
|
|
34
|
+
file format was restructured.
|
|
35
|
+
"""
|
|
36
|
+
if paths is None:
|
|
37
|
+
paths = []
|
|
38
|
+
self._data = AutoRecursiveDict()
|
|
39
|
+
|
|
40
|
+
for path in paths:
|
|
41
|
+
self.load_data(path)
|
|
42
|
+
|
|
43
|
+
def _add(self, isoel, col1, col2, lut_identifier, meta):
|
|
44
|
+
"""Convenience method for population self._data"""
|
|
45
|
+
self._data[lut_identifier][col1][col2]["isoelastics"] = isoel
|
|
46
|
+
self._data[lut_identifier][col1][col2]["meta"] = meta
|
|
47
|
+
|
|
48
|
+
# Use advanced slicing to flip the data columns
|
|
49
|
+
isoel_flip = [iso[:, [1, 0, 2]] for iso in isoel]
|
|
50
|
+
self._data[lut_identifier][col2][col1]["isoelastics"] = isoel_flip
|
|
51
|
+
self._data[lut_identifier][col2][col1]["meta"] = meta
|
|
52
|
+
|
|
53
|
+
def add(self, isoel, col1, col2, channel_width,
|
|
54
|
+
flow_rate, viscosity, method=None,
|
|
55
|
+
lut_identifier=None):
|
|
56
|
+
"""Add isoelastics
|
|
57
|
+
|
|
58
|
+
Parameters
|
|
59
|
+
----------
|
|
60
|
+
isoel: list of ndarrays
|
|
61
|
+
Each list item resembles one isoelastic line stored
|
|
62
|
+
as an array of shape (N,3). The last column contains
|
|
63
|
+
the emodulus data.
|
|
64
|
+
col1: str
|
|
65
|
+
Name of the first feature of all isoelastics
|
|
66
|
+
(e.g. isoel[0][:,0])
|
|
67
|
+
col2: str
|
|
68
|
+
Name of the second feature of all isoelastics
|
|
69
|
+
(e.g. isoel[0][:,1])
|
|
70
|
+
channel_width: float
|
|
71
|
+
Channel width in µm
|
|
72
|
+
flow_rate: float
|
|
73
|
+
Flow rate through the channel in µL/s
|
|
74
|
+
viscosity: float
|
|
75
|
+
Viscosity of the medium in mPa*s
|
|
76
|
+
method: str
|
|
77
|
+
The method used to compute the isoelastics
|
|
78
|
+
DEPRECATED since 0.32.0. Please use
|
|
79
|
+
`lut_identifier` instead.
|
|
80
|
+
lut_identifier: str:
|
|
81
|
+
Look-up table identifier used to identify which
|
|
82
|
+
isoelasticity lines to show. The function
|
|
83
|
+
:func:`get_available_identifiers` returns a list
|
|
84
|
+
of available identifiers.
|
|
85
|
+
|
|
86
|
+
Notes
|
|
87
|
+
-----
|
|
88
|
+
The following isoelastics are automatically added for
|
|
89
|
+
user convenience:
|
|
90
|
+
|
|
91
|
+
- isoelastics with `col1` and `col2` interchanged
|
|
92
|
+
- isoelastics for circularity if deformation was given
|
|
93
|
+
"""
|
|
94
|
+
lut_identifier = check_lut_identifier(lut_identifier, method)
|
|
95
|
+
|
|
96
|
+
for col in [col1, col2]:
|
|
97
|
+
if not dfn.scalar_feature_exists(col):
|
|
98
|
+
raise ValueError("Not a valid feature name: {}".format(col))
|
|
99
|
+
|
|
100
|
+
meta = [channel_width, flow_rate, viscosity]
|
|
101
|
+
|
|
102
|
+
# Add the feature data
|
|
103
|
+
self._add(isoel, col1, col2, lut_identifier, meta)
|
|
104
|
+
|
|
105
|
+
# Also add the feature data for circularity
|
|
106
|
+
if "deform" in [col1, col2]:
|
|
107
|
+
col1c, col2c = col1, col2
|
|
108
|
+
if col1c == "deform":
|
|
109
|
+
deform_ax = 0
|
|
110
|
+
col1c = "circ"
|
|
111
|
+
else:
|
|
112
|
+
deform_ax = 1
|
|
113
|
+
col2c = "circ"
|
|
114
|
+
iso_circ = []
|
|
115
|
+
for iso in isoel:
|
|
116
|
+
iso = iso.copy()
|
|
117
|
+
iso[:, deform_ax] = 1 - iso[:, deform_ax]
|
|
118
|
+
iso_circ.append(iso)
|
|
119
|
+
self._add(iso_circ, col1c, col2c, lut_identifier, meta)
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def add_px_err(isoel, col1, col2, px_um, inplace=False):
|
|
123
|
+
"""Undo pixelation correction
|
|
124
|
+
|
|
125
|
+
Since isoelasticity lines are usually computed directly from
|
|
126
|
+
the simulation data (e.g. the contour data are not discretized
|
|
127
|
+
on a grid but are extracted from FEM simulations), they are
|
|
128
|
+
not affected by pixelation effects as described in
|
|
129
|
+
:cite:`Herold2017`.
|
|
130
|
+
|
|
131
|
+
If the isoelasticity lines are displayed alongside experimental
|
|
132
|
+
data (which are affected by pixelation effects), then the lines
|
|
133
|
+
must be "un"-corrected, i.e. the pixelation error must be added
|
|
134
|
+
to the lines to match the experimental data.
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
isoel: list of 2d ndarrays of shape (N, 3)
|
|
139
|
+
Each item in the list corresponds to one isoelasticity
|
|
140
|
+
line. The first column is defined by `col1`, the second
|
|
141
|
+
by `col2`, and the third column is the emodulus.
|
|
142
|
+
col1, col2: str
|
|
143
|
+
Define the fist two columns of each isoelasticity line.
|
|
144
|
+
px_um: float
|
|
145
|
+
Pixel size [µm]
|
|
146
|
+
inplace: bool
|
|
147
|
+
If True, do not create a copy of the data in `isoel`
|
|
148
|
+
"""
|
|
149
|
+
new_isoel = []
|
|
150
|
+
for iso in isoel:
|
|
151
|
+
iso = np.array(iso, copy=not inplace)
|
|
152
|
+
delt1, delt2 = feat_emod.get_pixelation_delta_pair(
|
|
153
|
+
feat1=col1, feat2=col2, data1=iso[:, 0], data2=iso[:, 1],
|
|
154
|
+
px_um=px_um)
|
|
155
|
+
iso[:, 0] += delt1
|
|
156
|
+
iso[:, 1] += delt2
|
|
157
|
+
new_isoel.append(iso)
|
|
158
|
+
return new_isoel
|
|
159
|
+
|
|
160
|
+
@staticmethod
|
|
161
|
+
def convert(isoel, col1, col2,
|
|
162
|
+
channel_width_in, channel_width_out,
|
|
163
|
+
flow_rate_in, flow_rate_out,
|
|
164
|
+
viscosity_in, viscosity_out,
|
|
165
|
+
inplace=False):
|
|
166
|
+
"""Perform isoelastics scale conversion
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
isoel: list of 2d ndarrays of shape (N, 3)
|
|
171
|
+
Each item in the list corresponds to one isoelasticity
|
|
172
|
+
line. The first column is defined by `col1`, the second
|
|
173
|
+
by `col2`, and the third column is the emodulus.
|
|
174
|
+
col1, col2: str
|
|
175
|
+
Define the fist to columns of each isoelasticity line.
|
|
176
|
+
One of ["area_um", "circ", "deform"]
|
|
177
|
+
channel_width_in: float
|
|
178
|
+
Original channel width [µm]
|
|
179
|
+
channel_width_out: float
|
|
180
|
+
Target channel width [µm]
|
|
181
|
+
flow_rate_in: float
|
|
182
|
+
Original flow rate [µL/s]
|
|
183
|
+
flow_rate_out: float
|
|
184
|
+
Target flow rate [µL/s]
|
|
185
|
+
viscosity_in: float
|
|
186
|
+
Original viscosity [mPa*s]
|
|
187
|
+
viscosity_out: float
|
|
188
|
+
Target viscosity [mPa*s]
|
|
189
|
+
inplace: bool
|
|
190
|
+
If True, do not create a copy of the data in `isoel`
|
|
191
|
+
|
|
192
|
+
Returns
|
|
193
|
+
-------
|
|
194
|
+
isoel_scale: list of 2d ndarrays of shape (N, 3)
|
|
195
|
+
The scale-converted isoelasticity lines.
|
|
196
|
+
|
|
197
|
+
Notes
|
|
198
|
+
-----
|
|
199
|
+
If only the positions of the isoelastics are of interest and
|
|
200
|
+
not the value of the elastic modulus, then it is sufficient
|
|
201
|
+
to supply values for the channel width and set the values
|
|
202
|
+
for flow rate and viscosity to a constant (e.g. 1).
|
|
203
|
+
|
|
204
|
+
See Also
|
|
205
|
+
--------
|
|
206
|
+
dclab.features.emodulus.scale_linear.scale_feature: scale
|
|
207
|
+
conversion method used
|
|
208
|
+
"""
|
|
209
|
+
new_isoel = []
|
|
210
|
+
|
|
211
|
+
for iso in isoel:
|
|
212
|
+
iso = np.array(iso, copy=not inplace)
|
|
213
|
+
scale_kw = {"channel_width_in": channel_width_in,
|
|
214
|
+
"channel_width_out": channel_width_out,
|
|
215
|
+
"flow_rate_in": flow_rate_in,
|
|
216
|
+
"flow_rate_out": flow_rate_out,
|
|
217
|
+
"viscosity_in": viscosity_in,
|
|
218
|
+
"viscosity_out": viscosity_out,
|
|
219
|
+
"inplace": True}
|
|
220
|
+
feat_emod.scale_feature(col1, data=iso[:, 0], **scale_kw)
|
|
221
|
+
feat_emod.scale_feature(col2, data=iso[:, 1], **scale_kw)
|
|
222
|
+
feat_emod.scale_emodulus(emodulus=iso[:, 2], **scale_kw)
|
|
223
|
+
new_isoel.append(iso)
|
|
224
|
+
return new_isoel
|
|
225
|
+
|
|
226
|
+
def get(self, col1, col2, channel_width, method=None, lut_identifier=None,
|
|
227
|
+
flow_rate=None, viscosity=None, add_px_err=False, px_um=None):
|
|
228
|
+
"""Get isoelastics
|
|
229
|
+
|
|
230
|
+
Parameters
|
|
231
|
+
----------
|
|
232
|
+
col1: str
|
|
233
|
+
Name of the first feature of all isoelastics
|
|
234
|
+
(e.g. isoel[0][:,0])
|
|
235
|
+
col2: str
|
|
236
|
+
Name of the second feature of all isoelastics
|
|
237
|
+
(e.g. isoel[0][:,1])
|
|
238
|
+
channel_width: float
|
|
239
|
+
Channel width in µm
|
|
240
|
+
method: str
|
|
241
|
+
The method used to compute the isoelastics
|
|
242
|
+
DEPRECATED since 0.32.0. Please use
|
|
243
|
+
`lut_identifier` instead.
|
|
244
|
+
lut_identifier: str:
|
|
245
|
+
Look-up table identifier used to identify which
|
|
246
|
+
isoelasticity lines to show. The function
|
|
247
|
+
:func:`get_available_identifiers` returns a list
|
|
248
|
+
of available identifiers.
|
|
249
|
+
flow_rate: float or `None`
|
|
250
|
+
Flow rate through the channel in µL/s. If set to
|
|
251
|
+
`None`, the flow rate of the imported data will
|
|
252
|
+
be used (only do this if you do not need the
|
|
253
|
+
correct values for elastic moduli).
|
|
254
|
+
viscosity: float or `None`
|
|
255
|
+
Viscosity of the medium in mPa*s. If set to
|
|
256
|
+
`None`, the flow rate of the imported data will
|
|
257
|
+
be used (only do this if you do not need the
|
|
258
|
+
correct values for elastic moduli).
|
|
259
|
+
add_px_err: bool
|
|
260
|
+
If True, add pixelation errors according to
|
|
261
|
+
C. Herold (2017), https://arxiv.org/abs/1704.00572
|
|
262
|
+
and scripts/pixelation_correction.py
|
|
263
|
+
px_um: float
|
|
264
|
+
Pixel size [µm], used for pixelation error computation
|
|
265
|
+
|
|
266
|
+
See Also
|
|
267
|
+
--------
|
|
268
|
+
dclab.features.emodulus.scale_linear.scale_feature: scale
|
|
269
|
+
conversion method used
|
|
270
|
+
dclab.features.emodulus.pxcorr.get_pixelation_delta:
|
|
271
|
+
pixelation correction (applied to the feature data)
|
|
272
|
+
"""
|
|
273
|
+
lut_identifier = check_lut_identifier(lut_identifier, method)
|
|
274
|
+
|
|
275
|
+
for col in [col1, col2]:
|
|
276
|
+
if not dfn.scalar_feature_exists(col):
|
|
277
|
+
raise ValueError("Not a valid feature name: {}".format(col))
|
|
278
|
+
|
|
279
|
+
if "isoelastics" not in self._data[lut_identifier][col2][col1]:
|
|
280
|
+
msg = "No isoelastics matching {}, {}, {}".format(col1, col2,
|
|
281
|
+
lut_identifier)
|
|
282
|
+
raise KeyError(msg)
|
|
283
|
+
|
|
284
|
+
isoel = self._data[lut_identifier][col1][col2]["isoelastics"]
|
|
285
|
+
meta = self._data[lut_identifier][col1][col2]["meta"]
|
|
286
|
+
|
|
287
|
+
if flow_rate is None:
|
|
288
|
+
flow_rate = meta[1]
|
|
289
|
+
|
|
290
|
+
if viscosity is None:
|
|
291
|
+
viscosity = meta[2]
|
|
292
|
+
|
|
293
|
+
isoel_ret = self.convert(isoel, col1, col2,
|
|
294
|
+
channel_width_in=meta[0],
|
|
295
|
+
channel_width_out=channel_width,
|
|
296
|
+
flow_rate_in=meta[1],
|
|
297
|
+
flow_rate_out=flow_rate,
|
|
298
|
+
viscosity_in=meta[2],
|
|
299
|
+
viscosity_out=viscosity,
|
|
300
|
+
inplace=False)
|
|
301
|
+
|
|
302
|
+
if add_px_err:
|
|
303
|
+
self.add_px_err(isoel=isoel_ret,
|
|
304
|
+
col1=col1,
|
|
305
|
+
col2=col2,
|
|
306
|
+
px_um=px_um,
|
|
307
|
+
inplace=True)
|
|
308
|
+
|
|
309
|
+
return isoel_ret
|
|
310
|
+
|
|
311
|
+
def get_with_rtdcbase(self, col1, col2, dataset, method=None,
|
|
312
|
+
lut_identifier=None, viscosity=None,
|
|
313
|
+
add_px_err=False):
|
|
314
|
+
"""Convenience method that extracts the metadata from RTDCBase
|
|
315
|
+
|
|
316
|
+
Parameters
|
|
317
|
+
----------
|
|
318
|
+
col1: str
|
|
319
|
+
Name of the first feature of all isoelastics
|
|
320
|
+
(e.g. isoel[0][:,0])
|
|
321
|
+
col2: str
|
|
322
|
+
Name of the second feature of all isoelastics
|
|
323
|
+
(e.g. isoel[0][:,1])
|
|
324
|
+
method: str
|
|
325
|
+
The method used to compute the isoelastics
|
|
326
|
+
DEPRECATED since 0.32.0. Please use
|
|
327
|
+
`lut_identifier` instead.
|
|
328
|
+
lut_identifier: str:
|
|
329
|
+
Look-up table identifier used to identify which
|
|
330
|
+
isoelasticity lines to show. The function
|
|
331
|
+
:func:`get_available_identifiers` returns a list
|
|
332
|
+
of available identifiers.
|
|
333
|
+
dataset: dclab.rtdc_dataset.RTDCBase
|
|
334
|
+
The dataset from which to obtain the metadata.
|
|
335
|
+
viscosity: float, `None`, or False
|
|
336
|
+
Viscosity of the medium in mPa*s. If set to
|
|
337
|
+
`None`, the viscosity is computed from the meta
|
|
338
|
+
data (medium, flow rate, channel width, temperature)
|
|
339
|
+
in the [setup] config section. If this is not possible,
|
|
340
|
+
the flow rate of the imported data is used and a warning
|
|
341
|
+
will be issued.
|
|
342
|
+
add_px_err: bool
|
|
343
|
+
If True, add pixelation errors according to
|
|
344
|
+
C. Herold (2017), https://arxiv.org/abs/1704.00572
|
|
345
|
+
and scripts/pixelation_correction.py
|
|
346
|
+
"""
|
|
347
|
+
lut_identifier = check_lut_identifier(lut_identifier, method)
|
|
348
|
+
|
|
349
|
+
cfg = dataset.config
|
|
350
|
+
if viscosity is None:
|
|
351
|
+
if "temperature" in cfg["setup"] and "medium" in cfg["setup"]:
|
|
352
|
+
viscosity = feat_emod.get_viscosity(
|
|
353
|
+
medium=cfg["setup"]["medium"],
|
|
354
|
+
channel_width=cfg["setup"]["channel width"],
|
|
355
|
+
flow_rate=cfg["setup"]["flow rate"],
|
|
356
|
+
temperature=cfg["setup"]["temperature"],
|
|
357
|
+
model='buyukurganci-2022',
|
|
358
|
+
)
|
|
359
|
+
else:
|
|
360
|
+
warnings.warn("Computing emodulus data for isoelastics from "
|
|
361
|
+
+ "RTDCBase is not possible. Isoelastics will "
|
|
362
|
+
+ "not have correct emodulus values (this is "
|
|
363
|
+
+ "not relevant for plotting).",
|
|
364
|
+
IsoelasticsEmodulusMeaninglessWarning)
|
|
365
|
+
return self.get(col1=col1,
|
|
366
|
+
col2=col2,
|
|
367
|
+
lut_identifier=lut_identifier,
|
|
368
|
+
channel_width=cfg["setup"]["channel width"],
|
|
369
|
+
flow_rate=cfg["setup"]["flow rate"],
|
|
370
|
+
viscosity=viscosity,
|
|
371
|
+
add_px_err=add_px_err,
|
|
372
|
+
px_um=cfg["imaging"]["pixel size"])
|
|
373
|
+
|
|
374
|
+
def load_data(self, path):
|
|
375
|
+
"""Load isoelastics from a text file
|
|
376
|
+
|
|
377
|
+
Parameters
|
|
378
|
+
----------
|
|
379
|
+
path: str or pathlib.Path
|
|
380
|
+
Path to an isoelasticity lines text file
|
|
381
|
+
"""
|
|
382
|
+
isodata, meta = feat_emod.load_mtext(path)
|
|
383
|
+
assert len(meta["column features"]) == 3
|
|
384
|
+
assert meta["column features"][2] == "emodulus"
|
|
385
|
+
assert meta["lut identifier"]
|
|
386
|
+
|
|
387
|
+
# Slice out individual isoelastics
|
|
388
|
+
emoduli = np.unique(isodata[:, 2])
|
|
389
|
+
isoel = []
|
|
390
|
+
for emod in emoduli:
|
|
391
|
+
where = isodata[:, 2] == emod
|
|
392
|
+
isoel.append(isodata[where])
|
|
393
|
+
|
|
394
|
+
# Add isoelastics to instance
|
|
395
|
+
self.add(isoel=isoel,
|
|
396
|
+
col1=meta["column features"][0],
|
|
397
|
+
col2=meta["column features"][1],
|
|
398
|
+
channel_width=meta["channel_width"],
|
|
399
|
+
flow_rate=meta["flow_rate"],
|
|
400
|
+
viscosity=meta["fluid_viscosity"],
|
|
401
|
+
lut_identifier=meta["lut identifier"])
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
class AutoRecursiveDict(collections.UserDict):
|
|
405
|
+
def __getitem__(self, key):
|
|
406
|
+
if key not in self:
|
|
407
|
+
self[key] = AutoRecursiveDict()
|
|
408
|
+
return super(AutoRecursiveDict, self).__getitem__(key)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def check_lut_identifier(lut_identifier, method):
|
|
412
|
+
"""Transitional function that can be removed once `method` is removed"""
|
|
413
|
+
if lut_identifier is None:
|
|
414
|
+
if method is not None:
|
|
415
|
+
warnings.warn("The `method` argument is deprecated "
|
|
416
|
+
+ "please use `lut_identifier` instead!",
|
|
417
|
+
DeprecationWarning)
|
|
418
|
+
if method == "analytical":
|
|
419
|
+
lut_identifier = "LE-2D-ana-18"
|
|
420
|
+
elif method == "numerical":
|
|
421
|
+
lut_identifier = "LE-2D-FEM-19"
|
|
422
|
+
else:
|
|
423
|
+
raise ValueError("Please read the docstring")
|
|
424
|
+
# Now check again (this can be removed once lut_identifier becomes
|
|
425
|
+
# a non-keyword argument)
|
|
426
|
+
if lut_identifier is None:
|
|
427
|
+
raise ValueError("Please specify `lut_identifier`!")
|
|
428
|
+
return lut_identifier
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
@functools.lru_cache()
|
|
432
|
+
def get_available_identifiers():
|
|
433
|
+
"""Return a list of available LUT identifiers"""
|
|
434
|
+
isofiles = get_available_files()
|
|
435
|
+
ids = []
|
|
436
|
+
for pp in isofiles:
|
|
437
|
+
_, meta = feat_emod.load_mtext(pp)
|
|
438
|
+
ids.append(meta["lut identifier"])
|
|
439
|
+
return sorted(set(ids))
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
@functools.lru_cache()
|
|
443
|
+
def get_available_files():
|
|
444
|
+
"""Return list of available isoelasticity line files in dclab"""
|
|
445
|
+
isofiles = []
|
|
446
|
+
for pp in importlib_resources.files('dclab.isoelastics').iterdir():
|
|
447
|
+
name = pp.name
|
|
448
|
+
if name.startswith("iso") and name.endswith(".txt"):
|
|
449
|
+
isofiles.append(name)
|
|
450
|
+
return sorted(isofiles)
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def get_default():
|
|
454
|
+
"""Return default isoelasticity lines"""
|
|
455
|
+
# name of the isoelastics files
|
|
456
|
+
isofiles = get_available_files()
|
|
457
|
+
# file manager to temporarily work with the package files
|
|
458
|
+
file_manager = ExitStack()
|
|
459
|
+
paths = []
|
|
460
|
+
for name in isofiles:
|
|
461
|
+
ref = importlib_resources.files('dclab.isoelastics') / name
|
|
462
|
+
path = file_manager.enter_context(importlib_resources.as_file(ref))
|
|
463
|
+
paths.append(path)
|
|
464
|
+
# this loads the data into memory, so we don't need the files afterward
|
|
465
|
+
isoels = Isoelastics(paths=paths)
|
|
466
|
+
# close the file manager, deleting all files
|
|
467
|
+
file_manager.close()
|
|
468
|
+
return isoels
|