cellfinder 1.3.2__tar.gz → 1.4.0a0__tar.gz

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 cellfinder might be problematic. Click here for more details.

Files changed (81) hide show
  1. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/.github/workflows/test_and_deploy.yml +30 -7
  2. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/PKG-INFO +5 -4
  3. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/classify/classify.py +9 -1
  4. cellfinder-1.4.0a0/cellfinder/core/detect/detect.py +236 -0
  5. cellfinder-1.4.0a0/cellfinder/core/detect/filters/plane/classical_filter.py +347 -0
  6. cellfinder-1.4.0a0/cellfinder/core/detect/filters/plane/plane_filter.py +169 -0
  7. cellfinder-1.4.0a0/cellfinder/core/detect/filters/plane/tile_walker.py +154 -0
  8. cellfinder-1.4.0a0/cellfinder/core/detect/filters/setup_filters.py +427 -0
  9. cellfinder-1.4.0a0/cellfinder/core/detect/filters/volume/ball_filter.py +415 -0
  10. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/detect/filters/volume/structure_detection.py +73 -35
  11. cellfinder-1.4.0a0/cellfinder/core/detect/filters/volume/structure_splitting.py +306 -0
  12. cellfinder-1.4.0a0/cellfinder/core/detect/filters/volume/volume_filter.py +523 -0
  13. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/main.py +6 -2
  14. cellfinder-1.4.0a0/cellfinder/core/tools/IO.py +45 -0
  15. cellfinder-1.4.0a0/cellfinder/core/tools/threading.py +380 -0
  16. cellfinder-1.4.0a0/cellfinder/core/tools/tools.py +295 -0
  17. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder.egg-info/PKG-INFO +5 -4
  18. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder.egg-info/SOURCES.txt +2 -0
  19. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder.egg-info/requires.txt +4 -3
  20. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/pyproject.toml +6 -3
  21. cellfinder-1.3.2/cellfinder/core/detect/detect.py +0 -301
  22. cellfinder-1.3.2/cellfinder/core/detect/filters/plane/classical_filter.py +0 -45
  23. cellfinder-1.3.2/cellfinder/core/detect/filters/plane/plane_filter.py +0 -87
  24. cellfinder-1.3.2/cellfinder/core/detect/filters/plane/tile_walker.py +0 -88
  25. cellfinder-1.3.2/cellfinder/core/detect/filters/setup_filters.py +0 -70
  26. cellfinder-1.3.2/cellfinder/core/detect/filters/volume/ball_filter.py +0 -417
  27. cellfinder-1.3.2/cellfinder/core/detect/filters/volume/structure_splitting.py +0 -242
  28. cellfinder-1.3.2/cellfinder/core/detect/filters/volume/volume_filter.py +0 -202
  29. cellfinder-1.3.2/cellfinder/core/tools/tools.py +0 -173
  30. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/.github/workflows/test_include_guard.yaml +0 -0
  31. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/.gitignore +0 -0
  32. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/.napari/config.yml +0 -0
  33. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/CITATION.cff +0 -0
  34. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/LICENSE +0 -0
  35. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/MANIFEST.in +0 -0
  36. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/README.md +0 -0
  37. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/__init__.py +0 -0
  38. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/cli_migration_warning.py +0 -0
  39. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/__init__.py +0 -0
  40. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/classify/__init__.py +0 -0
  41. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/classify/augment.py +0 -0
  42. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/classify/cube_generator.py +0 -0
  43. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/classify/resnet.py +0 -0
  44. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/classify/tools.py +0 -0
  45. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/config/__init__.py +0 -0
  46. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/config/cellfinder.conf +0 -0
  47. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/detect/__init__.py +0 -0
  48. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/detect/filters/__init__.py +0 -0
  49. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/detect/filters/plane/__init__.py +0 -0
  50. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/detect/filters/volume/__init__.py +0 -0
  51. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/download/__init__.py +0 -0
  52. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/download/cli.py +0 -0
  53. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/download/download.py +0 -0
  54. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/tools/__init__.py +0 -0
  55. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/tools/array_operations.py +0 -0
  56. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/tools/geometry.py +0 -0
  57. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/tools/image_processing.py +0 -0
  58. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/tools/prep.py +0 -0
  59. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/tools/source_files.py +0 -0
  60. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/tools/system.py +0 -0
  61. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/tools/tiff.py +0 -0
  62. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/train/__init__.py +0 -0
  63. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/train/train_yml.py +0 -0
  64. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/core/types.py +0 -0
  65. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/__init__.py +0 -0
  66. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/curation.py +0 -0
  67. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/detect/__init__.py +0 -0
  68. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/detect/detect.py +0 -0
  69. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/detect/detect_containers.py +0 -0
  70. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/detect/thread_worker.py +0 -0
  71. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/input_container.py +0 -0
  72. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/napari.yaml +0 -0
  73. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/sample_data.py +0 -0
  74. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/train/__init__.py +0 -0
  75. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/train/train.py +0 -0
  76. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/train/train_containers.py +0 -0
  77. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder/napari/utils.py +0 -0
  78. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder.egg-info/dependency_links.txt +0 -0
  79. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder.egg-info/entry_points.txt +0 -0
  80. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/cellfinder.egg-info/top_level.txt +0 -0
  81. {cellfinder-1.3.2 → cellfinder-1.4.0a0}/setup.cfg +0 -0
@@ -9,6 +9,9 @@ on:
9
9
  - "v**"
10
10
  # Run on all pull-requests
11
11
  pull_request:
12
+ schedule:
13
+ # Runs at 6:10am UTC on Monday
14
+ - cron: '10 6 * * 1'
12
15
  # Allow workflow dispatch from GitHub
13
16
  workflow_dispatch:
14
17
 
@@ -35,26 +38,35 @@ jobs:
35
38
  test:
36
39
  needs: [linting, manifest]
37
40
  name: Run package tests
38
- timeout-minutes: 60
41
+ timeout-minutes: 120
39
42
  runs-on: ${{ matrix.os }}
40
43
  env:
41
44
  KERAS_BACKEND: torch
42
45
  CELLFINDER_TEST_DEVICE: cpu
46
+ # pooch cache dir
47
+ BRAINGLOBE_TEST_DATA_DIR: "~/.pooch_cache"
48
+
43
49
  strategy:
44
50
  matrix:
45
51
  # Run all supported Python versions on linux
46
52
  os: [ubuntu-latest]
47
53
  python-version: ["3.10", "3.11", "3.12"]
48
- # Include one windows and two macOS (intel based and arm based) runs
54
+ # Include one windows and one macOS (arm based) run
49
55
  include:
50
- - os: macos-13
51
- python-version: "3.12"
52
56
  - os: macos-latest
53
57
  python-version: "3.12"
54
58
  - os: windows-latest
55
59
  python-version: "3.12"
56
60
 
57
61
  steps:
62
+ - uses: actions/checkout@v4
63
+ - name: Cache pooch data
64
+ uses: actions/cache@v4
65
+ with:
66
+ path: "~/.pooch_cache"
67
+ # hash on conftest in case url changes
68
+ key: ${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/pooch_registry.txt') }}
69
+ # Cache the tensorflow model so we don't have to remake it every time
58
70
  - name: Cache brainglobe directory
59
71
  uses: actions/cache@v3
60
72
  with:
@@ -77,12 +89,16 @@ jobs:
77
89
  test_numba_disabled:
78
90
  needs: [linting, manifest]
79
91
  name: Run tests with numba disabled
80
- timeout-minutes: 60
92
+ timeout-minutes: 120
81
93
  runs-on: ubuntu-latest
82
94
  env:
83
- NUMBA_DISABLE_JIT: "1"
95
+ NUMBA_DISABLE_JIT: "1"
96
+ PYTORCH_JIT: "0"
97
+ # pooch cache dir
98
+ BRAINGLOBE_TEST_DATA_DIR: "~/.pooch_cache"
84
99
 
85
100
  steps:
101
+ - uses: actions/checkout@v4
86
102
  - name: Cache brainglobe directory
87
103
  uses: actions/cache@v3
88
104
  with:
@@ -90,6 +106,13 @@ jobs:
90
106
  ~/.brainglobe
91
107
  !~/.brainglobe/atlas.tar.gz
92
108
  key: brainglobe
109
+
110
+ - name: Cache pooch data
111
+ uses: actions/cache@v4
112
+ with:
113
+ path: "~/.pooch_cache"
114
+ key: ${{ runner.os }}-3.10-${{ hashFiles('**/pooch_registry.txt') }}
115
+
93
116
  # Setup pyqt libraries
94
117
  - name: Setup qtpy libraries
95
118
  uses: tlambert03/setup-qt-libs@v1
@@ -107,7 +130,7 @@ jobs:
107
130
  test_brainmapper_cli:
108
131
  needs: [linting, manifest]
109
132
  name: Run brainmapper tests to check for breakages
110
- timeout-minutes: 60
133
+ timeout-minutes: 120
111
134
  runs-on: ubuntu-latest
112
135
  env:
113
136
  KERAS_BACKEND: torch
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cellfinder
3
- Version: 1.3.2
3
+ Version: 1.4.0a0
4
4
  Summary: Automated 3D cell detection in large microscopy images
5
5
  Author-email: "Adam Tyson, Christian Niedworok, Charly Rousseau" <code@adamltyson.com>
6
6
  License: BSD-3-Clause
@@ -29,11 +29,11 @@ Requires-Dist: dask[array]
29
29
  Requires-Dist: fancylog>=0.0.7
30
30
  Requires-Dist: natsort
31
31
  Requires-Dist: numba
32
- Requires-Dist: numpy<2
32
+ Requires-Dist: numpy
33
33
  Requires-Dist: scikit-image
34
34
  Requires-Dist: scikit-learn
35
- Requires-Dist: keras>=3.0.0
36
- Requires-Dist: torch>=2.1.0
35
+ Requires-Dist: keras==3.5.0
36
+ Requires-Dist: torch!=2.4,>=2.1.0
37
37
  Requires-Dist: tifffile
38
38
  Requires-Dist: tqdm
39
39
  Provides-Extra: dev
@@ -46,6 +46,7 @@ Requires-Dist: pytest-qt; extra == "dev"
46
46
  Requires-Dist: pytest-timeout; extra == "dev"
47
47
  Requires-Dist: pytest; extra == "dev"
48
48
  Requires-Dist: tox; extra == "dev"
49
+ Requires-Dist: pooch>=1; extra == "dev"
49
50
  Provides-Extra: napari
50
51
  Requires-Dist: brainglobe-napari-io; extra == "napari"
51
52
  Requires-Dist: magicgui; extra == "napari"
@@ -30,7 +30,7 @@ def main(
30
30
  max_workers: int = 3,
31
31
  *,
32
32
  callback: Optional[Callable[[int], None]] = None,
33
- ) -> List:
33
+ ) -> List[Cell]:
34
34
  """
35
35
  Parameters
36
36
  ----------
@@ -68,6 +68,14 @@ def main(
68
68
  workers=workers,
69
69
  )
70
70
 
71
+ if trained_model and trained_model.suffix == ".h5":
72
+ print(
73
+ "Weights provided in place of the model, "
74
+ "loading weights into default model."
75
+ )
76
+ model_weights = trained_model
77
+ trained_model = None
78
+
71
79
  model = get_model(
72
80
  existing_model=trained_model,
73
81
  model_weights=model_weights,
@@ -0,0 +1,236 @@
1
+ """
2
+ Detection is run in three steps:
3
+
4
+ 1. 2D filtering
5
+ 2. 3D filtering
6
+ 3. Structure detection
7
+
8
+ In steps 1. and 2. filters are applied, and any bright points detected
9
+ post-filter are marked. To avoid using a separate mask array to mark the
10
+ bright points, the input data is clipped to [0, (max_val - 2)]
11
+ (max_val is the maximum value that the image data type can store), and:
12
+ - (max_val - 1) is used to mark bright points during 2D filtering
13
+ - (max_val) is used to mark bright points during 3D filtering
14
+ """
15
+
16
+ import dataclasses
17
+ from datetime import datetime
18
+ from typing import Callable, List, Optional, Tuple
19
+
20
+ import numpy as np
21
+ import torch
22
+ from brainglobe_utils.cells.cells import Cell
23
+
24
+ from cellfinder.core import logger, types
25
+ from cellfinder.core.detect.filters.plane import TileProcessor
26
+ from cellfinder.core.detect.filters.setup_filters import DetectionSettings
27
+ from cellfinder.core.detect.filters.volume.volume_filter import VolumeFilter
28
+ from cellfinder.core.tools.tools import inference_wrapper
29
+
30
+
31
+ @inference_wrapper
32
+ def main(
33
+ signal_array: types.array,
34
+ start_plane: int = 0,
35
+ end_plane: int = -1,
36
+ voxel_sizes: Tuple[float, float, float] = (5, 2, 2),
37
+ soma_diameter: float = 16,
38
+ max_cluster_size: float = 100_000,
39
+ ball_xy_size: float = 6,
40
+ ball_z_size: float = 15,
41
+ ball_overlap_fraction: float = 0.6,
42
+ soma_spread_factor: float = 1.4,
43
+ n_free_cpus: int = 2,
44
+ log_sigma_size: float = 0.2,
45
+ n_sds_above_mean_thresh: float = 10,
46
+ outlier_keep: bool = False,
47
+ artifact_keep: bool = False,
48
+ save_planes: bool = False,
49
+ plane_directory: Optional[str] = None,
50
+ batch_size: Optional[int] = None,
51
+ torch_device: str = "cpu",
52
+ use_scipy: bool = True,
53
+ split_ball_xy_size: int = 3,
54
+ split_ball_z_size: int = 3,
55
+ split_ball_overlap_fraction: float = 0.8,
56
+ split_soma_diameter: int = 7,
57
+ *,
58
+ callback: Optional[Callable[[int], None]] = None,
59
+ ) -> List[Cell]:
60
+ """
61
+ Perform cell candidate detection on a 3D signal array.
62
+
63
+ Parameters
64
+ ----------
65
+ signal_array : numpy.ndarray
66
+ 3D array representing the signal data.
67
+
68
+ start_plane : int
69
+ Index of the starting plane for detection.
70
+
71
+ end_plane : int
72
+ Index of the ending plane for detection.
73
+
74
+ voxel_sizes : Tuple[float, float, float]
75
+ Tuple of voxel sizes in each dimension (z, y, x).
76
+
77
+ soma_diameter : float
78
+ Diameter of the soma in physical units.
79
+
80
+ max_cluster_size : float
81
+ Maximum size of a cluster in physical units.
82
+
83
+ ball_xy_size : float
84
+ Size of the XY ball used for filtering in physical units.
85
+
86
+ ball_z_size : float
87
+ Size of the Z ball used for filtering in physical units.
88
+
89
+ ball_overlap_fraction : float
90
+ Fraction of overlap allowed between balls.
91
+
92
+ soma_spread_factor : float
93
+ Spread factor for soma size.
94
+
95
+ n_free_cpus : int
96
+ Number of free CPU cores available for parallel processing.
97
+
98
+ log_sigma_size : float
99
+ Size of the sigma for the log filter.
100
+
101
+ n_sds_above_mean_thresh : float
102
+ Number of standard deviations above the mean threshold.
103
+
104
+ outlier_keep : bool, optional
105
+ Whether to keep outliers during detection. Defaults to False.
106
+
107
+ artifact_keep : bool, optional
108
+ Whether to keep artifacts during detection. Defaults to False.
109
+
110
+ save_planes : bool, optional
111
+ Whether to save the planes during detection. Defaults to False.
112
+
113
+ plane_directory : str, optional
114
+ Directory path to save the planes. Defaults to None.
115
+
116
+ batch_size : int, optional
117
+ The number of planes to process in each batch. Defaults to 1.
118
+ For CPU, there's no benefit for a larger batch size. Only a memory
119
+ usage increase. For CUDA, the larger the batch size the better the
120
+ performance. Until it fills up the GPU memory - after which it
121
+ becomes slower.
122
+
123
+ torch_device : str, optional
124
+ The device on which to run the computation. By default, it's "cpu".
125
+ To run on a gpu, specify the PyTorch device name, such as "cuda" to
126
+ run on the first GPU.
127
+
128
+ callback : Callable[int], optional
129
+ A callback function that is called every time a plane has finished
130
+ being processed. Called with the plane number that has finished.
131
+
132
+ Returns
133
+ -------
134
+ List[Cell]
135
+ List of detected cells.
136
+ """
137
+ start_time = datetime.now()
138
+ if batch_size is None:
139
+ if torch_device == "cpu":
140
+ batch_size = 4
141
+ else:
142
+ batch_size = 1
143
+
144
+ if not np.issubdtype(signal_array.dtype, np.number):
145
+ raise TypeError(
146
+ "signal_array must be a numpy datatype, but has datatype "
147
+ f"{signal_array.dtype}"
148
+ )
149
+
150
+ if signal_array.ndim != 3:
151
+ raise ValueError("Input data must be 3D")
152
+
153
+ if end_plane < 0:
154
+ end_plane = len(signal_array)
155
+ end_plane = min(len(signal_array), end_plane)
156
+
157
+ torch_device = torch_device.lower()
158
+ batch_size = max(batch_size, 1)
159
+ # brainmapper can pass them in as str
160
+ voxel_sizes = list(map(float, voxel_sizes))
161
+
162
+ settings = DetectionSettings(
163
+ plane_shape=signal_array.shape[1:],
164
+ plane_original_np_dtype=signal_array.dtype,
165
+ voxel_sizes=voxel_sizes,
166
+ soma_spread_factor=soma_spread_factor,
167
+ soma_diameter_um=soma_diameter,
168
+ max_cluster_size_um3=max_cluster_size,
169
+ ball_xy_size_um=ball_xy_size,
170
+ ball_z_size_um=ball_z_size,
171
+ start_plane=start_plane,
172
+ end_plane=end_plane,
173
+ n_free_cpus=n_free_cpus,
174
+ ball_overlap_fraction=ball_overlap_fraction,
175
+ log_sigma_size=log_sigma_size,
176
+ n_sds_above_mean_thresh=n_sds_above_mean_thresh,
177
+ outlier_keep=outlier_keep,
178
+ artifact_keep=artifact_keep,
179
+ save_planes=save_planes,
180
+ plane_directory=plane_directory,
181
+ batch_size=batch_size,
182
+ torch_device=torch_device,
183
+ )
184
+
185
+ # replicate the settings specific to splitting, before we access anything
186
+ # of the original settings, causing cached properties
187
+ kwargs = dataclasses.asdict(settings)
188
+ kwargs["ball_z_size_um"] = split_ball_z_size * settings.z_pixel_size
189
+ kwargs["ball_xy_size_um"] = (
190
+ split_ball_xy_size * settings.in_plane_pixel_size
191
+ )
192
+ kwargs["ball_overlap_fraction"] = split_ball_overlap_fraction
193
+ kwargs["soma_diameter_um"] = (
194
+ split_soma_diameter * settings.in_plane_pixel_size
195
+ )
196
+ # always run on cpu because copying to gpu overhead is likely slower than
197
+ # any benefit for detection on smallish volumes
198
+ kwargs["torch_device"] = "cpu"
199
+ # for splitting, we only do 3d filtering. Its input is a zero volume
200
+ # with cell voxels marked with threshold_value. So just use float32
201
+ # for input because the filters will also use float(32). So there will
202
+ # not be need to convert the input a different dtype before passing to
203
+ # the filters.
204
+ kwargs["plane_original_np_dtype"] = np.float32
205
+ splitting_settings = DetectionSettings(**kwargs)
206
+
207
+ # Create 3D analysis filter
208
+ mp_3d_filter = VolumeFilter(settings=settings)
209
+
210
+ # Create 2D analysis filter
211
+ mp_tile_processor = TileProcessor(
212
+ plane_shape=settings.plane_shape,
213
+ clipping_value=settings.clipping_value,
214
+ threshold_value=settings.threshold_value,
215
+ n_sds_above_mean_thresh=n_sds_above_mean_thresh,
216
+ log_sigma_size=log_sigma_size,
217
+ soma_diameter=settings.soma_diameter,
218
+ torch_device=torch_device,
219
+ dtype=settings.filtering_dtype.__name__,
220
+ use_scipy=use_scipy,
221
+ )
222
+
223
+ orig_n_threads = torch.get_num_threads()
224
+ torch.set_num_threads(settings.n_torch_comp_threads)
225
+
226
+ # process the data
227
+ mp_3d_filter.process(mp_tile_processor, signal_array, callback=callback)
228
+ cells = mp_3d_filter.get_results(splitting_settings)
229
+
230
+ torch.set_num_threads(orig_n_threads)
231
+
232
+ time_elapsed = datetime.now() - start_time
233
+ s = f"Detection complete. Found {len(cells)} cells in {time_elapsed}"
234
+ logger.debug(s)
235
+ print(s)
236
+ return cells