celldetective 1.5.0b0__py3-none-any.whl → 1.5.0b1__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.
celldetective/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.5.0b"
1
+ __version__ = "1.5.0b1"
@@ -256,7 +256,7 @@ class AppInitWindow(CelldetectiveMainWindow):
256
256
  DownloadProcess = self.bg_loader.DownloadProcess
257
257
  else:
258
258
  from celldetective.processes.downloader import DownloadProcess
259
- from celldetective.gui.workers import ProgressWindow
259
+ from celldetective.gui.workers import GenericProgressWindow
260
260
 
261
261
  self.target_dir = str(
262
262
  QFileDialog.getExistingDirectory(self, "Select Folder for Download")
@@ -268,12 +268,12 @@ class AppInitWindow(CelldetectiveMainWindow):
268
268
  self.output_dir = self.target_dir
269
269
  self.file = "demo_ricm"
270
270
  process_args = {"output_dir": self.output_dir, "file": self.file}
271
- self.job = ProgressWindow(
271
+ self.job = GenericProgressWindow(
272
272
  DownloadProcess,
273
273
  parent_window=self,
274
274
  title="Download",
275
- position_info=False,
276
275
  process_args=process_args,
276
+ label_text="Downloading demo_ricm...",
277
277
  )
278
278
  result = self.job.exec_()
279
279
  if result == QDialog.Accepted:
@@ -316,3 +316,102 @@ class RunnerSignal(QObject):
316
316
 
317
317
  finished = pyqtSignal()
318
318
  error = pyqtSignal(str)
319
+
320
+
321
+ class GenericProgressWindow(CelldetectiveDialog):
322
+
323
+ def __init__(
324
+ self,
325
+ process=None,
326
+ parent_window=None,
327
+ title="",
328
+ process_args=None,
329
+ label_text="Progress:",
330
+ ):
331
+
332
+ super().__init__()
333
+
334
+ self.setWindowTitle(f"{title}")
335
+ self.__process = process
336
+ self.parent_window = parent_window
337
+
338
+ self.__btn_stp = QPushButton("Cancel")
339
+ self.__label = QLabel("Idle")
340
+ self.progress_label = QLabel(label_text)
341
+
342
+ self.progress_bar = QProgressBar()
343
+ self.progress_bar.setValue(0)
344
+ self.progress_bar.setFormat("%p%")
345
+
346
+ self.__runner = Runner(
347
+ process=self.__process,
348
+ process_args=process_args,
349
+ )
350
+ logger.info("Runner initialized...")
351
+ self.pool = QThreadPool.globalInstance()
352
+
353
+ self.__btn_stp.clicked.connect(self.__stp_net)
354
+ self.__runner.signals.finished.connect(self.__on_finished)
355
+ self.__runner.signals.error.connect(self.__on_error)
356
+ self.__runner.signals.update_status.connect(self.__label.setText)
357
+
358
+ # Connect update_pos for generic progress (Runner maps generic list progress to update_pos)
359
+ self.__runner.signals.update_pos.connect(self.progress_bar.setValue)
360
+
361
+ self.__btn_stp.setDisabled(True)
362
+
363
+ self.layout = QVBoxLayout()
364
+ self.layout.addWidget(self.progress_label)
365
+ self.layout.addWidget(self.progress_bar)
366
+
367
+ self.btn_layout = QHBoxLayout()
368
+ self.btn_layout.addWidget(self.__btn_stp)
369
+ self.btn_layout.addWidget(self.__label)
370
+
371
+ self.layout.addLayout(self.btn_layout)
372
+
373
+ self.setLayout(self.layout)
374
+ self.setFixedSize(QSize(400, 150))
375
+ self.show()
376
+ self.raise_()
377
+ self.activateWindow()
378
+ logger.info("GenericProgressWindow initialized and shown.")
379
+ self.__run_net()
380
+ self.setModal(True)
381
+
382
+ def closeEvent(self, evnt):
383
+ evnt.ignore()
384
+ self.setWindowState(Qt.WindowMinimized)
385
+
386
+ def __run_net(self):
387
+ self.__btn_stp.setEnabled(True)
388
+ self.__label.setText("Running...")
389
+ self.pool.start(self.__runner)
390
+
391
+ def __stp_net(self):
392
+ self.__runner.close()
393
+ logger.info("\n Job cancelled... Abort.")
394
+ self.reject()
395
+
396
+ def __on_finished(self):
397
+ self.__btn_stp.setDisabled(True)
398
+ self.__label.setText("\nFinished!")
399
+ self.__runner.close()
400
+ self.accept()
401
+
402
+ def __on_error(self, message="Error"):
403
+ self.__btn_stp.setDisabled(True)
404
+ self.__label.setText("\nError")
405
+ self.__runner.close()
406
+
407
+ # Show error in a message box to ensure it's seen
408
+ from PyQt5.QtWidgets import QMessageBox
409
+
410
+ msg = QMessageBox()
411
+ msg.setIcon(QMessageBox.Critical)
412
+ msg.setText("Process failed")
413
+ msg.setInformativeText(str(message))
414
+ msg.setWindowTitle("Error")
415
+ msg.exec_()
416
+
417
+ self.reject()
@@ -11,101 +11,127 @@ import time
11
11
  from pathlib import Path
12
12
  import json
13
13
 
14
+
14
15
  class DownloadProcess(Process):
15
16
 
16
- def __init__(self, queue=None, process_args=None, *args, **kwargs):
17
-
18
- super().__init__(*args, **kwargs)
19
-
20
- if process_args is not None:
21
- for key, value in process_args.items():
22
- setattr(self, key, value)
23
-
24
- self.queue = queue
25
- self.progress = True
26
-
27
- file_path = Path(os.path.dirname(os.path.realpath(__file__)))
28
- zenodo_json = os.sep.join([str(file_path.parents[2]),"celldetective", "links", "zenodo.json"])
29
- print(f"{zenodo_json=}")
30
-
31
- with open(zenodo_json,"r") as f:
32
- zenodo_json = json.load(f)
33
- all_files = list(zenodo_json['files']['entries'].keys())
34
- all_files_short = [f.replace(".zip","") for f in all_files]
35
- zenodo_url = zenodo_json['links']['files'].replace('api/','')
36
- full_links = ["/".join([zenodo_url, f]) for f in all_files]
37
- index = all_files_short.index(self.file)
38
-
39
- self.zip_url = full_links[index]
40
- self.path_to_zip_file = os.sep.join([self.output_dir, 'temp.zip'])
41
-
42
- self.sum_done = 0
43
- self.t0 = time.time()
44
-
45
- def download_url_to_file(self, url, dst):
46
- try:
47
- file_size = None
48
- ssl._create_default_https_context = ssl._create_unverified_context
49
- u = urlopen(url)
50
- meta = u.info()
51
- if hasattr(meta, 'getheaders'):
52
- content_length = meta.getheaders("Content-Length")
53
- else:
54
- content_length = meta.get_all("Content-Length")
55
- if content_length is not None and len(content_length) > 0:
56
- file_size = int(content_length[0])
57
- # We deliberately save it in a temp file and move it after
58
- dst = os.path.expanduser(dst)
59
- dst_dir = os.path.dirname(dst)
60
- f = tempfile.NamedTemporaryFile(delete=False, dir=dst_dir)
61
-
62
- try:
63
- with tqdm(total=file_size, disable=not self.progress,
64
- unit='B', unit_scale=True, unit_divisor=1024) as pbar:
65
- while True:
66
- buffer = u.read(8192) #8192
67
- if len(buffer) == 0:
68
- break
69
- f.write(buffer)
70
- pbar.update(len(buffer))
71
- self.sum_done+=len(buffer) / file_size * 100
72
- mean_exec_per_step = (time.time() - self.t0) / (self.sum_done*file_size / 100 + 1)
73
- pred_time = (file_size - (self.sum_done*file_size / 100 + 1)) * mean_exec_per_step
74
- self.queue.put([self.sum_done, pred_time])
75
- f.close()
76
- shutil.move(f.name, dst)
77
- finally:
78
- f.close()
79
- if os.path.exists(f.name):
80
- os.remove(f.name)
81
- except Exception as e:
82
- print("No internet connection: ", e)
83
- return None
84
-
85
- def run(self):
86
-
87
- self.download_url_to_file(fr"{self.zip_url}",self.path_to_zip_file)
88
- with zipfile.ZipFile(self.path_to_zip_file, 'r') as zip_ref:
89
- zip_ref.extractall(self.output_dir)
90
-
91
- file_to_rename = glob(os.sep.join([self.output_dir,self.file,"*[!.json][!.png][!.h5][!.csv][!.npy][!.tif][!.ini]"]))
92
- if len(file_to_rename)>0 and not file_to_rename[0].endswith(os.sep) and not self.file.startswith('demo'):
93
- os.rename(file_to_rename[0], os.sep.join([self.output_dir,self.file,self.file]))
94
-
95
- os.remove(self.path_to_zip_file)
96
- self.queue.put([100,0])
97
- time.sleep(0.5)
98
-
99
- # Send end signal
100
- self.queue.put("finished")
101
- self.queue.close()
102
-
103
- def end_process(self):
104
-
105
- self.terminate()
106
- self.queue.put("finished")
107
-
108
- def abort_process(self):
109
-
110
- self.terminate()
111
- self.queue.put("error")
17
+ def __init__(self, queue=None, process_args=None, *args, **kwargs):
18
+
19
+ super().__init__(*args, **kwargs)
20
+
21
+ if process_args is not None:
22
+ for key, value in process_args.items():
23
+ setattr(self, key, value)
24
+
25
+ self.queue = queue
26
+ self.progress = True
27
+
28
+ # Get celldetective package root
29
+ current_dir = os.path.dirname(os.path.realpath(__file__))
30
+ package_root = os.path.dirname(current_dir)
31
+ zenodo_json = os.path.join(package_root, "links", "zenodo.json")
32
+ # print(f"{zenodo_json=}")
33
+
34
+ with open(zenodo_json, "r") as f:
35
+ zenodo_json = json.load(f)
36
+ all_files = list(zenodo_json["files"]["entries"].keys())
37
+ all_files_short = [f.replace(".zip", "") for f in all_files]
38
+ zenodo_url = zenodo_json["links"]["files"].replace("api/", "")
39
+ full_links = ["/".join([zenodo_url, f]) for f in all_files]
40
+ index = all_files_short.index(self.file)
41
+
42
+ self.zip_url = full_links[index]
43
+ self.path_to_zip_file = os.sep.join([self.output_dir, "temp.zip"])
44
+
45
+ self.sum_done = 0
46
+ self.t0 = time.time()
47
+
48
+ def download_url_to_file(self, url, dst):
49
+ try:
50
+ file_size = None
51
+ ssl._create_default_https_context = ssl._create_unverified_context
52
+ u = urlopen(url)
53
+ meta = u.info()
54
+ if hasattr(meta, "getheaders"):
55
+ content_length = meta.getheaders("Content-Length")
56
+ else:
57
+ content_length = meta.get_all("Content-Length")
58
+ if content_length is not None and len(content_length) > 0:
59
+ file_size = int(content_length[0])
60
+ # We deliberately save it in a temp file and move it after
61
+ dst = os.path.expanduser(dst)
62
+ dst_dir = os.path.dirname(dst)
63
+ f = tempfile.NamedTemporaryFile(delete=False, dir=dst_dir)
64
+
65
+ try:
66
+ with tqdm(
67
+ total=file_size,
68
+ disable=not self.progress,
69
+ unit="B",
70
+ unit_scale=True,
71
+ unit_divisor=1024,
72
+ ) as pbar:
73
+ while True:
74
+ buffer = u.read(8192) # 8192
75
+ if len(buffer) == 0:
76
+ break
77
+ f.write(buffer)
78
+ pbar.update(len(buffer))
79
+ self.sum_done += len(buffer) / file_size * 100
80
+ mean_exec_per_step = (time.time() - self.t0) / (
81
+ self.sum_done * file_size / 100 + 1
82
+ )
83
+ pred_time = (
84
+ file_size - (self.sum_done * file_size / 100 + 1)
85
+ ) * mean_exec_per_step
86
+ self.queue.put([self.sum_done, pred_time])
87
+ f.close()
88
+ shutil.move(f.name, dst)
89
+ finally:
90
+ f.close()
91
+ if os.path.exists(f.name):
92
+ os.remove(f.name)
93
+ except Exception as e:
94
+ print("No internet connection: ", e)
95
+ return None
96
+
97
+ def run(self):
98
+
99
+ self.download_url_to_file(rf"{self.zip_url}", self.path_to_zip_file)
100
+ with zipfile.ZipFile(self.path_to_zip_file, "r") as zip_ref:
101
+ zip_ref.extractall(self.output_dir)
102
+
103
+ file_to_rename = glob(
104
+ os.sep.join(
105
+ [
106
+ self.output_dir,
107
+ self.file,
108
+ "*[!.json][!.png][!.h5][!.csv][!.npy][!.tif][!.ini]",
109
+ ]
110
+ )
111
+ )
112
+ if (
113
+ len(file_to_rename) > 0
114
+ and not file_to_rename[0].endswith(os.sep)
115
+ and not self.file.startswith("demo")
116
+ ):
117
+ os.rename(
118
+ file_to_rename[0], os.sep.join([self.output_dir, self.file, self.file])
119
+ )
120
+
121
+ os.remove(self.path_to_zip_file)
122
+ self.queue.put([100, 0])
123
+ time.sleep(0.5)
124
+
125
+ # Send end signal
126
+ self.queue.put("finished")
127
+ self.queue.close()
128
+
129
+ def end_process(self):
130
+
131
+ self.terminate()
132
+ self.queue.put("finished")
133
+
134
+ def abort_process(self):
135
+
136
+ self.terminate()
137
+ self.queue.put("error")
@@ -159,6 +159,44 @@ def download_url_to_file(url, dst, progress=True):
159
159
  def download_zenodo_file(file, output_dir):
160
160
 
161
161
  logger.info(f"{file=} {output_dir=}")
162
+
163
+ # GUI Check
164
+ try:
165
+ from PyQt5.QtWidgets import QApplication, QDialog
166
+
167
+ app = QApplication.instance()
168
+ use_gui = app is not None
169
+ except ImportError:
170
+ use_gui = False
171
+
172
+ if use_gui:
173
+ try:
174
+ from celldetective.gui.workers import GenericProgressWindow
175
+ from celldetective.processes.downloader import DownloadProcess
176
+
177
+ # Find parent window if possible, else None is fine for a dialog
178
+ parent = app.activeWindow()
179
+
180
+ process_args = {"output_dir": output_dir, "file": file}
181
+ job = GenericProgressWindow(
182
+ DownloadProcess,
183
+ parent_window=parent,
184
+ title="Download",
185
+ process_args=process_args,
186
+ label_text=f"Downloading {file}...",
187
+ )
188
+ result = job.exec_()
189
+ if result == QDialog.Accepted:
190
+ return # DownloadProcess handles the file operations
191
+ else:
192
+ logger.info("Download cancelled or failed.")
193
+ return
194
+
195
+ except Exception as e:
196
+ logger.error(f"Failed to use GUI downloader: {e}. Falling back to console.")
197
+ # Fallback to console implementation below if GUI fails
198
+
199
+ # Console Implementation
162
200
  zenodo_json = os.sep.join(
163
201
  [
164
202
  os.path.split(os.path.dirname(os.path.realpath(__file__)))[0],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: celldetective
3
- Version: 1.5.0b0
3
+ Version: 1.5.0b1
4
4
  Summary: description
5
5
  Home-page: http://github.com/remyeltorro/celldetective
6
6
  Author: Rémy Torro
@@ -1,6 +1,6 @@
1
1
  celldetective/__init__.py,sha256=LfnOyfUnYPGDc8xcsF_PfYEL7-CqAb7BMBPBIWGv84o,666
2
2
  celldetective/__main__.py,sha256=Rzzu9ArxZSgfBVjV-lyn-3oanQB2MumQR6itK5ZaRpA,2597
3
- celldetective/_version.py,sha256=AMZ674Vi7YVfxguQYyBETUqhTbHYuk3GDM_LK-X1UBg,23
3
+ celldetective/_version.py,sha256=6QH0Vgfkt-TPgdS6Nql1G9jeZAByFTkMEeYsa6NspPk,24
4
4
  celldetective/events.py,sha256=n15R53c7QZ2wT8gjb0oeNikQbuRBrVVbyNsRCqXjzXA,8166
5
5
  celldetective/exceptions.py,sha256=f3VmIYOthWTiqMEV5xQCox2rw5c5e7yog88h-CcV4oI,356
6
6
  celldetective/extra_properties.py,sha256=s_2R4_El2p-gQNZ_EpgDxgrN3UnRitN7KDKHhyLuoHc,21681
@@ -15,7 +15,7 @@ celldetective/signals.py,sha256=2UURVmeonNgUHpiMQVSps0E9VuskKSbsfsmeCtEmfp8,1374
15
15
  celldetective/tracking.py,sha256=pjejp65IltUMjW_tlbxjYW0SoBR1-gaEeSJa0y2cWpw,49286
16
16
  celldetective/datasets/segmentation_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  celldetective/datasets/signal_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- celldetective/gui/InitWindow.py,sha256=ynelHEkC9USY14MrsHr_HKtC6YPWQOahk3sv-ZcaKFc,20921
18
+ celldetective/gui/InitWindow.py,sha256=fNuY7d8EtNNOB2_ZrijyNdoQ7x5GOlq1IFqPBUv1ElM,20953
19
19
  celldetective/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  celldetective/gui/about.py,sha256=l9SA7WnQs3ISPvZYAGMmf1A0GRXcinkyGwWJpG8akFQ,1977
21
21
  celldetective/gui/analyze_block.py,sha256=R82PVFHXfKn8BvUCpbjDOkLBNF4xRVCzYKFHitjw0kk,4114
@@ -39,7 +39,7 @@ celldetective/gui/seg_model_loader.py,sha256=6DzpX630JJgtcsaDEuWA8PEkeb8FC3p__3x
39
39
  celldetective/gui/survival_ui.py,sha256=IwdRm1gRvhkWdMtrQk04OIKKksW3NZSGYtZO_2GptrA,16034
40
40
  celldetective/gui/tableUI.py,sha256=kZP2lp9NwHtbWEqIyaDwohX42tRkhI0Hlf_8O5w5BD0,61267
41
41
  celldetective/gui/thresholds_gui.py,sha256=w6ke2TyIEi71LxbuFGz0UrwH8h21N_ESU-o6xq_NNKo,33346
42
- celldetective/gui/workers.py,sha256=0U-wn_dmZjB2idGjpM8s_1dLET9Eh2TmVWB6PLJTSas,11411
42
+ celldetective/gui/workers.py,sha256=6uk4skcwNd3qowBrpSSgv0hvbL-4naH-g-TmF3u7NB4,14363
43
43
  celldetective/gui/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
44
  celldetective/gui/base/channel_norm_generator.py,sha256=JqNAo87zA3nMKzkGjvoeV-SHI89eIATwQj4jHv3-LpI,13973
45
45
  celldetective/gui/base/components.py,sha256=DF1sT2AZIpTec7mYYihIMTDYKRrT5k2DoaceZjvAEEw,7452
@@ -118,7 +118,7 @@ celldetective/processes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
118
118
  celldetective/processes/background_correction.py,sha256=fyv2_7ztUex7RDwIRaURweYZsRe-YD_ZPUHeiFmVq6Q,10715
119
119
  celldetective/processes/compute_neighborhood.py,sha256=DGi4U3el0OisRNaOQSzUaXpEgHBO440-Q4cUphB6FAA,34393
120
120
  celldetective/processes/detect_events.py,sha256=4psWjnYxbMB3p0BrRoQgkXgIdsnUIErrqUkE9CU4hRM,9733
121
- celldetective/processes/downloader.py,sha256=jnNitmQ9xUCGJHSvr3Myts5soe6rdYDBx_AGJKr1AWk,3406
121
+ celldetective/processes/downloader.py,sha256=3SA5T1AoLch90d-VZzIY4wVAlSjDY_kgVLPN3ztRyVk,4589
122
122
  celldetective/processes/measure_cells.py,sha256=ccf2j7_6dcRevEhseVXioIjiATx8IvIsi5ZG3IcdhJY,20876
123
123
  celldetective/processes/segment_cells.py,sha256=klGl5y3tHbLbQFNAQz0PV1FspmiPC-GHVGWYLgyLqwc,26500
124
124
  celldetective/processes/track_cells.py,sha256=cgQNn7fsqPCHODhe27sqvMUlubsi7qM_0qjAXbj68oY,15084
@@ -141,7 +141,7 @@ celldetective/utils/color_mappings.py,sha256=yarqOTSrTsnOPPiPrrN_vLoPCbgWqF3wjqF
141
141
  celldetective/utils/data_cleaning.py,sha256=K-2gScxLreX7QkrM0h3dZdP0IsmvCzcxNh2-M9PALZY,22025
142
142
  celldetective/utils/data_loaders.py,sha256=tExtC_7gX16VYmYFz8BU7jRKLDug2egVghU1YIcGRh0,16292
143
143
  celldetective/utils/dataset_helpers.py,sha256=3ezpHO6nytw2Mx0D3maP_4535V2ohOTQn6Qpfk8gnms,6898
144
- celldetective/utils/downloaders.py,sha256=Cf7K-f_Bm4M6HIfgiSoIoph0O1NS6LZIaYvgWKauXes,6595
144
+ celldetective/utils/downloaders.py,sha256=BIl_8XCeaKvtMVC36WITT2g5-O-n0csoMEQXVoa1B4o,7887
145
145
  celldetective/utils/experiment.py,sha256=bgADS70QuW4KGbzDJbVpVM-tw4qmZKMWtDT1cSxugrY,58342
146
146
  celldetective/utils/image_augmenters.py,sha256=USYd8z6dVn5z1x96IYJ4mG0smN9I_S21QMGU0wyHmjc,11654
147
147
  celldetective/utils/image_cleaning.py,sha256=KliQ3K5hdwPx4eFxJnmg3yi-ZIoimEveunPJkbbA6wA,2388
@@ -164,7 +164,7 @@ celldetective/utils/event_detection/__init__.py,sha256=KX20PwPTevdbZ-25otDy_QTme
164
164
  celldetective/utils/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
165
165
  celldetective/utils/plots/regression.py,sha256=oUCn29-hp7PxMqC-R0yoL60KMw5ZWpZAIoCDh2ErlcY,1764
166
166
  celldetective/utils/stardist_utils/__init__.py,sha256=e9s3DEaTKCUOGZb5k_DgShBTl4B0U-Jmg3Ioo8D5PyE,3978
167
- celldetective-1.5.0b0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
167
+ celldetective-1.5.0b1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
168
168
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
169
169
  tests/test_events.py,sha256=eLFwwEEJfQAdwhews3-fn1HSvzozcNNFN_Qn0gOvQkE,685
170
170
  tests/test_filters.py,sha256=uj4NVyUnKXa18EpTSiWCetGKI1VFopDyNSJSUxX44wA,1689
@@ -180,8 +180,8 @@ tests/test_utils.py,sha256=aSB_eMw9fzTsnxxdYoNmdQQRrXkWqBXB7Uv4TGU6kYE,4778
180
180
  tests/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
181
181
  tests/gui/test_new_project.py,sha256=wRjW2vEaZb0LWT-f8G8-Ptk8CW9z8-FDPLpV5uqj6ck,8778
182
182
  tests/gui/test_project.py,sha256=KzAnodIc0Ovta0ARL5Kr5PkOR5euA6qczT_GhEZpyE4,4710
183
- celldetective-1.5.0b0.dist-info/METADATA,sha256=btAint9Y6sB0i_XItoVQqUHMsn1KtXNm0JSeavdXH48,10947
184
- celldetective-1.5.0b0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
185
- celldetective-1.5.0b0.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
186
- celldetective-1.5.0b0.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
187
- celldetective-1.5.0b0.dist-info/RECORD,,
183
+ celldetective-1.5.0b1.dist-info/METADATA,sha256=_caTP5XkidOp8X2DIaINXht-jIS1cznMI0IPzzU3K68,10947
184
+ celldetective-1.5.0b1.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
185
+ celldetective-1.5.0b1.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
186
+ celldetective-1.5.0b1.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
187
+ celldetective-1.5.0b1.dist-info/RECORD,,