dclab 0.67.0__cp314-cp314t-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-314t-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-314t-darwin.so +0 -0
  32. dclab/external/skimage/_find_contours_cy.pyx +188 -0
  33. dclab/external/skimage/_pnpoly.cpython-314t-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-314t-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
dclab/statistics.py ADDED
@@ -0,0 +1,226 @@
1
+ """Statistics computation for RT-DC dataset instances"""
2
+
3
+ import numpy as np
4
+ import traceback as tb
5
+ import warnings
6
+
7
+ from . import definitions as dfn
8
+
9
+
10
+ class BadMethodWarning(UserWarning):
11
+ pass
12
+
13
+
14
+ class Statistics(object):
15
+ available_methods = {}
16
+
17
+ def __init__(self, name, method, req_feature=False):
18
+ """A helper class for computing statistics
19
+
20
+ All statistical methods are registered in the dictionary
21
+ `Statistics.available_methods`.
22
+ """
23
+ self.method = method
24
+ self.name = name
25
+ self.req_feature = req_feature
26
+ Statistics.available_methods[name] = self
27
+
28
+ def __call__(self, **kwargs):
29
+ data = self._get_data(kwargs)
30
+ if len(data) == 0:
31
+ result = np.nan
32
+ else:
33
+ try:
34
+ result = self.method(data)
35
+ except BaseException:
36
+ exc = tb.format_exc().replace("\n", "\n | ")
37
+ warnings.warn("Failed to compute {} for {}: {}".format(
38
+ self.name, kwargs["ds"].title, exc),
39
+ BadMethodWarning)
40
+ result = np.nan
41
+ return result
42
+
43
+ def _get_data(self, kwargs):
44
+ """Convenience wrapper to get statistics data"""
45
+ if "ds" not in kwargs:
46
+ raise ValueError("Keyword argument 'ds' missing.")
47
+
48
+ ds = kwargs["ds"]
49
+
50
+ if self.req_feature:
51
+ if "feature" not in kwargs:
52
+ raise ValueError("Keyword argument 'feature' missing.")
53
+ return self.get_feature(ds, kwargs["feature"])
54
+ else:
55
+ return ds
56
+
57
+ def get_feature(self, ds, feat):
58
+ """Return filtered feature data
59
+
60
+ The features are filtered according to the user-defined filters,
61
+ using the information in `ds.filter.all`. In addition, all
62
+ `nan` and `inf` values are purged.
63
+
64
+ Parameters
65
+ ----------
66
+ ds: dclab.rtdc_dataset.RTDCBase
67
+ The dataset containing the feature
68
+ feat: str
69
+ The name of the feature; must be a scalar feature
70
+ """
71
+ if ds.config["filtering"]["enable filters"]:
72
+ x = ds[feat][ds.filter.all]
73
+ else:
74
+ x = ds[feat]
75
+ bad = np.isnan(x) | np.isinf(x)
76
+ xout = x[~bad]
77
+ return xout
78
+
79
+
80
+ def flow_rate(ds):
81
+ """Return the flow rate of an RT-DC dataset"""
82
+ conf = ds.config["setup"]
83
+ if "flow rate" in conf:
84
+ return conf["flow rate"]
85
+ else:
86
+ return np.nan
87
+
88
+
89
+ def get_statistics(ds, methods=None, features=None, ret_dict=False):
90
+ """Compute statistics for an RT-DC dataset
91
+
92
+ Parameters
93
+ ----------
94
+ ds: dclab.rtdc_dataset.RTDCBase
95
+ The dataset for which to compute the statistics.
96
+ methods: list of str or None
97
+ The methods wih which to compute the statistics.
98
+ The list of available methods is given with
99
+ :func:`.available_methods.keys`
100
+ If set to `None`, statistics for all methods are computed.
101
+ features: list of str
102
+ Feature name identifiers are defined by
103
+ :func:`dclab.definitions.feature_exists`.
104
+ If set to `None`, statistics for all scalar features
105
+ available are computed.
106
+ ret_dict: bool
107
+ Instead of returning ``(header, values)``, return a dictionary
108
+ with headers as keys.
109
+
110
+ Returns
111
+ -------
112
+ header: list of str
113
+ The header (feature + method names) of the computed statistics.
114
+ values: list of float
115
+ The computed statistics.
116
+ """
117
+ if methods is None:
118
+ cls = list(Statistics.available_methods.keys())
119
+ # sort the features in a usable way
120
+ avm = Statistics.available_methods
121
+ me1 = [m for m in cls if not avm[m].req_feature]
122
+ me2 = [m for m in cls if avm[m].req_feature]
123
+ methods = me1 + me2
124
+
125
+ if features is None:
126
+ features = ds.features_scalar
127
+ else:
128
+ features = [a.lower() for a in features]
129
+
130
+ header = []
131
+ values = []
132
+
133
+ # First loop over all methods that do not require a feature
134
+ for mt in methods:
135
+ meth = Statistics.available_methods[mt]
136
+ if not meth.req_feature:
137
+ values.append(meth(ds=ds))
138
+ header.append(mt)
139
+
140
+ # To make sure that all methods are computed for each feature in a block,
141
+ # we loop over all features. It would be easier to loop over the methods,
142
+ # but the ordering of the resulting statistics would not be human-friendly.
143
+ for ft in features:
144
+ for mt in methods:
145
+ meth = Statistics.available_methods[mt]
146
+ if meth.req_feature:
147
+ if ft in ds:
148
+ values.append(meth(ds=ds, feature=ft))
149
+ else:
150
+ values.append(np.nan)
151
+ label = dfn.get_feature_label(ft, rtdc_ds=ds)
152
+ header.append(" ".join([mt, label]))
153
+
154
+ if ret_dict:
155
+ return dict(zip(header, values))
156
+ else:
157
+ return header, values
158
+
159
+
160
+ def mode(data):
161
+ """Compute an intelligent value for the mode
162
+
163
+ The most common value in experimental is not very useful if there
164
+ are a lot of digits after the comma. This method approaches this
165
+ issue by rounding to bin size that is determined by the
166
+ Freedman–Diaconis rule.
167
+
168
+ Parameters
169
+ ----------
170
+ data: 1d ndarray
171
+ The data for which the mode should be computed.
172
+
173
+ Returns
174
+ -------
175
+ mode: float
176
+ The mode computed with the Freedman-Diaconis rule.
177
+ """
178
+ # size
179
+ n = data.shape[0]
180
+ # interquartile range
181
+ iqr = np.percentile(data, 75)-np.percentile(data, 25)
182
+ # Freedman–Diaconis
183
+ bin_size = 2 * iqr / n**(1/3)
184
+
185
+ if bin_size == 0:
186
+ return np.nan
187
+
188
+ # Add bin_size/2, because we want the center of the bin and
189
+ # not the left corner of the bin.
190
+ databin = np.round(data/bin_size)*bin_size + bin_size/2
191
+ u, indices = np.unique(databin, return_inverse=True)
192
+ mode = u[np.argmax(np.bincount(indices))]
193
+
194
+ return mode
195
+
196
+
197
+ # Register all the methods
198
+ # Methods that require an axis
199
+ Statistics(name="Mean", req_feature=True, method=np.average)
200
+ # Premature-Optimization warning: `np.percentile` also accepts an array
201
+ # of percentiles as the `q` argument, which I would expect to yield better
202
+ # performance than computing percentiles individually. Implementing this
203
+ # would break the way we are defining statistical methods here (One
204
+ # `Statistics` instance per method) and thus requires a considerable
205
+ # amount of work (much more work than writing this text here). It would
206
+ # also make understanding the code more difficult. In addition, computing
207
+ # statistics is not done often and is extremely fast anyway for a few
208
+ # millions of events. Don't optimize this!
209
+ Statistics(name="10th Percentile", req_feature=True,
210
+ method=lambda data: np.percentile(data, 10))
211
+ Statistics(name="25th Percentile", req_feature=True,
212
+ method=lambda data: np.percentile(data, 25))
213
+ Statistics(name="Median", req_feature=True, method=np.median)
214
+ Statistics(name="75th Percentile", req_feature=True,
215
+ method=lambda data: np.percentile(data, 75))
216
+ Statistics(name="90th Percentile", req_feature=True,
217
+ method=lambda data: np.percentile(data, 90))
218
+ Statistics(name="Mode", req_feature=True, method=mode)
219
+ Statistics(name="SD", req_feature=True, method=np.std)
220
+ # Methods that work on RTDCBase
221
+ Statistics(name="Events",
222
+ method=lambda mm: np.sum(mm.filter.all))
223
+ Statistics(name="%-gated",
224
+ method=lambda mm: np.average(mm.filter.all)*100)
225
+ Statistics(name="Flow rate",
226
+ method=lambda mm: flow_rate(mm))
dclab/util.py ADDED
@@ -0,0 +1,176 @@
1
+ """Utility methods"""
2
+ import functools
3
+ import hashlib
4
+ import importlib
5
+ import numbers
6
+ import pathlib
7
+ import warnings
8
+
9
+ import h5py
10
+ import numpy as np
11
+ from .rtdc_dataset.config import Configuration, ConfigurationDict
12
+
13
+
14
+ if np.lib.NumpyVersion(np.__version__) >= "2.0.0":
15
+ copy_if_needed = None
16
+ else:
17
+ copy_if_needed = False
18
+
19
+
20
+ class file_monitoring_lru_cache:
21
+ """Decorator for caching data extracted from files
22
+
23
+ The function that is decorated with `file_monitoring_lru_cache`
24
+ must accept `path` as its first argument. Caching is
25
+ done with an `lru_cache`. In addition to the full path
26
+ and the other arguments to the decorated function, the
27
+ size and the modification time of `path` is used as a
28
+ key for the decorator.
29
+ If the path does not exist, no caching is done.
30
+
31
+ Use case: Extract and cache metadata from a file on disk
32
+ that may change.
33
+ """
34
+ def __init__(self, maxsize=100):
35
+ self.lru_cache = functools.lru_cache(maxsize=maxsize)
36
+ self.cached_wrapper = None
37
+
38
+ def __call__(self, func):
39
+ @self.lru_cache
40
+ def cached_wrapper(path, path_stats, *args, **kwargs):
41
+ assert path_stats, "We need stat for validating the cache"
42
+ return func(path, *args, **kwargs)
43
+
44
+ @functools.wraps(func)
45
+ def wrapper(path, *args, **kwargs):
46
+ full_path = pathlib.Path(path).resolve()
47
+ if full_path.exists():
48
+ path_stat = full_path.stat()
49
+ return cached_wrapper(
50
+ path=full_path,
51
+ path_stats=(path_stat.st_mtime_ns, path_stat.st_size),
52
+ *args,
53
+ **kwargs)
54
+ else:
55
+ # `func` will most-likely raise an exception
56
+ return func(path, *args, **kwargs)
57
+
58
+ wrapper.cache_clear = cached_wrapper.cache_clear
59
+ wrapper.cache_info = cached_wrapper.cache_info
60
+
61
+ return wrapper
62
+
63
+
64
+ class LazyLoader():
65
+ """Lazy load a module on first attribute access"""
66
+
67
+ def __init__(self, modname):
68
+ self._modname = modname
69
+ self._mod = None
70
+
71
+ def __getattr__(self, attr):
72
+ """Get attribute from module, load module if not loaded yet"""
73
+
74
+ if self._mod is None:
75
+ # module is unset, load it
76
+ self._mod = importlib.import_module(self._modname)
77
+
78
+ # retry getattr if module was just loaded for first time
79
+ # call this outside exception handler in case it raises new exception
80
+ return getattr(self._mod, attr)
81
+
82
+
83
+ @file_monitoring_lru_cache(maxsize=100)
84
+ def hashfile(fname, blocksize=65536, count=0, constructor=hashlib.md5,
85
+ hasher_class=None):
86
+ """Compute md5 hex-hash of a file
87
+
88
+ Parameters
89
+ ----------
90
+ fname: str or pathlib.Path
91
+ path to the file
92
+ blocksize: int
93
+ block size in bytes read from the file
94
+ (set to `0` to hash the entire file)
95
+ count: int
96
+ number of blocks read from the file
97
+ hasher_class: callable
98
+ deprecated, see use `constructor` instead
99
+ constructor: callable
100
+ hash algorithm constructor
101
+ """
102
+ if hasher_class is not None:
103
+ warnings.warn("The `hasher_class` argument is deprecated, please use "
104
+ "`constructor` instead.")
105
+ constructor = hasher_class
106
+
107
+ path = pathlib.Path(fname)
108
+
109
+ hasher = constructor()
110
+ with path.open('rb') as fd:
111
+ buf = fd.read(blocksize)
112
+ ii = 0
113
+ while len(buf) > 0:
114
+ hasher.update(buf)
115
+ buf = fd.read(blocksize)
116
+ ii += 1
117
+ if count and ii == count:
118
+ break
119
+ return hasher.hexdigest()
120
+
121
+
122
+ def hashobj(obj):
123
+ """Compute md5 hex-hash of a Python object"""
124
+ return hashlib.md5(obj2bytes(obj)).hexdigest()
125
+
126
+
127
+ def obj2bytes(obj):
128
+ """Bytes representation of an object for hashing
129
+
130
+ Note that there is no guarantee that the bytes representation
131
+ returned is reproducible across sessions. This is currently the
132
+ case when an :class:`.RTDCBase` instance is passed. There is no
133
+ opinion on wether/how this should be changed.
134
+ """
135
+ if isinstance(obj, str):
136
+ return obj.encode("utf-8")
137
+ elif isinstance(obj, pathlib.Path):
138
+ return obj2bytes(str(obj))
139
+ elif isinstance(obj, (bool, numbers.Number)):
140
+ return str(obj).encode("utf-8")
141
+ elif obj is None:
142
+ return b"none"
143
+ elif isinstance(obj, np.ndarray):
144
+ return obj.tobytes()
145
+ elif isinstance(obj, tuple):
146
+ return obj2bytes(list(obj))
147
+ elif isinstance(obj, list):
148
+ return b"".join(obj2bytes(o) for o in obj)
149
+ elif isinstance(obj, dict):
150
+ return obj2bytes(sorted(obj.items()))
151
+ elif hasattr(obj, "identifier"):
152
+ # For RTDCBase, this identifier is not reproducible in-between
153
+ # sessions. We might want to change this to something that is
154
+ # reproducible in the future (if the need arises).
155
+ return obj2bytes(obj.identifier)
156
+ elif isinstance(obj, h5py.Dataset):
157
+ # path within the HDF5 file
158
+ o_name = obj.name
159
+ # filename
160
+ o_filename = obj.file.filename
161
+ _data = [o_name, o_filename]
162
+ if pathlib.Path(o_filename).exists():
163
+ # when the file was changed
164
+ _data.append(pathlib.Path(obj.file.filename).stat().st_mtime)
165
+ # size of the file
166
+ _data.append(pathlib.Path(obj.file.filename).stat().st_size)
167
+ return obj2bytes(_data)
168
+ elif hasattr(obj, "__array__"): # must come after h5py.Dataset
169
+ return obj2bytes(obj.__array__())
170
+ elif isinstance(obj, Configuration):
171
+ return obj2bytes(obj.tostring())
172
+ elif isinstance(obj, ConfigurationDict):
173
+ return obj2bytes(dict(obj))
174
+ else:
175
+ raise ValueError("No rule to convert object '{}' to string.".
176
+ format(obj.__class__))
dclab/warn.py ADDED
@@ -0,0 +1,15 @@
1
+
2
+
3
+ class PipelineWarning(UserWarning):
4
+ """Super-class for warnings relevant to data analysis
5
+
6
+ There are those types of warnings in dclab that are
7
+ important to the user, because they suggest that the
8
+ user may not use the correct model (e.g. Young's modulus
9
+ computation) in his analysis pipeline. All of these
10
+ warnings should be subclassed from PipelineWarning
11
+ to allow identifying them in higher-level software
12
+ such as DCscope and to present them correctly to the
13
+ user.
14
+ """
15
+ pass
@@ -0,0 +1,153 @@
1
+ Metadata-Version: 2.4
2
+ Name: dclab
3
+ Version: 0.67.0
4
+ Summary: Library for real-time deformability cytometry (RT-DC)
5
+ Author: Benedikt Hartmann, Eoghan O'Connell, Maik Herbig, Maximilian Schlögel, Nadia Sbaa, Paul Müller, Philipp Rosendahl, Raghava Alajangi
6
+ Maintainer-email: Paul Müller <dev@craban.de>
7
+ License-Expression: GPL-2.0-or-later
8
+ Project-URL: source, https://github.com/DC-Analysis/dclab
9
+ Project-URL: tracker, https://github.com/DC-Analysis/dclab/issues
10
+ Project-URL: documentation, https://dclab.readthedocs.io/en/stable/
11
+ Project-URL: changelog, https://dclab.readthedocs.io/en/stable/sec_changelog.html
12
+ Keywords: RT-DC,deformability,cytometry
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Scientific/Engineering :: Visualization
16
+ Classifier: Intended Audience :: Science/Research
17
+ Requires-Python: <4,>=3.9
18
+ Description-Content-Type: text/x-rst
19
+ License-File: LICENSE
20
+ Requires-Dist: h5py<4,>=3.0.0
21
+ Requires-Dist: hdf5plugin<5,>=3.3.1
22
+ Requires-Dist: importlib-resources>=6.0
23
+ Requires-Dist: numpy<3,>=1.21
24
+ Requires-Dist: scipy<2,>=1.10.0
25
+ Provides-Extra: all
26
+ Requires-Dist: dclab[dcor,export,http,s3,tdms]; extra == "all"
27
+ Provides-Extra: dcor
28
+ Requires-Dist: requests<3,>=2.31.0; extra == "dcor"
29
+ Provides-Extra: export
30
+ Requires-Dist: fcswrite>=0.5.1; extra == "export"
31
+ Requires-Dist: av; extra == "export"
32
+ Provides-Extra: http
33
+ Requires-Dist: requests<3,>=2.31.0; extra == "http"
34
+ Provides-Extra: s3
35
+ Requires-Dist: boto3>=1.34.31; extra == "s3"
36
+ Provides-Extra: tdms
37
+ Requires-Dist: imageio[ffmpeg]; extra == "tdms"
38
+ Requires-Dist: nptdms<1.9,>=0.23.0; extra == "tdms"
39
+ Dynamic: license-file
40
+
41
+ |dclab|
42
+ =======
43
+
44
+ |PyPI Version| |Build Status| |Coverage Status| |Docs Status|
45
+
46
+
47
+ This is a Python library for the post-measurement analysis of
48
+ real-time deformability cytometry (RT-DC) datasets; an essential part of
49
+ the DC Cosmos (
50
+ `DCscope <https://github.com/DC-analysis/DCscope>`__,
51
+ `DCOR <https://github.com/DCOR-dev/dcor_control>`__,
52
+ `DCOR-Aid <https://github.com/DCOR-dev/DCOR-Aid>`__,
53
+ `DCTag <https://github.com/DC-analysis/DCTag>`__,
54
+ `DCKit <https://github.com/DC-analysis/DCKit>`__,
55
+ ).
56
+
57
+ Documentation
58
+ -------------
59
+ The documentation, including the code reference and examples, is available at
60
+ `dclab.readthedocs.io <https://dclab.readthedocs.io/en/stable/>`__.
61
+
62
+
63
+ Installation
64
+ ------------
65
+
66
+ ::
67
+
68
+ pip install dclab[all]
69
+
70
+ For more options, please check out the `documentation
71
+ <https://dclab.readthedocs.io/en/latest/sec_getting_started.html#installation>`__.
72
+
73
+
74
+ Information for developers
75
+ --------------------------
76
+
77
+
78
+ Contributing
79
+ ~~~~~~~~~~~~
80
+ The main branch for developing dclab is master.
81
+ If you want to make small changes like one-liners,
82
+ documentation, or default values in the configuration,
83
+ you may work on the master branch. If you want to change
84
+ more, please (fork dclab and) create a separate branch,
85
+ e.g. ``my_new_feature_dev``, and create a pull-request
86
+ once you are done making your changes.
87
+ Please make sure to edit the
88
+ `Changelog <https://github.com/DC-analysis/dclab/blob/master/CHANGELOG>`__.
89
+
90
+ **Very important:** Please always try to use ::
91
+
92
+
93
+ git pull --rebase
94
+
95
+ instead of::
96
+
97
+ git pull
98
+
99
+ to prevent non-linearities in the commit history.
100
+
101
+ Tests
102
+ ~~~~~
103
+ dclab is tested using pytest. If you have the time, please write test
104
+ methods for your code and put them in the ``tests`` directory. To run
105
+ the tests, install `pytest` and run::
106
+
107
+ pytest tests
108
+
109
+
110
+ Docs
111
+ ~~~~
112
+ The docs are built with `sphinx <https://www.sphinx-doc.org>`_. Please make
113
+ sure they compile when you change them (this also includes function doc strings)::
114
+
115
+ cd docs
116
+ pip install -r requirements.txt
117
+ sphinx-build . _build # open "index.html" in the "_build" directory
118
+
119
+
120
+ PEP8
121
+ ~~~~
122
+ We use flake8 to enforce coding style::
123
+
124
+ pip install flake8
125
+ flake8 --exclude _version.py dclab
126
+ flake8 docs
127
+ flake8 examples
128
+ flake8 tests
129
+
130
+
131
+ Incrementing version
132
+ ~~~~~~~~~~~~~~~~~~~~
133
+ Dclab gets its version from the latest git tag.
134
+ If you think that a new version should be published,
135
+ create a tag on the master branch (if you have the necessary
136
+ permissions to do so)::
137
+
138
+ git tag -a "0.1.3"
139
+ git push --tags origin
140
+
141
+ Appveyor and GitHub Actions will then automatically build source package and wheels
142
+ and publish them on PyPI.
143
+
144
+
145
+ .. |dclab| image:: https://raw.github.com/DC-analysis/dclab/master/docs/logo/dclab.png
146
+ .. |PyPI Version| image:: https://img.shields.io/pypi/v/dclab.svg
147
+ :target: https://pypi.python.org/pypi/dclab
148
+ .. |Build Status| image:: https://img.shields.io/github/actions/workflow/status/DC-analysis/dclab/check.yml
149
+ :target: https://github.com/DC-analysis/dclab/actions?query=workflow%3AChecks
150
+ .. |Coverage Status| image:: https://img.shields.io/codecov/c/github/DC-analysis/dclab/master.svg
151
+ :target: https://codecov.io/gh/DC-analysis/dclab
152
+ .. |Docs Status| image:: https://readthedocs.org/projects/dclab/badge/?version=latest
153
+ :target: https://readthedocs.org/projects/dclab/builds/