cellfinder 1.5.1__py3-none-any.whl → 1.7.0__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.

Potentially problematic release.


This version of cellfinder might be problematic. Click here for more details.

@@ -1,5 +1,7 @@
1
1
  import argparse
2
2
 
3
+ from cellfinder.core import logger
4
+
3
5
  BRAINGLOBE_WORKFLOWS = "https://github.com/brainglobe/brainglobe-workflows"
4
6
  NEW_NAME = "brainmapper"
5
7
  BLOG_POST = "https://brainglobe.info/blog/version1/core_and_napari_merge.html"
@@ -36,7 +38,7 @@ def cli_catch() -> None:
36
38
  ),
37
39
  )
38
40
 
39
- print(
41
+ logger.warning(
40
42
  "Hey, it looks like you're trying to run the old command-line tool.",
41
43
  "This workflow has been renamed and moved -",
42
44
  " you can now find it in the brainglobe-workflows package:\n",
@@ -11,7 +11,7 @@ from brainglobe_utils.general.system import get_num_processes
11
11
  from cellfinder.core import logger, types
12
12
  from cellfinder.core.classify.cube_generator import CubeGeneratorFromFile
13
13
  from cellfinder.core.classify.tools import get_model
14
- from cellfinder.core.train.train_yml import depth_type, models
14
+ from cellfinder.core.train.train_yaml import depth_type, models
15
15
 
16
16
 
17
17
  def main(
@@ -70,7 +70,7 @@ def main(
70
70
  )
71
71
 
72
72
  if trained_model and Path(trained_model).suffix == ".h5":
73
- print(
73
+ logger.warning(
74
74
  "Weights provided in place of the model, "
75
75
  "loading weights into default model."
76
76
  )
@@ -103,7 +103,7 @@ def main(
103
103
  points_list.append(cell)
104
104
 
105
105
  time_elapsed = datetime.now() - start_time
106
- print(
106
+ logger.info(
107
107
  "Classfication complete - all points done in : {}".format(time_elapsed)
108
108
  )
109
109
 
@@ -47,9 +47,19 @@ def get_model(
47
47
  f"Setting model weights according to: {model_weights}",
48
48
  )
49
49
  if model_weights is None:
50
- raise OSError("`model_weights` must be provided")
51
- model.load_weights(model_weights)
52
- return model
50
+ raise OSError(
51
+ "`model_weights` must be provided for inference "
52
+ "or continued training."
53
+ )
54
+ try:
55
+ model.load_weights(model_weights)
56
+ except (OSError, ValueError) as e:
57
+ raise ValueError(
58
+ f"Error loading weights: {model_weights}.\n"
59
+ "Provided weights don't match the model architecture.\n"
60
+ ) from e
61
+
62
+ return model
53
63
 
54
64
 
55
65
  def make_lists(
@@ -48,8 +48,7 @@ def main(
48
48
  save_planes: bool = False,
49
49
  plane_directory: Optional[str] = None,
50
50
  batch_size: Optional[int] = None,
51
- torch_device: str = "cpu",
52
- use_scipy: bool = True,
51
+ torch_device: Optional[str] = None,
53
52
  split_ball_xy_size: int = 3,
54
53
  split_ball_z_size: int = 3,
55
54
  split_ball_overlap_fraction: float = 0.8,
@@ -121,9 +120,9 @@ def main(
121
120
  becomes slower.
122
121
 
123
122
  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.
123
+ The device on which to run the computation. If not specified (None),
124
+ "cuda" will be used if a GPU is available, otherwise "cpu".
125
+ You can also manually specify "cuda" or "cpu".
127
126
 
128
127
  callback : Callable[int], optional
129
128
  A callback function that is called every time a plane has finished
@@ -135,6 +134,8 @@ def main(
135
134
  List of detected cells.
136
135
  """
137
136
  start_time = datetime.now()
137
+ if torch_device is None:
138
+ torch_device = "cuda" if torch.cuda.is_available() else "cpu"
138
139
  if batch_size is None:
139
140
  if torch_device == "cpu":
140
141
  batch_size = 4
@@ -155,6 +156,12 @@ def main(
155
156
  end_plane = min(len(signal_array), end_plane)
156
157
 
157
158
  torch_device = torch_device.lower()
159
+ # Use SciPy filtering on CPU (better performance); use PyTorch on GPU
160
+ if torch_device != "cuda":
161
+ use_scipy = True
162
+ else:
163
+ use_scipy = False
164
+
158
165
  batch_size = max(batch_size, 1)
159
166
  # brainmapper can pass them in as str
160
167
  voxel_sizes = list(map(float, voxel_sizes))
@@ -231,6 +238,5 @@ def main(
231
238
 
232
239
  time_elapsed = datetime.now() - start_time
233
240
  s = f"Detection complete. Found {len(cells)} cells in {time_elapsed}"
234
- logger.debug(s)
235
- print(s)
241
+ logger.info(s)
236
242
  return cells
@@ -6,6 +6,7 @@ import pooch
6
6
  from brainglobe_utils.general.config import get_config_obj
7
7
 
8
8
  from cellfinder import DEFAULT_CELLFINDER_DIRECTORY
9
+ from cellfinder.core import logger
9
10
  from cellfinder.core.tools.source_files import (
10
11
  default_configuration_path,
11
12
  user_specific_configuration_path,
@@ -74,7 +75,7 @@ def amend_user_configuration(new_model_path=None) -> None:
74
75
  new_model_path : Path, optional
75
76
  The path to the new model configuration.
76
77
  """
77
- print("(Over-)writing custom user configuration")
78
+ logger.info("(Over-)writing custom user configuration")
78
79
 
79
80
  original_config = default_configuration_path()
80
81
  new_config = user_specific_configuration_path()
cellfinder/core/main.py CHANGED
@@ -6,7 +6,7 @@ from brainglobe_utils.cells.cells import Cell
6
6
 
7
7
  from cellfinder.core import logger
8
8
  from cellfinder.core.download.download import model_type
9
- from cellfinder.core.train.train_yml import depth_type
9
+ from cellfinder.core.train.train_yaml import depth_type
10
10
 
11
11
 
12
12
  def main(
@@ -37,7 +37,7 @@ def main(
37
37
  skip_classification: bool = False,
38
38
  detected_cells: List[Cell] = None,
39
39
  classification_batch_size: Optional[int] = None,
40
- classification_torch_device: str = "cpu",
40
+ torch_device: Optional[str] = None,
41
41
  *,
42
42
  detect_callback: Optional[Callable[[int], None]] = None,
43
43
  classify_callback: Optional[Callable[[int], None]] = None,
@@ -77,7 +77,7 @@ def main(
77
77
  log_sigma_size,
78
78
  n_sds_above_mean_thresh,
79
79
  batch_size=classification_batch_size,
80
- torch_device=classification_torch_device,
80
+ torch_device=torch_device,
81
81
  callback=detect_callback,
82
82
  )
83
83
 
@@ -15,6 +15,7 @@ Typical example::
15
15
 
16
16
  from cellfinder.core.tools.threading import ThreadWithException, \\
17
17
  EOFSignal, ProcessWithException
18
+ from cellfinder.core import logger
18
19
  import torch
19
20
 
20
21
 
@@ -63,7 +64,7 @@ Typical example::
63
64
  # thread exited for whatever reason (not exception)
64
65
  break
65
66
 
66
- print(f"Thread processed tensor {i}")
67
+ logger.debug(f"Thread processed tensor {i}")
67
68
  finally:
68
69
  # whatever happens, make sure thread is told to finish so it
69
70
  # doesn't get stuck
@@ -248,8 +249,8 @@ class ExceptionWithQueueMixIn:
248
249
  ... # do something with the msg
249
250
  ... pass
250
251
  ... except ExecutionFailure as e:
251
- ... print(f"got exception {type(e.__cause__)}")
252
- ... print(f"with message {e.__cause__.args[0]}")
252
+ ... logger.error(f"got exception {type(e.__cause__)}")
253
+ ... logger.error(f"with message {e.__cause__.args[0]}")
253
254
  """
254
255
  msg, value = self.from_thread_queue.get(block=True, timeout=timeout)
255
256
  if msg == "eof":
@@ -3,9 +3,6 @@ main
3
3
  ===============
4
4
 
5
5
  Trains a network based on a yaml file specifying cubes of cells/non cells.
6
-
7
- N.B imports are within functions to prevent tensorflow being imported before
8
- it's warnings are silenced
9
6
  """
10
7
 
11
8
  import os
@@ -29,12 +26,16 @@ from brainglobe_utils.general.system import (
29
26
  from brainglobe_utils.IO.cells import find_relevant_tiffs
30
27
  from brainglobe_utils.IO.yaml import read_yaml_section
31
28
  from fancylog import fancylog
29
+ from keras.callbacks import CSVLogger, ModelCheckpoint, TensorBoard
32
30
  from sklearn.model_selection import train_test_split
33
31
 
34
32
  import cellfinder.core as program_for_log
35
33
  from cellfinder.core import logger
34
+ from cellfinder.core.classify.cube_generator import CubeGeneratorFromDisk
36
35
  from cellfinder.core.classify.resnet import layer_type
36
+ from cellfinder.core.classify.tools import get_model, make_lists
37
37
  from cellfinder.core.download.download import DEFAULT_DOWNLOAD_DIRECTORY
38
+ from cellfinder.core.tools.prep import prep_model_weights
38
39
 
39
40
  depth_type = Literal["18", "34", "50", "101", "152"]
40
41
 
@@ -316,16 +317,6 @@ def run(
316
317
  save_progress=False,
317
318
  epochs=100,
318
319
  ):
319
- from keras.callbacks import (
320
- CSVLogger,
321
- ModelCheckpoint,
322
- TensorBoard,
323
- )
324
-
325
- from cellfinder.core.classify.cube_generator import CubeGeneratorFromDisk
326
- from cellfinder.core.classify.tools import get_model, make_lists
327
- from cellfinder.core.tools.prep import prep_model_weights
328
-
329
320
  start_time = datetime.now()
330
321
 
331
322
  ensure_directory_exists(output_dir)
@@ -95,6 +95,22 @@ class CurationWidget(QWidget):
95
95
  self.training_data_non_cell_choice, self.point_layer_names
96
96
  )
97
97
 
98
+ @self.viewer.layers.events.removed.connect
99
+ def _remove_selection_layers(event: QtCore.QEvent):
100
+ """
101
+ Set internal background, signal, training data cell,
102
+ and training data non-cell layers to None when they
103
+ are removed from the napari viewer GUI.
104
+ """
105
+ if event.value == self.signal_layer:
106
+ self.signal_layer = None
107
+ if event.value == self.background_layer:
108
+ self.background_layer = None
109
+ if event.value == self.training_data_cell_layer:
110
+ self.training_data_cell_layer = None
111
+ if event.value == self.training_data_non_cell_layer:
112
+ self.training_data_non_cell_layer = None
113
+
98
114
  @staticmethod
99
115
  def _update_combobox_options(combobox: QComboBox, options_list: List[str]):
100
116
  original_text = combobox.currentText()
@@ -406,7 +422,7 @@ class CurationWidget(QWidget):
406
422
  self.update_status_label("Ready")
407
423
 
408
424
  def __prep_directories_for_save(self):
409
- self.yaml_filename = self.output_directory / "training.yml"
425
+ self.yaml_filename = self.output_directory / "training.yaml"
410
426
  self.cell_cube_dir = self.output_directory / "cells"
411
427
  self.no_cell_cube_dir = self.output_directory / "non_cells"
412
428
 
@@ -261,6 +261,7 @@ def detect_widget() -> FunctionGui:
261
261
  end_plane: int,
262
262
  n_free_cpus: int,
263
263
  analyse_local: bool,
264
+ use_gpu: bool,
264
265
  debug: bool,
265
266
  reset_button,
266
267
  ) -> None:
@@ -315,6 +316,8 @@ def detect_widget() -> FunctionGui:
315
316
  How many CPU cores to leave free
316
317
  analyse_local : bool
317
318
  Only analyse planes around the current position
319
+ use_gpu : bool
320
+ If True, use GPU for processing (if available); otherwise, use CPU.
318
321
  debug : bool
319
322
  Increase logging
320
323
  reset_button :
@@ -389,7 +392,7 @@ def detect_widget() -> FunctionGui:
389
392
  end_plane = len(signal_image.data)
390
393
 
391
394
  misc_inputs = MiscInputs(
392
- start_plane, end_plane, n_free_cpus, analyse_local, debug
395
+ start_plane, end_plane, n_free_cpus, analyse_local, use_gpu, debug
393
396
  )
394
397
 
395
398
  worker = Worker(
@@ -1,8 +1,9 @@
1
- from dataclasses import dataclass
1
+ from dataclasses import dataclass, field
2
2
  from pathlib import Path
3
3
  from typing import List, Optional
4
4
 
5
5
  import numpy
6
+ import torch
6
7
  from brainglobe_utils.cells.cells import Cell
7
8
 
8
9
  from cellfinder.napari.input_container import InputContainer
@@ -30,7 +31,7 @@ class DataInputs(InputContainer):
30
31
  self.voxel_size_x,
31
32
  )
32
33
  # del operator doesn't affect self, because asdict creates a copy of
33
- # fields.
34
+ # the dict.
34
35
  del data_input_dict["voxel_size_z"]
35
36
  del data_input_dict["voxel_size_y"]
36
37
  del data_input_dict["voxel_size_x"]
@@ -144,10 +145,13 @@ class MiscInputs(InputContainer):
144
145
  end_plane: int = 0
145
146
  n_free_cpus: int = 2
146
147
  analyse_local: bool = False
148
+ use_gpu: bool = field(default_factory=lambda: torch.cuda.is_available())
147
149
  debug: bool = False
148
150
 
149
151
  def as_core_arguments(self) -> dict:
150
152
  misc_input_dict = super().as_core_arguments()
153
+ misc_input_dict["torch_device"] = "cuda" if self.use_gpu else "cpu"
154
+ del misc_input_dict["use_gpu"]
151
155
  del misc_input_dict["debug"]
152
156
  del misc_input_dict["analyse_local"]
153
157
  return misc_input_dict
@@ -162,5 +166,11 @@ class MiscInputs(InputContainer):
162
166
  "n_free_cpus", custom_label="Number of free CPUs"
163
167
  ),
164
168
  analyse_local=dict(value=cls.defaults()["analyse_local"]),
169
+ use_gpu=dict(
170
+ widget_type="CheckBox",
171
+ label="Use GPU",
172
+ value=cls.defaults()["use_gpu"],
173
+ enabled=torch.cuda.is_available(),
174
+ ),
165
175
  debug=dict(value=cls.defaults()["debug"]),
166
176
  )
@@ -1,8 +1,18 @@
1
1
  from abc import abstractmethod
2
- from dataclasses import asdict, dataclass
2
+ from dataclasses import dataclass, fields
3
3
  from typing import Optional
4
4
 
5
5
 
6
+ def asdict_no_copy(obj: dataclass) -> dict:
7
+ """
8
+ Similar to `asdict`, except it makes no copies of the field values.
9
+ asdict will do a deep copy of field values that are non-basic objects.
10
+
11
+ It still creates a new dict to return, though.
12
+ """
13
+ return {field.name: getattr(obj, field.name) for field in fields(obj)}
14
+
15
+
6
16
  @dataclass
7
17
  class InputContainer:
8
18
  """Base for classes that contain inputs
@@ -23,7 +33,7 @@ class InputContainer:
23
33
  # Derived classes are not expected to be particularly
24
34
  # slow to instantiate, so use the default constructor
25
35
  # to avoid code repetition.
26
- return asdict(cls())
36
+ return asdict_no_copy(cls())
27
37
 
28
38
  @abstractmethod
29
39
  def as_core_arguments(self) -> dict:
@@ -32,10 +42,10 @@ class InputContainer:
32
42
  The implementation provided here can be re-used in derived classes, if
33
43
  convenient.
34
44
  """
35
- # note that asdict returns a new instance of a dict,
45
+ # note that asdict_no_copy returns a new instance of a dict,
36
46
  # so any subsequent modifications of this dict won't affect the class
37
47
  # instance
38
- return asdict(self)
48
+ return asdict_no_copy(self)
39
49
 
40
50
  @classmethod
41
51
  def _custom_widget(
@@ -7,7 +7,7 @@ from napari.qt.threading import thread_worker
7
7
  from napari.utils.notifications import show_info
8
8
  from qtpy.QtWidgets import QScrollArea
9
9
 
10
- from cellfinder.core.train.train_yml import run as train_yml
10
+ from cellfinder.core.train.train_yaml import run as train_yaml
11
11
  from cellfinder.napari.utils import cellfinder_header, html_label_widget
12
12
 
13
13
  from .train_containers import (
@@ -25,14 +25,14 @@ def run_training(
25
25
  optional_training_inputs: OptionalTrainingInputs,
26
26
  misc_training_inputs: MiscTrainingInputs,
27
27
  ):
28
- print("Running training")
29
- train_yml(
28
+ show_info("Running training...")
29
+ train_yaml(
30
30
  **training_data_inputs.as_core_arguments(),
31
31
  **optional_network_inputs.as_core_arguments(),
32
32
  **optional_training_inputs.as_core_arguments(),
33
33
  **misc_training_inputs.as_core_arguments(),
34
34
  )
35
- print("Finished!")
35
+ show_info("Training finished!")
36
36
 
37
37
 
38
38
  def training_widget() -> FunctionGui:
@@ -60,7 +60,6 @@ def training_widget() -> FunctionGui:
60
60
  continue_training: bool,
61
61
  augment: bool,
62
62
  tensorboard: bool,
63
- save_weights: bool,
64
63
  save_checkpoints: bool,
65
64
  save_progress: bool,
66
65
  epochs: int,
@@ -96,9 +95,6 @@ def training_widget() -> FunctionGui:
96
95
  Augment the training data to improve generalisation
97
96
  tensorboard : bool
98
97
  Log to output_directory/tensorboard
99
- save_weights : bool
100
- Only store the model weights, and not the full model
101
- Useful to save storage space
102
98
  save_checkpoints : bool
103
99
  Store the model at intermediate points during training
104
100
  save_progress : bool
@@ -133,7 +129,6 @@ def training_widget() -> FunctionGui:
133
129
  continue_training,
134
130
  augment,
135
131
  tensorboard,
136
- save_weights,
137
132
  save_checkpoints,
138
133
  save_progress,
139
134
  epochs,
@@ -147,6 +142,7 @@ def training_widget() -> FunctionGui:
147
142
  if yaml_files[0] == Path.home(): # type: ignore
148
143
  show_info("Please select a YAML file for training")
149
144
  else:
145
+ show_info("Starting training process...")
150
146
  worker = run_training(
151
147
  training_data_inputs,
152
148
  optional_network_inputs,
@@ -5,7 +5,7 @@ from typing import Optional
5
5
  from magicgui.types import FileDialogMode
6
6
 
7
7
  from cellfinder.core.download.download import model_filenames
8
- from cellfinder.core.train.train_yml import models
8
+ from cellfinder.core.train.train_yaml import models
9
9
  from cellfinder.napari.input_container import InputContainer
10
10
  from cellfinder.napari.utils import html_label_widget
11
11
 
@@ -31,7 +31,7 @@ class TrainingDataInputs(InputContainer):
31
31
  "yaml_files",
32
32
  custom_label="YAML files",
33
33
  mode=FileDialogMode.EXISTING_FILES,
34
- filter="*.yml",
34
+ filter="*.yaml",
35
35
  ),
36
36
  output_directory=cls._custom_widget(
37
37
  "output_directory", mode=FileDialogMode.EXISTING_DIRECTORY
@@ -75,7 +75,6 @@ class OptionalTrainingInputs(InputContainer):
75
75
  continue_training: bool = False
76
76
  augment: bool = True
77
77
  tensorboard: bool = False
78
- save_weights: bool = False
79
78
  save_checkpoints: bool = True
80
79
  save_progress: bool = True
81
80
  epochs: int = 100
@@ -98,7 +97,6 @@ class OptionalTrainingInputs(InputContainer):
98
97
  continue_training=cls._custom_widget("continue_training"),
99
98
  augment=cls._custom_widget("augment"),
100
99
  tensorboard=cls._custom_widget("tensorboard"),
101
- save_weights=cls._custom_widget("save_weights"),
102
100
  save_checkpoints=cls._custom_widget("save_checkpoints"),
103
101
  save_progress=cls._custom_widget("save_progress"),
104
102
  epochs=cls._custom_widget("epochs"),
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: cellfinder
3
- Version: 1.5.1
3
+ Version: 1.7.0
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
@@ -33,7 +33,7 @@ Requires-Dist: numpy
33
33
  Requires-Dist: scikit-image
34
34
  Requires-Dist: scikit-learn
35
35
  Requires-Dist: keras>=3.7.0
36
- Requires-Dist: torch!=2.4,>=2.1.0
36
+ Requires-Dist: torch>=2.4.1
37
37
  Requires-Dist: tifffile
38
38
  Requires-Dist: tqdm
39
39
  Requires-Dist: qt-niu
@@ -56,6 +56,7 @@ Requires-Dist: napari-plugin-engine>=0.1.4; extra == "napari"
56
56
  Requires-Dist: napari[pyqt5]; extra == "napari"
57
57
  Requires-Dist: pooch>=1; extra == "napari"
58
58
  Requires-Dist: qtpy; extra == "napari"
59
+ Dynamic: license-file
59
60
 
60
61
  [![Python Version](https://img.shields.io/pypi/pyversions/cellfinder.svg)](https://pypi.org/project/cellfinder)
61
62
  [![PyPI](https://img.shields.io/pypi/v/cellfinder.svg)](https://pypi.org/project/cellfinder)
@@ -1,18 +1,18 @@
1
1
  cellfinder/__init__.py,sha256=S5oQ3EORuyQTMYC4uUuzGKZ23J3Ya6q-1DOBib1KfiA,1166
2
- cellfinder/cli_migration_warning.py,sha256=gPtNrtnXvWpl5q0k_EGAQZg0DwcpCmuBTgpg56n5NfA,1578
2
+ cellfinder/cli_migration_warning.py,sha256=u4nKQiPYmpx0HRqm0PI8wBx78rNiiBSQSGciDoXEq78,1623
3
3
  cellfinder/core/__init__.py,sha256=pRFuQsl78HEK0S6gvhJw70QLbjjSBzP-GFO0AtVaGtk,62
4
- cellfinder/core/main.py,sha256=QiLo8qtK6hRT_cu-xSP9k93EE-dZjmb2xxocsY-hTwU,3836
4
+ cellfinder/core/main.py,sha256=ZAkouPqPkg1KgR3k94E4IaxjwTKNmSg-SLsPTDpKr5c,3816
5
5
  cellfinder/core/types.py,sha256=lTqWE4v0SMM0qLAZJdyAzqV1nLgDtobEpglNJcXt160,106
6
6
  cellfinder/core/classify/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  cellfinder/core/classify/augment.py,sha256=8dMbM7KhimM6NMgdMC53oHoCfYj1CIB-h3Yk8CZAxPw,6321
8
- cellfinder/core/classify/classify.py,sha256=p3TvpnTVCVa9xCSgHm7QsgHeYeNZaoSbvf9fgZ3uF0c,3560
8
+ cellfinder/core/classify/classify.py,sha256=WudUeF-cWpJ7FxnjPsaSVC8HL2aPMgPfT9RJ7hZM3xE,3576
9
9
  cellfinder/core/classify/cube_generator.py,sha256=jC5aogTVy213PHouViSR9CgKkuOks3yk6csQC5kRoOE,17125
10
10
  cellfinder/core/classify/resnet.py,sha256=vGa85y_NcQnOXwAt5EtatLx5mrO8IoShCcNKtJ5-EFg,10034
11
- cellfinder/core/classify/tools.py,sha256=s5PEKAsZVbVuoferZ_nqMUM0f2bV_8WEKsdKe3SXEuE,2560
11
+ cellfinder/core/classify/tools.py,sha256=gdWE8cBMlT1pqxBKt6j2az7i7FOMR4N0ds4w9YnBvtQ,2924
12
12
  cellfinder/core/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  cellfinder/core/config/cellfinder.conf,sha256=5i8axif7ekMutKDiVnZRs-LiJrgVQljg_beltidqtNk,56
14
14
  cellfinder/core/detect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- cellfinder/core/detect/detect.py,sha256=cd6D3XOzP5HEA_Hb3Ik4AVmNzu0im4sQxV46cCY6izU,8056
15
+ cellfinder/core/detect/detect.py,sha256=oFLu69VtjMUGLFXFeZTx1QRcTQc5uhEvLCS5Z6LNFB8,8307
16
16
  cellfinder/core/detect/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  cellfinder/core/detect/filters/setup_filters.py,sha256=gvWhdGVdGrK_Ab-t0kKPnXaf43qLi78ed_-vNPI0nE4,14554
18
18
  cellfinder/core/detect/filters/plane/__init__.py,sha256=lybcPbVDnurEQeq2FiLq0zR8p_ztarQOlajhdh1Q2-4,40
@@ -26,7 +26,7 @@ cellfinder/core/detect/filters/volume/structure_splitting.py,sha256=0LGE8cQ6EJIs
26
26
  cellfinder/core/detect/filters/volume/volume_filter.py,sha256=o9_4IsITedhqkhfwRsIhE53_zLNcFjgQzXbMMddH_q4,20544
27
27
  cellfinder/core/download/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  cellfinder/core/download/cli.py,sha256=X9L9ZIkWqs58hX8G8q_0AKN4gk8BhydGxI9nLpdHQQE,1764
29
- cellfinder/core/download/download.py,sha256=YQP4NMM9Xt0rECRJEV5z6RCZNi5uCFhohFnDreH0qHA,3277
29
+ cellfinder/core/download/download.py,sha256=bmPwOm48ApylydasJ8ZvuoQgSSlsb8k4_DL1ikNZrIY,3318
30
30
  cellfinder/core/tools/IO.py,sha256=jK1R_6YahQ_MbPlwg1IM-Fp-din-hLBNq71Jxn3q2WQ,1356
31
31
  cellfinder/core/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  cellfinder/core/tools/array_operations.py,sha256=LDbqWA_N2YtxeKS877QYdJRL2FCMC1R1ExJtdb6-vEA,3371
@@ -35,27 +35,27 @@ cellfinder/core/tools/image_processing.py,sha256=z27bGjf3Iv3G4Nt1OYzpEnIYQNc4nNo
35
35
  cellfinder/core/tools/prep.py,sha256=YU4VDyjEsOXn3S3gymEfPUzka-WYiHmR4Q4XdRebhDI,2175
36
36
  cellfinder/core/tools/source_files.py,sha256=vvwsIMe1ULKvXg_x22L75iqvCyMjEbUjJsDFQk3GYzY,856
37
37
  cellfinder/core/tools/system.py,sha256=WvEzPr7v-ohLDnzf4n13TMcN5OYIAXOEkaSmrHzdnwc,2438
38
- cellfinder/core/tools/threading.py,sha256=EmDLF22ZvXJnsWg7g6sv4cZgNweC0YrVw2o7QXjrO9s,14094
38
+ cellfinder/core/tools/threading.py,sha256=mc-XVEfLHj3AFWYcK1Qh4TKmVuW4mNaxgLBlQmBVViU,14154
39
39
  cellfinder/core/tools/tiff.py,sha256=NzIz6wq2GzxmcIhawFMwZADe-uQO2rIG46H7xkpGKLs,2899
40
40
  cellfinder/core/tools/tools.py,sha256=opMGC5GBBsId0dmL8V0KQrI4U70w_D_KtGQYpZNeHYQ,9390
41
41
  cellfinder/core/train/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
- cellfinder/core/train/train_yml.py,sha256=9QXv2wk24G8hYskMnBij7OngEELUWySK2fH4NFbYWw4,13260
42
+ cellfinder/core/train/train_yaml.py,sha256=tG5FXHZj26PqPUaZCVmFgnvACvIh23mCwEDXwoXv2Hc,13104
43
43
  cellfinder/napari/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- cellfinder/napari/curation.py,sha256=Egp56_ke1x1s1ZO9FK8oWgxG-xerBYWG76_V56JJ3eQ,21425
45
- cellfinder/napari/input_container.py,sha256=tkm0dkPt7kSL8Xkvs1fh8M6vKWw57QLIt_wv74HFkGk,2150
44
+ cellfinder/napari/curation.py,sha256=2TmpK80NMNITVz8usT6-MV9m-_bt_-zBh8V3HLv4Xj8,22175
45
+ cellfinder/napari/input_container.py,sha256=upTkufWF3aOr9sPPK13C2YwqQ6tygULym8oDXrRLXJs,2510
46
46
  cellfinder/napari/napari.yaml,sha256=WMR1CIAmYIVyQngbdbomTRZLvlDbb6LxsXsvTRClQnE,921
47
47
  cellfinder/napari/sample_data.py,sha256=oUST23q09MM8dxHbUCmO0AjtXG6OlR_32LLqP0EU2UA,732
48
48
  cellfinder/napari/utils.py,sha256=AwTs76M9azutHhHj2yuaKErDEQ5F6pFbIIakBfzen6M,3824
49
49
  cellfinder/napari/detect/__init__.py,sha256=BD9Bg9NTAr6yRTq2A_p58U6j4w5wbY0sdXwhPJ3MSMY,34
50
- cellfinder/napari/detect/detect.py,sha256=EC71KN0AEr49hMjvS8yzvGvfRctqKqn_lNERyx9UAPc,13810
51
- cellfinder/napari/detect/detect_containers.py,sha256=j9NTsIyyDNrhlI2dc7hvc7QlxvI1NRHlCe137v7fsPg,5467
50
+ cellfinder/napari/detect/detect.py,sha256=LBgbJ_OKOrXmXvRCIYyr8a4NgBioPVz-ZCqxHiFCw1A,13945
51
+ cellfinder/napari/detect/detect_containers.py,sha256=WQ34EjXaOS91NeWMOP6oWnTSrU4KMZPxxrhvnfXmK0I,5895
52
52
  cellfinder/napari/detect/thread_worker.py,sha256=PWM3OE-FpK-dpdhaE_Gi-2lD3u8sL-SJ13mp0pMhTyI,3078
53
53
  cellfinder/napari/train/__init__.py,sha256=xo4CK-DvSecInGEc2ohcTgQYlH3iylFnGvKTCoq2WkI,35
54
- cellfinder/napari/train/train.py,sha256=zJY7zKcLqDTDtD76thmbwViEU4tTFCmXZze-zHsTpoo,5941
55
- cellfinder/napari/train/train_containers.py,sha256=1wZ_GPe7B5XsLYs5XIx4m8GMw5KeVhg6SchhPtXu4V8,4386
56
- cellfinder-1.5.1.dist-info/LICENSE,sha256=Tw8iMytIDXLSmcIUsbQmRWojstl9yOWsPCx6ZT6dZLY,1564
57
- cellfinder-1.5.1.dist-info/METADATA,sha256=57JEunyuzIH3y7gp6ygxbSiNhyeT8i8MMo76ofwmvZw,7142
58
- cellfinder-1.5.1.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
59
- cellfinder-1.5.1.dist-info/entry_points.txt,sha256=cKKjU8GPiN-TRelG2sT2JCKAcB9XDCjP6g9atE9pSoY,247
60
- cellfinder-1.5.1.dist-info/top_level.txt,sha256=jyTQzX-tDjbsMr6s-E71Oy0IKQzmHTXSk4ZhpG5EDSE,11
61
- cellfinder-1.5.1.dist-info/RECORD,,
54
+ cellfinder/napari/train/train.py,sha256=tXrB8j_c293mzhWX5iEs4FvIwV1FpZuaX1rsSP4dgDQ,5830
55
+ cellfinder/napari/train/train_containers.py,sha256=ovPl4ZiH6DUr-CGIYu-iju05z3_rtomyYnCWI6fURKc,4296
56
+ cellfinder-1.7.0.dist-info/licenses/LICENSE,sha256=Tw8iMytIDXLSmcIUsbQmRWojstl9yOWsPCx6ZT6dZLY,1564
57
+ cellfinder-1.7.0.dist-info/METADATA,sha256=l2M8eBQv8-A7BX77cT9BAapFgvV78p0yV4Gjb3kFl4k,7158
58
+ cellfinder-1.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
59
+ cellfinder-1.7.0.dist-info/entry_points.txt,sha256=n2n3muDgifENJtTRz1JqYStxvuprROCwmKLt-VxvEHk,248
60
+ cellfinder-1.7.0.dist-info/top_level.txt,sha256=jyTQzX-tDjbsMr6s-E71Oy0IKQzmHTXSk4ZhpG5EDSE,11
61
+ cellfinder-1.7.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,7 +1,7 @@
1
1
  [console_scripts]
2
2
  cellfinder = cellfinder.cli_migration_warning:cli_catch
3
3
  cellfinder_download = cellfinder.core.download.cli:main
4
- cellfinder_train = cellfinder.core.train.train_yml:cli
4
+ cellfinder_train = cellfinder.core.train.train_yaml:cli
5
5
 
6
6
  [napari.manifest]
7
7
  cellfinder = cellfinder.napari:napari.yaml