cellects 0.1.3__py3-none-any.whl → 0.2.7__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 (38) hide show
  1. cellects/__main__.py +65 -25
  2. cellects/config/all_vars_dict.py +18 -17
  3. cellects/core/cellects_threads.py +1034 -396
  4. cellects/core/motion_analysis.py +1664 -2010
  5. cellects/core/one_image_analysis.py +1082 -1061
  6. cellects/core/program_organizer.py +1687 -1316
  7. cellects/core/script_based_run.py +80 -76
  8. cellects/gui/advanced_parameters.py +365 -326
  9. cellects/gui/cellects.py +102 -91
  10. cellects/gui/custom_widgets.py +4 -3
  11. cellects/gui/first_window.py +226 -104
  12. cellects/gui/if_several_folders_window.py +117 -68
  13. cellects/gui/image_analysis_window.py +841 -450
  14. cellects/gui/required_output.py +100 -56
  15. cellects/gui/ui_strings.py +840 -0
  16. cellects/gui/video_analysis_window.py +317 -135
  17. cellects/image_analysis/cell_leaving_detection.py +64 -4
  18. cellects/image_analysis/image_segmentation.py +451 -22
  19. cellects/image_analysis/morphological_operations.py +2166 -1635
  20. cellects/image_analysis/network_functions.py +616 -253
  21. cellects/image_analysis/one_image_analysis_threads.py +94 -153
  22. cellects/image_analysis/oscillations_functions.py +131 -0
  23. cellects/image_analysis/progressively_add_distant_shapes.py +2 -3
  24. cellects/image_analysis/shape_descriptors.py +517 -466
  25. cellects/utils/formulas.py +169 -6
  26. cellects/utils/load_display_save.py +362 -105
  27. cellects/utils/utilitarian.py +86 -9
  28. cellects-0.2.7.dist-info/LICENSE +675 -0
  29. cellects-0.2.7.dist-info/METADATA +829 -0
  30. cellects-0.2.7.dist-info/RECORD +44 -0
  31. cellects/core/one_video_per_blob.py +0 -540
  32. cellects/image_analysis/cluster_flux_study.py +0 -102
  33. cellects-0.1.3.dist-info/LICENSE.odt +0 -0
  34. cellects-0.1.3.dist-info/METADATA +0 -176
  35. cellects-0.1.3.dist-info/RECORD +0 -44
  36. {cellects-0.1.3.dist-info → cellects-0.2.7.dist-info}/WHEEL +0 -0
  37. {cellects-0.1.3.dist-info → cellects-0.2.7.dist-info}/entry_points.txt +0 -0
  38. {cellects-0.1.3.dist-info → cellects-0.2.7.dist-info}/top_level.txt +0 -0
@@ -28,6 +28,7 @@ Notes:
28
28
  - Image processing functions expect binary (boolean/int8) input matrices
29
29
  """
30
30
  from copy import deepcopy
31
+ import pandas as pd
31
32
  from cellects.utils.decorators import njit
32
33
  import numpy as np
33
34
  from numpy.typing import NDArray
@@ -115,10 +116,22 @@ def bracket_to_uint8_image_contrast(image: NDArray):
115
116
  -------
116
117
  ndarray of uint8
117
118
  Output image converted to uint8 type after normalization.
118
- """
119
- image -= np.min(image)
120
- return to_uint8(255 * (image / np.max(image)))
121
119
 
120
+ Examples
121
+ --------
122
+ >>> image = np.random.randint(0, 255, (10, 10), dtype=np.uint8)
123
+ >>> res = bracket_to_uint8_image_contrast(image)
124
+ >>> print(res)
125
+
126
+ >>> image = np.zeros((10, 10), dtype=np.uint8)
127
+ >>> res = bracket_to_uint8_image_contrast(image)
128
+ >>> print(res)
129
+ """
130
+ image -= image.min()
131
+ if image.max() == 0:
132
+ return np.zeros_like(image, dtype=np.uint8)
133
+ else:
134
+ return to_uint8(255 * (image / np.max(image)))
122
135
 
123
136
  @njit()
124
137
  def linear_model(x: NDArray, a: float, b: float) -> float:
@@ -229,8 +242,11 @@ def get_var(mo: dict, binary_image: NDArray, Xn: NDArray, Yn: NDArray) -> Tuple[
229
242
  -----
230
243
  Performance considerations: This function uses Numba's `@njit` decorator for performance.
231
244
  """
232
- vx = np.sum(binary_image * Xn) / mo["m00"]
233
- vy = np.sum(binary_image * Yn) / mo["m00"]
245
+ if mo['m00'] == 0:
246
+ vx, vy = 0., 0.
247
+ else:
248
+ vx = np.sum(binary_image * Xn) / mo["m00"]
249
+ vy = np.sum(binary_image * Yn) / mo["m00"]
234
250
  return vx, vy
235
251
 
236
252
 
@@ -277,7 +293,17 @@ def get_skewness_kurtosis(mnx: float, mny: float, sx: float, sy: float, n: int)
277
293
  Kurtosis: nan
278
294
 
279
295
  """
280
- return mnx / sx ** n, mny / sy ** n
296
+ if sx == 0:
297
+ fx = 0
298
+ else:
299
+ fx = mnx / sx ** n
300
+
301
+ if sy == 0:
302
+ fy = 0
303
+ else:
304
+ fy = mny / sy ** n
305
+
306
+ return fx, fy
281
307
 
282
308
 
283
309
  def get_standard_deviations(mo: dict, binary_image: NDArray, cx: float, cy: float) -> Tuple[float, float]:
@@ -635,3 +661,140 @@ def find_duplicates_coord(array1: NDArray[int]) -> NDArray[bool]:
635
661
  counts = np.bincount(inverse_indices)
636
662
  # A row is duplicate if its count > 1
637
663
  return counts[inverse_indices] > 1
664
+
665
+ def detect_first_move(size_dynamics: NDArray, growth_threshold)-> int:
666
+ """
667
+ Detects the first move in a time series where the value exceeds the initial value by a given threshold.
668
+
669
+ Parameters
670
+ ----------
671
+ size_dynamics : numpy.ndarray
672
+ The time series data of dynamics.
673
+ growth_threshold: int or float
674
+ The threshold value for detecting the first move.
675
+
676
+ Returns
677
+ -------
678
+ int or pandas.NA
679
+ The index of the first move where the condition is met.
680
+ Returns `pandas.NA` if no such index exists.
681
+
682
+ Examples
683
+ --------
684
+ >>> size_dynamics = np.array([10, 12, 15, 18])
685
+ >>> growth_threshold = 5
686
+ >>> detect_first_move(size_dynamics, growth_threshold)
687
+ 2
688
+ """
689
+ first_move = pd.NA
690
+ thresh_reached = np.nonzero(size_dynamics >= (size_dynamics[0] + growth_threshold))[0]
691
+ if len(thresh_reached) > 0:
692
+ first_move = thresh_reached[0]
693
+ return first_move
694
+
695
+ @njit()
696
+ def get_newly_explored_area(binary_vid: NDArray[np.uint8]) -> NDArray:
697
+ """
698
+ Get newly explored area in a binary video.
699
+
700
+ Calculate the number of new pixels that have become active (==1) from
701
+ the previous frame in a binary video representation.
702
+
703
+ Parameters
704
+ ----------
705
+ binary_vid : np.ndarray
706
+ The current frame of the binary video.
707
+
708
+ Returns
709
+ -------
710
+ np.ndarray
711
+ An array containing the number of new active pixels for each row.
712
+
713
+ Notes
714
+ -----
715
+ This function uses Numba's @njit decorator for performance.
716
+
717
+ Examples
718
+ --------
719
+ >>> binary_vid=np.zeros((4, 5, 5), dtype=np.uint8)
720
+ >>> binary_vid[:2, 3, 3] = 1
721
+ >>> binary_vid[1, 4, 3] = 1
722
+ >>> binary_vid[2, 3, 4] = 1
723
+ >>> binary_vid[3, 2, 3] = 1
724
+ >>> get_newly_explored_area(binary_vid)
725
+ array([0, 1, 1, 1])
726
+
727
+ >>> binary_vid=np.zeros((5, 5), dtype=np.uint8)[None, :, :]
728
+ >>> get_newly_explored_area(binary_vid)
729
+ array([0])
730
+ """
731
+ return ((binary_vid - binary_vid[0, ...]) == 1).reshape(binary_vid.shape[0], - 1).sum(1)
732
+
733
+ def get_contour_width_from_im_shape(im_shape: Tuple) -> int:
734
+ """
735
+ Calculate the contour width based on image shape.
736
+
737
+ Parameters
738
+ ----------
739
+ im_shape : tuple of int, two items
740
+ The dimensions of the image.
741
+
742
+ Returns
743
+ -------
744
+ int
745
+ The calculated contour width.
746
+ """
747
+ return np.max((np.round(np.log10(np.max(im_shape)) - 2).astype(int), 1))
748
+
749
+ def scale_coordinates(coord: NDArray, scale: Tuple, dims: Tuple) -> Tuple[NDArray[np.int64], np.int64, np.int64, np.int64, np.int64]:
750
+ """
751
+ Scale coordinates based on given scale factors and dimensions.
752
+
753
+ Parameters
754
+ ----------
755
+ coord : numpy.ndarray
756
+ A 2x2 array of coordinates to be scaled.
757
+ scale : tuple of float
758
+ Scaling factors for the x and y coordinates, respectively.
759
+ dims : tuple of int
760
+ Maximum dimensions (height, width) for the scaled coordinates.
761
+
762
+ Returns
763
+ -------
764
+ numpy.ndarray
765
+ Scaled and rounded coordinates.
766
+ int
767
+ Minimum y-coordinate.
768
+ int
769
+ Maximum y-coordinate.
770
+ int
771
+ Minimum x-coordinate.
772
+ int
773
+ Maximum x-coordinate.
774
+
775
+ Examples
776
+ --------
777
+ >>> coord = np.array(((47, 38), (59, 37)))
778
+ >>> scale = (0.92, 0.87)
779
+ >>> dims = (245, 300, 3)
780
+ >>> scaled_coord, min_y, max_y, min_x, max_x = scale_coordinates(coord, scale, dims)
781
+ >>> scaled_coord
782
+ array([[43, 33],
783
+ [54, 32]])
784
+ >>> min_y, max_y
785
+ (np.int64(43), np.int64(54))
786
+ >>> min_x, max_x
787
+ (np.int64(32), np.int64(33))
788
+
789
+ Notes
790
+ -----
791
+ This function assumes that the input coordinates are in a specific format
792
+ and will fail if not. The scaling factors should be positive.
793
+ """
794
+ coord = np.array(((np.round(coord[0][0] * scale[0]), np.round(coord[0][1] * scale[1])),
795
+ (np.round(coord[1][0] * scale[0]), np.round(coord[1][1] * scale[1]))), dtype=np.int64)
796
+ min_y = np.max((0, np.min(coord[:, 0])))
797
+ max_y = np.min((dims[0], np.max(coord[:, 0])))
798
+ min_x = np.max((0, np.min(coord[:, 1])))
799
+ max_x = np.min((dims[1], np.max(coord[:, 1])))
800
+ return coord, min_y, max_y, min_x, max_x