tobac 1.6.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. tobac/__init__.py +112 -0
  2. tobac/analysis/__init__.py +31 -0
  3. tobac/analysis/cell_analysis.py +628 -0
  4. tobac/analysis/feature_analysis.py +212 -0
  5. tobac/analysis/spatial.py +619 -0
  6. tobac/centerofgravity.py +226 -0
  7. tobac/feature_detection.py +1758 -0
  8. tobac/merge_split.py +324 -0
  9. tobac/plotting.py +2321 -0
  10. tobac/segmentation/__init__.py +10 -0
  11. tobac/segmentation/watershed_segmentation.py +1316 -0
  12. tobac/testing.py +1179 -0
  13. tobac/tests/segmentation_tests/test_iris_xarray_segmentation.py +0 -0
  14. tobac/tests/segmentation_tests/test_segmentation.py +1183 -0
  15. tobac/tests/segmentation_tests/test_segmentation_time_pad.py +104 -0
  16. tobac/tests/test_analysis_spatial.py +1109 -0
  17. tobac/tests/test_convert.py +265 -0
  18. tobac/tests/test_datetime.py +216 -0
  19. tobac/tests/test_decorators.py +148 -0
  20. tobac/tests/test_feature_detection.py +1321 -0
  21. tobac/tests/test_generators.py +273 -0
  22. tobac/tests/test_import.py +24 -0
  23. tobac/tests/test_iris_xarray_match_utils.py +244 -0
  24. tobac/tests/test_merge_split.py +351 -0
  25. tobac/tests/test_pbc_utils.py +497 -0
  26. tobac/tests/test_sample_data.py +197 -0
  27. tobac/tests/test_testing.py +747 -0
  28. tobac/tests/test_tracking.py +714 -0
  29. tobac/tests/test_utils.py +650 -0
  30. tobac/tests/test_utils_bulk_statistics.py +789 -0
  31. tobac/tests/test_utils_coordinates.py +328 -0
  32. tobac/tests/test_utils_internal.py +97 -0
  33. tobac/tests/test_xarray_utils.py +232 -0
  34. tobac/tracking.py +613 -0
  35. tobac/utils/__init__.py +27 -0
  36. tobac/utils/bulk_statistics.py +360 -0
  37. tobac/utils/datetime.py +184 -0
  38. tobac/utils/decorators.py +540 -0
  39. tobac/utils/general.py +753 -0
  40. tobac/utils/generators.py +87 -0
  41. tobac/utils/internal/__init__.py +2 -0
  42. tobac/utils/internal/coordinates.py +430 -0
  43. tobac/utils/internal/iris_utils.py +462 -0
  44. tobac/utils/internal/label_props.py +82 -0
  45. tobac/utils/internal/xarray_utils.py +439 -0
  46. tobac/utils/mask.py +364 -0
  47. tobac/utils/periodic_boundaries.py +419 -0
  48. tobac/wrapper.py +244 -0
  49. tobac-1.6.2.dist-info/METADATA +154 -0
  50. tobac-1.6.2.dist-info/RECORD +53 -0
  51. tobac-1.6.2.dist-info/WHEEL +5 -0
  52. tobac-1.6.2.dist-info/licenses/LICENSE +29 -0
  53. tobac-1.6.2.dist-info/top_level.txt +1 -0
tobac/utils/mask.py ADDED
@@ -0,0 +1,364 @@
1
+ """Provide essential methods for masking"""
2
+
3
+
4
+ def column_mask_from2D(mask_2D, cube, z_coord="model_level_number"):
5
+ """Turn 2D watershedding mask into a 3D mask of selected columns.
6
+
7
+ Parameters
8
+ ----------
9
+ cube : iris.cube.Cube
10
+ Data cube.
11
+
12
+ mask_2D : iris.cube.Cube
13
+ 2D cube containing mask (int id for tacked volumes 0
14
+ everywhere else).
15
+
16
+ z_coord : str
17
+ Name of the vertical coordinate in the cube.
18
+
19
+ Returns
20
+ -------
21
+ mask_2D : iris.cube.Cube
22
+ 3D cube containing columns of 2D mask (int id for tracked
23
+ volumes, 0 everywhere else).
24
+ """
25
+
26
+ from copy import deepcopy
27
+
28
+ mask_3D = deepcopy(cube)
29
+ mask_3D.rename("segmentation_mask")
30
+ dim = mask_3D.coord_dims(z_coord)[0]
31
+ for i in range(len(mask_3D.coord(z_coord).points)):
32
+ slc = [slice(None)] * len(mask_3D.shape)
33
+ slc[dim] = slice(i, i + 1)
34
+ mask_out = mask_3D[slc]
35
+ mask_3D.data[slc] = mask_2D.core_data()
36
+ return mask_3D
37
+
38
+
39
+ def mask_cube_cell(variable_cube, mask, cell, track):
40
+ """Mask cube for tracked volume of an individual cell.
41
+
42
+ Parameters
43
+ ----------
44
+ variable_cube : iris.cube.Cube
45
+ Unmasked data cube.
46
+
47
+ mask : iris.cube.Cube
48
+ Cube containing mask (int id for tracked volumes, 0 everywhere
49
+ else).
50
+
51
+ cell : int
52
+ Integer id of cell to create masked cube for.
53
+
54
+ track : pandas.DataFrame
55
+ Output of the linking.
56
+
57
+ Returns
58
+ -------
59
+ variable_cube_out : iris.cube.Cube
60
+ Masked cube with data for respective cell.
61
+ """
62
+
63
+ from copy import deepcopy
64
+
65
+ variable_cube_out = deepcopy(variable_cube)
66
+ feature_ids = track.loc[track["cell"] == cell, "feature"].values
67
+ variable_cube_out = mask_cube_features(variable_cube, mask, feature_ids)
68
+ return variable_cube_out
69
+
70
+
71
+ def mask_cube_all(variable_cube, mask):
72
+ """Mask cube (iris.cube) for tracked volume.
73
+
74
+ Parameters
75
+ ----------
76
+ variable_cube : iris.cube.Cube
77
+ Unmasked data cube.
78
+
79
+ mask : iris.cube.Cube
80
+ Cube containing mask (int id for tacked volumes 0 everywhere
81
+ else).
82
+
83
+ Returns
84
+ -------
85
+ variable_cube_out : iris.cube.Cube
86
+ Masked cube for untracked volume.
87
+ """
88
+
89
+ from dask.array import ma
90
+ from copy import deepcopy
91
+
92
+ variable_cube_out = deepcopy(variable_cube)
93
+ variable_cube_out.data = ma.masked_where(
94
+ mask.core_data() == 0, variable_cube_out.core_data()
95
+ )
96
+ return variable_cube_out
97
+
98
+
99
+ def mask_cube_untracked(variable_cube, mask):
100
+ """Mask cube (iris.cube) for untracked volume.
101
+
102
+ Parameters
103
+ ----------
104
+ variable_cube : iris.cube.Cube
105
+ Unmasked data cube.
106
+
107
+ mask : iris.cube.Cube
108
+ Cube containing mask (int id for tacked volumes 0 everywhere
109
+ else).
110
+
111
+ Returns
112
+ -------
113
+ variable_cube_out : iris.cube.Cube
114
+ Masked cube for untracked volume.
115
+ """
116
+
117
+ from dask.array import ma
118
+ from copy import deepcopy
119
+
120
+ variable_cube_out = deepcopy(variable_cube)
121
+ variable_cube_out.data = ma.masked_where(
122
+ mask.core_data() > 0, variable_cube_out.core_data()
123
+ )
124
+ return variable_cube_out
125
+
126
+
127
+ def mask_cube(cube_in, mask):
128
+ """Mask cube where mask is not zero.
129
+
130
+ Parameters
131
+ ----------
132
+ cube_in : iris.cube.Cube
133
+ Unmasked data cube.
134
+
135
+ mask : iris.cube.Cube
136
+ Mask to use for masking, >0 where cube is supposed to be masked.
137
+
138
+ Returns
139
+ -------
140
+ variable_cube_out : iris.cube.Cube
141
+ Masked cube.
142
+ """
143
+
144
+ from dask.array import ma
145
+ from copy import deepcopy
146
+
147
+ cube_out = deepcopy(cube_in)
148
+ cube_out.data = ma.masked_where(mask.core_data() != 0, cube_in.core_data())
149
+ return cube_out
150
+
151
+
152
+ def mask_cell(mask, cell, track, masked=False):
153
+ """Create mask for specific cell.
154
+
155
+ Parameters
156
+ ----------
157
+ mask : iris.cube.Cube
158
+ Cube containing mask (int id for tracked volumes 0 everywhere
159
+ else).
160
+
161
+ cell : int
162
+ Integer id of cell to create masked cube for.
163
+
164
+ track : pandas.DataFrame
165
+ Output of the linking.
166
+
167
+ masked : bool, optional
168
+ Bool determining whether to mask the mask for the cell where
169
+ it is 0. Default is False.
170
+
171
+ Returns
172
+ -------
173
+ mask_i : numpy.ndarray
174
+ Mask for a specific cell.
175
+ """
176
+
177
+ feature_ids = track.loc[track["cell"] == cell, "feature"].values
178
+ mask_i = mask_features(mask, feature_ids, masked=masked)
179
+ return mask_i
180
+
181
+
182
+ def mask_cell_surface(mask, cell, track, masked=False, z_coord="model_level_number"):
183
+ """Create surface projection of 3d-mask for individual cell by
184
+ collapsing one coordinate.
185
+
186
+ Parameters
187
+ ----------
188
+ mask : iris.cube.Cube
189
+ Cube containing mask (int id for tacked volumes, 0 everywhere
190
+ else).
191
+
192
+ cell : int
193
+ Integer id of cell to create masked cube for.
194
+
195
+ track : pandas.DataFrame
196
+ Output of the linking.
197
+
198
+ masked : bool, optional
199
+ Bool determining whether to mask the mask for the cell where
200
+ it is 0. Default is False.
201
+
202
+ z_coord : str, optional
203
+ Name of the coordinate to collapse. Default is 'model_level_number'.
204
+
205
+ Returns
206
+ -------
207
+ mask_i_surface : iris.cube.Cube
208
+ Collapsed Masked cube for the cell with the maximum value
209
+ along the collapsed coordinate.
210
+
211
+ """
212
+
213
+ feature_ids = track.loc[track["cell"] == cell, "feature"].values
214
+ mask_i_surface = mask_features_surface(
215
+ mask, feature_ids, masked=masked, z_coord=z_coord
216
+ )
217
+ return mask_i_surface
218
+
219
+
220
+ def mask_cube_features(variable_cube, mask, feature_ids):
221
+ """Mask cube for tracked volume of one or more specific
222
+ features.
223
+
224
+ Parameters
225
+ ----------
226
+ variable_cube : iris.cube.Cube
227
+ Unmasked data cube.
228
+
229
+ mask : iris.cube.Cube
230
+ Cube containing mask (int id for tacked volumes, 0 everywhere
231
+ else).
232
+
233
+ feature_ids : int or list of ints
234
+ Integer ids of features to create masked cube for.
235
+
236
+ Returns
237
+ -------
238
+ variable_cube_out : iris.cube.Cube
239
+ Masked cube with data for respective features.
240
+ """
241
+
242
+ from dask.array import ma, isin
243
+ from copy import deepcopy
244
+
245
+ variable_cube_out = deepcopy(variable_cube)
246
+ variable_cube_out.data = ma.masked_where(
247
+ ~isin(mask.core_data(), feature_ids), variable_cube_out.core_data()
248
+ )
249
+ return variable_cube_out
250
+
251
+
252
+ def mask_features(mask, feature_ids, masked=False):
253
+ """Create mask for specific features.
254
+
255
+ Parameters
256
+ ----------
257
+ mask : iris.cube.Cube
258
+ Cube containing mask (int id for tacked volumes 0 everywhere
259
+ else).
260
+
261
+ feature_ids : int or list of ints
262
+ Integer ids of the features to create the masked cube for.
263
+
264
+ masked : bool, optional
265
+ Bool determining whether to mask the mask for the cell where
266
+ it is 0. Default is False.
267
+
268
+ Returns
269
+ -------
270
+ mask_i : numpy.ndarray
271
+ Masked cube for specific features.
272
+ """
273
+
274
+ from dask.array import ma, isin
275
+ from copy import deepcopy
276
+
277
+ mask_i = deepcopy(mask)
278
+ mask_i_data = mask_i.core_data()
279
+ mask_i_data[~isin(mask_i.core_data(), feature_ids)] = 0
280
+ if masked:
281
+ mask_i.data = ma.masked_equal(mask_i.core_data(), 0)
282
+ return mask_i
283
+
284
+
285
+ def mask_features_surface(
286
+ mask, feature_ids, masked=False, z_coord="model_level_number"
287
+ ):
288
+ """Create surface projection of 3d-mask for specific features
289
+ by collapsing one coordinate.
290
+
291
+ Parameters
292
+ ----------
293
+ mask : iris.cube.Cube
294
+ Cube containing mask (int id for tacked volumes 0 everywhere
295
+ else).
296
+
297
+ feature_ids : int or list of ints
298
+ Integer ids of the features to create the masked cube for.
299
+
300
+ masked : bool, optional
301
+ Bool determining whether to mask the mask for the cell where
302
+ it is 0. Default is False
303
+
304
+ z_coord : str, optional
305
+ Name of the coordinate to collapse. Default is
306
+ 'model_level_number'.
307
+
308
+ Returns
309
+ -------
310
+ mask_i_surface : iris.cube.Cube
311
+ Collapsed Masked cube for the features with the maximum value
312
+ along the collapsed coordinate.
313
+ """
314
+
315
+ from iris.analysis import MAX
316
+ from dask.array import ma, isin
317
+ from copy import deepcopy
318
+
319
+ mask_i = deepcopy(mask)
320
+ # mask_i.data=[~isin(mask_i.data,feature_ids)]=0
321
+ mask_i_data = mask_i.core_data()
322
+ mask_i_data[~isin(mask_i.core_data(), feature_ids)] = 0
323
+ mask_i_surface = mask_i.collapsed(z_coord, MAX)
324
+ if masked:
325
+ mask_i_surface.data = ma.masked_equal(mask_i_surface.core_data(), 0)
326
+ return mask_i_surface
327
+
328
+
329
+ def mask_all_surface(mask, masked=False, z_coord="model_level_number"):
330
+ """Create surface projection of 3d-mask for all features
331
+ by collapsing one coordinate.
332
+
333
+ Parameters
334
+ ----------
335
+ mask : iris.cube.Cube
336
+ Cube containing mask (int id for tacked volumes 0 everywhere
337
+ else).
338
+
339
+ masked : bool, optional
340
+ Bool determining whether to mask the mask for the cell where
341
+ it is 0. Default is False
342
+
343
+ z_coord : str, optional
344
+ Name of the coordinate to collapse. Default is
345
+ 'model_level_number'.
346
+
347
+ Returns
348
+ -------
349
+ mask_i_surface : iris.cube.Cube (2D)
350
+ Collapsed Masked cube for the features with the maximum value
351
+ along the collapsed coordinate.
352
+ """
353
+
354
+ from iris.analysis import MAX
355
+ from dask.array import ma, isin
356
+ from copy import deepcopy
357
+
358
+ mask_i = deepcopy(mask)
359
+ mask_i_surface = mask_i.collapsed(z_coord, MAX)
360
+ mask_i_surface_data = mask_i_surface.core_data()
361
+ mask_i_surface.data[mask_i_surface_data > 0] = 1
362
+ if masked:
363
+ mask_i_surface.data = ma.masked_equal(mask_i_surface.core_data(), 0)
364
+ return mask_i_surface