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.

Files changed (142) hide show
  1. dclab/__init__.py +41 -0
  2. dclab/_version.py +34 -0
  3. dclab/cached.py +97 -0
  4. dclab/cli/__init__.py +10 -0
  5. dclab/cli/common.py +237 -0
  6. dclab/cli/task_compress.py +126 -0
  7. dclab/cli/task_condense.py +223 -0
  8. dclab/cli/task_join.py +229 -0
  9. dclab/cli/task_repack.py +98 -0
  10. dclab/cli/task_split.py +154 -0
  11. dclab/cli/task_tdms2rtdc.py +186 -0
  12. dclab/cli/task_verify_dataset.py +75 -0
  13. dclab/definitions/__init__.py +79 -0
  14. dclab/definitions/feat_const.py +202 -0
  15. dclab/definitions/feat_logic.py +182 -0
  16. dclab/definitions/meta_const.py +252 -0
  17. dclab/definitions/meta_logic.py +111 -0
  18. dclab/definitions/meta_parse.py +94 -0
  19. dclab/downsampling.cpython-314-darwin.so +0 -0
  20. dclab/downsampling.pyx +230 -0
  21. dclab/external/__init__.py +4 -0
  22. dclab/external/packaging/LICENSE +3 -0
  23. dclab/external/packaging/LICENSE.APACHE +177 -0
  24. dclab/external/packaging/LICENSE.BSD +23 -0
  25. dclab/external/packaging/__init__.py +6 -0
  26. dclab/external/packaging/_structures.py +61 -0
  27. dclab/external/packaging/version.py +505 -0
  28. dclab/external/skimage/LICENSE +28 -0
  29. dclab/external/skimage/__init__.py +2 -0
  30. dclab/external/skimage/_find_contours.py +216 -0
  31. dclab/external/skimage/_find_contours_cy.cpython-314-darwin.so +0 -0
  32. dclab/external/skimage/_find_contours_cy.pyx +188 -0
  33. dclab/external/skimage/_pnpoly.cpython-314-darwin.so +0 -0
  34. dclab/external/skimage/_pnpoly.pyx +99 -0
  35. dclab/external/skimage/_shared/__init__.py +1 -0
  36. dclab/external/skimage/_shared/geometry.cpython-314-darwin.so +0 -0
  37. dclab/external/skimage/_shared/geometry.pxd +6 -0
  38. dclab/external/skimage/_shared/geometry.pyx +55 -0
  39. dclab/external/skimage/measure.py +7 -0
  40. dclab/external/skimage/pnpoly.py +53 -0
  41. dclab/external/statsmodels/LICENSE +35 -0
  42. dclab/external/statsmodels/__init__.py +6 -0
  43. dclab/external/statsmodels/nonparametric/__init__.py +1 -0
  44. dclab/external/statsmodels/nonparametric/_kernel_base.py +203 -0
  45. dclab/external/statsmodels/nonparametric/kernel_density.py +165 -0
  46. dclab/external/statsmodels/nonparametric/kernels.py +36 -0
  47. dclab/features/__init__.py +9 -0
  48. dclab/features/bright.py +81 -0
  49. dclab/features/bright_bc.py +93 -0
  50. dclab/features/bright_perc.py +63 -0
  51. dclab/features/contour.py +161 -0
  52. dclab/features/emodulus/__init__.py +339 -0
  53. dclab/features/emodulus/load.py +252 -0
  54. dclab/features/emodulus/lut_HE-2D-FEM-22.txt +16432 -0
  55. dclab/features/emodulus/lut_HE-3D-FEM-22.txt +1276 -0
  56. dclab/features/emodulus/lut_LE-2D-FEM-19.txt +13082 -0
  57. dclab/features/emodulus/pxcorr.py +135 -0
  58. dclab/features/emodulus/scale_linear.py +247 -0
  59. dclab/features/emodulus/viscosity.py +260 -0
  60. dclab/features/fl_crosstalk.py +95 -0
  61. dclab/features/inert_ratio.py +377 -0
  62. dclab/features/volume.py +242 -0
  63. dclab/http_utils.py +322 -0
  64. dclab/isoelastics/__init__.py +468 -0
  65. dclab/isoelastics/iso_HE-2D-FEM-22-area_um-deform.txt +2440 -0
  66. dclab/isoelastics/iso_HE-2D-FEM-22-volume-deform.txt +2635 -0
  67. dclab/isoelastics/iso_HE-3D-FEM-22-area_um-deform.txt +1930 -0
  68. dclab/isoelastics/iso_HE-3D-FEM-22-volume-deform.txt +2221 -0
  69. dclab/isoelastics/iso_LE-2D-FEM-19-area_um-deform.txt +2151 -0
  70. dclab/isoelastics/iso_LE-2D-FEM-19-volume-deform.txt +2250 -0
  71. dclab/isoelastics/iso_LE-2D-ana-18-area_um-deform.txt +1266 -0
  72. dclab/kde/__init__.py +1 -0
  73. dclab/kde/base.py +459 -0
  74. dclab/kde/contours.py +222 -0
  75. dclab/kde/methods.py +313 -0
  76. dclab/kde_contours.py +10 -0
  77. dclab/kde_methods.py +11 -0
  78. dclab/lme4/__init__.py +5 -0
  79. dclab/lme4/lme4_template.R +94 -0
  80. dclab/lme4/rsetup.py +204 -0
  81. dclab/lme4/wrapr.py +386 -0
  82. dclab/polygon_filter.py +398 -0
  83. dclab/rtdc_dataset/__init__.py +15 -0
  84. dclab/rtdc_dataset/check.py +902 -0
  85. dclab/rtdc_dataset/config.py +533 -0
  86. dclab/rtdc_dataset/copier.py +353 -0
  87. dclab/rtdc_dataset/core.py +896 -0
  88. dclab/rtdc_dataset/export.py +867 -0
  89. dclab/rtdc_dataset/feat_anc_core/__init__.py +24 -0
  90. dclab/rtdc_dataset/feat_anc_core/af_basic.py +75 -0
  91. dclab/rtdc_dataset/feat_anc_core/af_emodulus.py +160 -0
  92. dclab/rtdc_dataset/feat_anc_core/af_fl_max_ctc.py +133 -0
  93. dclab/rtdc_dataset/feat_anc_core/af_image_contour.py +113 -0
  94. dclab/rtdc_dataset/feat_anc_core/af_ml_class.py +102 -0
  95. dclab/rtdc_dataset/feat_anc_core/ancillary_feature.py +320 -0
  96. dclab/rtdc_dataset/feat_anc_ml/__init__.py +32 -0
  97. dclab/rtdc_dataset/feat_anc_plugin/__init__.py +3 -0
  98. dclab/rtdc_dataset/feat_anc_plugin/plugin_feature.py +329 -0
  99. dclab/rtdc_dataset/feat_basin.py +762 -0
  100. dclab/rtdc_dataset/feat_temp.py +102 -0
  101. dclab/rtdc_dataset/filter.py +263 -0
  102. dclab/rtdc_dataset/fmt_dcor/__init__.py +7 -0
  103. dclab/rtdc_dataset/fmt_dcor/access_token.py +52 -0
  104. dclab/rtdc_dataset/fmt_dcor/api.py +173 -0
  105. dclab/rtdc_dataset/fmt_dcor/base.py +299 -0
  106. dclab/rtdc_dataset/fmt_dcor/basin.py +73 -0
  107. dclab/rtdc_dataset/fmt_dcor/logs.py +26 -0
  108. dclab/rtdc_dataset/fmt_dcor/tables.py +66 -0
  109. dclab/rtdc_dataset/fmt_dict.py +103 -0
  110. dclab/rtdc_dataset/fmt_hdf5/__init__.py +6 -0
  111. dclab/rtdc_dataset/fmt_hdf5/base.py +192 -0
  112. dclab/rtdc_dataset/fmt_hdf5/basin.py +30 -0
  113. dclab/rtdc_dataset/fmt_hdf5/events.py +276 -0
  114. dclab/rtdc_dataset/fmt_hdf5/feat_defect.py +164 -0
  115. dclab/rtdc_dataset/fmt_hdf5/logs.py +33 -0
  116. dclab/rtdc_dataset/fmt_hdf5/tables.py +60 -0
  117. dclab/rtdc_dataset/fmt_hierarchy/__init__.py +11 -0
  118. dclab/rtdc_dataset/fmt_hierarchy/base.py +278 -0
  119. dclab/rtdc_dataset/fmt_hierarchy/events.py +146 -0
  120. dclab/rtdc_dataset/fmt_hierarchy/hfilter.py +140 -0
  121. dclab/rtdc_dataset/fmt_hierarchy/mapper.py +134 -0
  122. dclab/rtdc_dataset/fmt_http.py +102 -0
  123. dclab/rtdc_dataset/fmt_s3.py +354 -0
  124. dclab/rtdc_dataset/fmt_tdms/__init__.py +476 -0
  125. dclab/rtdc_dataset/fmt_tdms/event_contour.py +264 -0
  126. dclab/rtdc_dataset/fmt_tdms/event_image.py +220 -0
  127. dclab/rtdc_dataset/fmt_tdms/event_mask.py +62 -0
  128. dclab/rtdc_dataset/fmt_tdms/event_trace.py +146 -0
  129. dclab/rtdc_dataset/fmt_tdms/exc.py +37 -0
  130. dclab/rtdc_dataset/fmt_tdms/naming.py +151 -0
  131. dclab/rtdc_dataset/load.py +77 -0
  132. dclab/rtdc_dataset/meta_table.py +25 -0
  133. dclab/rtdc_dataset/writer.py +1019 -0
  134. dclab/statistics.py +226 -0
  135. dclab/util.py +176 -0
  136. dclab/warn.py +15 -0
  137. dclab-0.67.0.dist-info/METADATA +153 -0
  138. dclab-0.67.0.dist-info/RECORD +142 -0
  139. dclab-0.67.0.dist-info/WHEEL +6 -0
  140. dclab-0.67.0.dist-info/entry_points.txt +8 -0
  141. dclab-0.67.0.dist-info/licenses/LICENSE +283 -0
  142. 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