spacr 0.5.0__py3-none-any.whl → 0.9.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.
Files changed (100) hide show
  1. spacr/__init__.py +0 -2
  2. spacr/__main__.py +3 -3
  3. spacr/core.py +13 -106
  4. spacr/gui_core.py +2 -2
  5. spacr/gui_utils.py +1 -13
  6. spacr/io.py +24 -25
  7. spacr/mediar.py +12 -8
  8. spacr/plot.py +50 -13
  9. spacr/settings.py +45 -6
  10. spacr/submodules.py +11 -1
  11. spacr/timelapse.py +21 -3
  12. spacr/utils.py +154 -15
  13. {spacr-0.5.0.dist-info → spacr-0.9.0.dist-info}/METADATA +62 -62
  14. spacr-0.9.0.dist-info/RECORD +109 -0
  15. {spacr-0.5.0.dist-info → spacr-0.9.0.dist-info}/WHEEL +1 -1
  16. spacr/resources/MEDIAR/.gitignore +0 -18
  17. spacr/resources/MEDIAR/LICENSE +0 -21
  18. spacr/resources/MEDIAR/README.md +0 -189
  19. spacr/resources/MEDIAR/SetupDict.py +0 -39
  20. spacr/resources/MEDIAR/__pycache__/SetupDict.cpython-39.pyc +0 -0
  21. spacr/resources/MEDIAR/__pycache__/evaluate.cpython-39.pyc +0 -0
  22. spacr/resources/MEDIAR/__pycache__/generate_mapping.cpython-39.pyc +0 -0
  23. spacr/resources/MEDIAR/__pycache__/main.cpython-39.pyc +0 -0
  24. spacr/resources/MEDIAR/config/baseline.json +0 -60
  25. spacr/resources/MEDIAR/config/mediar_example.json +0 -72
  26. spacr/resources/MEDIAR/config/pred/pred_mediar.json +0 -17
  27. spacr/resources/MEDIAR/config/step1_pretraining/phase1.json +0 -55
  28. spacr/resources/MEDIAR/config/step1_pretraining/phase2.json +0 -58
  29. spacr/resources/MEDIAR/config/step2_finetuning/finetuning1.json +0 -66
  30. spacr/resources/MEDIAR/config/step2_finetuning/finetuning2.json +0 -66
  31. spacr/resources/MEDIAR/config/step3_prediction/base_prediction.json +0 -16
  32. spacr/resources/MEDIAR/config/step3_prediction/ensemble_tta.json +0 -23
  33. spacr/resources/MEDIAR/core/BasePredictor.py +0 -120
  34. spacr/resources/MEDIAR/core/BaseTrainer.py +0 -240
  35. spacr/resources/MEDIAR/core/Baseline/Predictor.py +0 -59
  36. spacr/resources/MEDIAR/core/Baseline/Trainer.py +0 -113
  37. spacr/resources/MEDIAR/core/Baseline/__init__.py +0 -2
  38. spacr/resources/MEDIAR/core/Baseline/__pycache__/Predictor.cpython-39.pyc +0 -0
  39. spacr/resources/MEDIAR/core/Baseline/__pycache__/Trainer.cpython-39.pyc +0 -0
  40. spacr/resources/MEDIAR/core/Baseline/__pycache__/__init__.cpython-39.pyc +0 -0
  41. spacr/resources/MEDIAR/core/Baseline/__pycache__/utils.cpython-39.pyc +0 -0
  42. spacr/resources/MEDIAR/core/Baseline/utils.py +0 -80
  43. spacr/resources/MEDIAR/core/MEDIAR/EnsemblePredictor.py +0 -105
  44. spacr/resources/MEDIAR/core/MEDIAR/Predictor.py +0 -234
  45. spacr/resources/MEDIAR/core/MEDIAR/Trainer.py +0 -172
  46. spacr/resources/MEDIAR/core/MEDIAR/__init__.py +0 -3
  47. spacr/resources/MEDIAR/core/MEDIAR/__pycache__/EnsemblePredictor.cpython-39.pyc +0 -0
  48. spacr/resources/MEDIAR/core/MEDIAR/__pycache__/Predictor.cpython-39.pyc +0 -0
  49. spacr/resources/MEDIAR/core/MEDIAR/__pycache__/Trainer.cpython-39.pyc +0 -0
  50. spacr/resources/MEDIAR/core/MEDIAR/__pycache__/__init__.cpython-39.pyc +0 -0
  51. spacr/resources/MEDIAR/core/MEDIAR/__pycache__/utils.cpython-39.pyc +0 -0
  52. spacr/resources/MEDIAR/core/MEDIAR/utils.py +0 -429
  53. spacr/resources/MEDIAR/core/__init__.py +0 -2
  54. spacr/resources/MEDIAR/core/__pycache__/BasePredictor.cpython-39.pyc +0 -0
  55. spacr/resources/MEDIAR/core/__pycache__/BaseTrainer.cpython-39.pyc +0 -0
  56. spacr/resources/MEDIAR/core/__pycache__/__init__.cpython-39.pyc +0 -0
  57. spacr/resources/MEDIAR/core/__pycache__/utils.cpython-39.pyc +0 -0
  58. spacr/resources/MEDIAR/core/utils.py +0 -40
  59. spacr/resources/MEDIAR/evaluate.py +0 -71
  60. spacr/resources/MEDIAR/generate_mapping.py +0 -121
  61. spacr/resources/MEDIAR/image/examples/img1.tiff +0 -0
  62. spacr/resources/MEDIAR/image/examples/img2.tif +0 -0
  63. spacr/resources/MEDIAR/image/failure_cases.png +0 -0
  64. spacr/resources/MEDIAR/image/mediar_framework.png +0 -0
  65. spacr/resources/MEDIAR/image/mediar_model.PNG +0 -0
  66. spacr/resources/MEDIAR/image/mediar_results.png +0 -0
  67. spacr/resources/MEDIAR/main.py +0 -125
  68. spacr/resources/MEDIAR/predict.py +0 -70
  69. spacr/resources/MEDIAR/requirements.txt +0 -14
  70. spacr/resources/MEDIAR/train_tools/__init__.py +0 -3
  71. spacr/resources/MEDIAR/train_tools/__pycache__/__init__.cpython-39.pyc +0 -0
  72. spacr/resources/MEDIAR/train_tools/__pycache__/measures.cpython-39.pyc +0 -0
  73. spacr/resources/MEDIAR/train_tools/__pycache__/utils.cpython-39.pyc +0 -0
  74. spacr/resources/MEDIAR/train_tools/data_utils/__init__.py +0 -1
  75. spacr/resources/MEDIAR/train_tools/data_utils/__pycache__/__init__.cpython-39.pyc +0 -0
  76. spacr/resources/MEDIAR/train_tools/data_utils/__pycache__/datasetter.cpython-39.pyc +0 -0
  77. spacr/resources/MEDIAR/train_tools/data_utils/__pycache__/transforms.cpython-39.pyc +0 -0
  78. spacr/resources/MEDIAR/train_tools/data_utils/__pycache__/utils.cpython-39.pyc +0 -0
  79. spacr/resources/MEDIAR/train_tools/data_utils/custom/CellAware.py +0 -88
  80. spacr/resources/MEDIAR/train_tools/data_utils/custom/LoadImage.py +0 -161
  81. spacr/resources/MEDIAR/train_tools/data_utils/custom/NormalizeImage.py +0 -77
  82. spacr/resources/MEDIAR/train_tools/data_utils/custom/__init__.py +0 -3
  83. spacr/resources/MEDIAR/train_tools/data_utils/custom/__pycache__/CellAware.cpython-39.pyc +0 -0
  84. spacr/resources/MEDIAR/train_tools/data_utils/custom/__pycache__/LoadImage.cpython-39.pyc +0 -0
  85. spacr/resources/MEDIAR/train_tools/data_utils/custom/__pycache__/NormalizeImage.cpython-39.pyc +0 -0
  86. spacr/resources/MEDIAR/train_tools/data_utils/custom/__pycache__/__init__.cpython-39.pyc +0 -0
  87. spacr/resources/MEDIAR/train_tools/data_utils/custom/modalities.pkl +0 -0
  88. spacr/resources/MEDIAR/train_tools/data_utils/datasetter.py +0 -208
  89. spacr/resources/MEDIAR/train_tools/data_utils/transforms.py +0 -148
  90. spacr/resources/MEDIAR/train_tools/data_utils/utils.py +0 -84
  91. spacr/resources/MEDIAR/train_tools/measures.py +0 -200
  92. spacr/resources/MEDIAR/train_tools/models/MEDIARFormer.py +0 -102
  93. spacr/resources/MEDIAR/train_tools/models/__init__.py +0 -1
  94. spacr/resources/MEDIAR/train_tools/models/__pycache__/MEDIARFormer.cpython-39.pyc +0 -0
  95. spacr/resources/MEDIAR/train_tools/models/__pycache__/__init__.cpython-39.pyc +0 -0
  96. spacr/resources/MEDIAR/train_tools/utils.py +0 -70
  97. spacr-0.5.0.dist-info/RECORD +0 -190
  98. {spacr-0.5.0.dist-info → spacr-0.9.0.dist-info}/LICENSE +0 -0
  99. {spacr-0.5.0.dist-info → spacr-0.9.0.dist-info}/entry_points.txt +0 -0
  100. {spacr-0.5.0.dist-info → spacr-0.9.0.dist-info}/top_level.txt +0 -0
spacr/submodules.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import seaborn as sns
2
- import os, random, sqlite3, re, shap, string, time
2
+ import os, random, sqlite3, re, shap, string, time, shutil
3
3
  import pandas as pd
4
4
  import numpy as np
5
5
 
@@ -580,6 +580,16 @@ def analyze_recruitment(settings):
580
580
  from .settings import get_analyze_recruitment_default_settings
581
581
 
582
582
  settings = get_analyze_recruitment_default_settings(settings=settings)
583
+
584
+ if settings['src'].endswith('/measurements.db'):
585
+ src_orig = settings['src']
586
+ settings['src'] = os.path.dirname(settings['src'])
587
+ if not settings['src'].endswith('/measurements'):
588
+ src_mes = os.path.join(settings['src'], 'measurements')
589
+ if not os.path.exists(src_mes):
590
+ os.makedirs(src_mes)
591
+ shutil.move(src_orig, os.path.join(src_mes, 'measurements.db'))
592
+
583
593
  save_settings(settings, name='recruitment')
584
594
 
585
595
  print(f"Cell(s): {settings['cell_types']}, in {settings['cell_plate_metadata']}")
spacr/timelapse.py CHANGED
@@ -286,7 +286,7 @@ def _prepare_for_tracking_v1(mask_array):
286
286
  })
287
287
  return pd.DataFrame(frames)
288
288
 
289
- def _prepare_for_tracking(mask_array):
289
+ def _prepare_for_tracking_v1(mask_array):
290
290
  frames = []
291
291
  for t, frame in enumerate(mask_array):
292
292
  props = regionprops_table(
@@ -305,6 +305,24 @@ def _prepare_for_tracking(mask_array):
305
305
  'bbox-0','bbox-1','bbox-2','bbox-3','eccentricity']])
306
306
  return pd.concat(frames, ignore_index=True)
307
307
 
308
+ def _prepare_for_tracking(mask_array):
309
+ frames = []
310
+ for t, frame in enumerate(mask_array):
311
+ props = regionprops_table(
312
+ frame,
313
+ properties=('label', 'centroid', 'area', 'bbox', 'eccentricity')
314
+ )
315
+ df = pd.DataFrame(props)
316
+ df = df.rename(columns={
317
+ 'centroid-0': 'y',
318
+ 'centroid-1': 'x',
319
+ 'area': 'mass',
320
+ 'label': 'original_label'
321
+ })
322
+ df['frame'] = t
323
+ frames.append(df[['frame','y','x','mass','original_label',
324
+ 'bbox-0','bbox-1','bbox-2','bbox-3','eccentricity']])
325
+ return pd.concat(frames, ignore_index=True)
308
326
 
309
327
  def _track_by_iou(masks, iou_threshold=0.1):
310
328
  """
@@ -544,7 +562,7 @@ def _facilitate_trackin_with_adaptive_removal_v1(masks, search_range=500, max_at
544
562
  print(f"Failed to track objects after {max_attempts} attempts. Consider adjusting parameters.")
545
563
  return None, None, None
546
564
 
547
- def _trackpy_track_cells(src, name, batch_filenames, object_type, masks, timelapse_displacement, timelapse_memory, timelapse_remove_transient, plot, save, mode):
565
+ def _trackpy_track_cells(src, name, batch_filenames, object_type, masks, timelapse_displacement, timelapse_memory, timelapse_remove_transient, plot, save, mode, track_by_iou):
548
566
  """
549
567
  Track cells using the Trackpy library.
550
568
 
@@ -577,7 +595,7 @@ def _trackpy_track_cells(src, name, batch_filenames, object_type, masks, timelap
577
595
  if timelapse_displacement is None:
578
596
  timelapse_displacement = 50
579
597
 
580
- masks, features, tracks_df = _facilitate_trackin_with_adaptive_removal(masks, search_range=timelapse_displacement, max_attempts=100, memory=timelapse_memory)
598
+ masks, features, tracks_df = _facilitate_trackin_with_adaptive_removal(masks, search_range=timelapse_displacement, max_attempts=100, memory=timelapse_memory, track_by_iou=track_by_iou)
581
599
 
582
600
  tracks_df['particle'] += 1
583
601
 
spacr/utils.py CHANGED
@@ -10,7 +10,7 @@ import skimage.measure as measure
10
10
  from skimage.transform import resize as resizescikit
11
11
  from skimage.morphology import dilation, square
12
12
  from skimage.measure import find_contours
13
- from skimage.segmentation import clear_border
13
+ from skimage.segmentation import clear_border, find_boundaries
14
14
  from scipy.stats import pearsonr
15
15
 
16
16
  from collections import defaultdict, OrderedDict
@@ -431,7 +431,7 @@ def close_multiprocessing_processes():
431
431
 
432
432
  def check_mask_folder(src,mask_fldr):
433
433
 
434
- mask_folder = os.path.join(src,'norm_channel_stack',mask_fldr)
434
+ mask_folder = os.path.join(src,'masks',mask_fldr)
435
435
  stack_folder = os.path.join(src,'stack')
436
436
 
437
437
  if not os.path.exists(mask_folder):
@@ -1266,9 +1266,9 @@ def _pivot_counts_table(db_path):
1266
1266
 
1267
1267
  def _get_cellpose_channels(src, nucleus_channel, pathogen_channel, cell_channel):
1268
1268
 
1269
- cell_mask_path = os.path.join(src, 'norm_channel_stack', 'cell_mask_stack')
1270
- nucleus_mask_path = os.path.join(src, 'norm_channel_stack', 'nucleus_mask_stack')
1271
- pathogen_mask_path = os.path.join(src, 'norm_channel_stack', 'pathogen_mask_stack')
1269
+ cell_mask_path = os.path.join(src, 'masks', 'cell_mask_stack')
1270
+ nucleus_mask_path = os.path.join(src, 'masks', 'nucleus_mask_stack')
1271
+ pathogen_mask_path = os.path.join(src, 'masks', 'pathogen_mask_stack')
1272
1272
 
1273
1273
 
1274
1274
  if os.path.exists(cell_mask_path) or os.path.exists(nucleus_mask_path) or os.path.exists(pathogen_mask_path):
@@ -3088,17 +3088,19 @@ def _object_filter(df, object_type, size_range, intensity_range, mask_chans, mas
3088
3088
  return df
3089
3089
 
3090
3090
  def _get_regex(metadata_type, img_format, custom_regex=None):
3091
+
3092
+ print(f"Image_format: {img_format}")
3091
3093
 
3092
3094
  if img_format == None:
3093
- img_format == '.tif'
3095
+ img_format == 'tif'
3094
3096
  if metadata_type == 'cellvoyager':
3095
- regex = f'(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID>..)A(?P<AID>..)Z(?P<sliceID>.*)C(?P<chanID>.*){img_format}'
3097
+ regex = f"(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID>..)A(?P<AID>..)Z(?P<sliceID>.*)C(?P<chanID>.*).{img_format}"
3096
3098
  elif metadata_type == 'cq1':
3097
- regex = f'W(?P<wellID>.*)F(?P<fieldID>.*)T(?P<timeID>.*)Z(?P<sliceID>.*)C(?P<chanID>.*){img_format}'
3099
+ regex = f"W(?P<wellID>.*)F(?P<fieldID>.*)T(?P<timeID>.*)Z(?P<sliceID>.*)C(?P<chanID>.*).{img_format}"
3098
3100
  elif metadata_type == 'auto':
3099
- regex = f'(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID>.*)C(?P<chanID>.*).tif'
3101
+ regex = f"(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID>.*)C(?P<chanID>.*).tif"
3100
3102
  elif metadata_type == 'custom':
3101
- regex = f'({custom_regex}){img_format}'
3103
+ regex = f"({custom_regex}){img_format}"
3102
3104
 
3103
3105
  print(f'regex mode:{metadata_type} regex:{regex}')
3104
3106
  return regex
@@ -4507,6 +4509,76 @@ def _merge_cells_based_on_parasite_overlap(parasite_mask, cell_mask, nuclei_mask
4507
4509
  relabeled_cell_mask, _ = label(cell_mask, return_num=True)
4508
4510
  return relabeled_cell_mask.astype(np.uint16)
4509
4511
 
4512
+ def _merge_cells_without_nucleus(adj_cell_mask: np.ndarray, nuclei_mask: np.ndarray):
4513
+ """
4514
+ Relabel any cell that lacks a nucleus to the ID of an adjacent
4515
+ cell that *does* contain a nucleus.
4516
+
4517
+ Parameters
4518
+ ----------
4519
+ adj_cell_mask : np.ndarray
4520
+ Labelled (0 = background) cell mask after all other merging steps.
4521
+ nuclei_mask : np.ndarray
4522
+ Labelled (0 = background) nuclei mask.
4523
+
4524
+ Returns
4525
+ -------
4526
+ np.ndarray
4527
+ Updated cell mask with nucleus-free cells merged into
4528
+ neighbouring nucleus-bearing cells.
4529
+ """
4530
+ out = adj_cell_mask.copy()
4531
+
4532
+ # ----------------------------------------------------------------- #
4533
+ # 1 — Identify which cell IDs contain a nucleus
4534
+ nuc_labels = np.unique(nuclei_mask[nuclei_mask > 0])
4535
+
4536
+ cells_with_nuc = set()
4537
+ for nuc_id in nuc_labels:
4538
+ labels, counts = np.unique(adj_cell_mask[nuclei_mask == nuc_id],
4539
+ return_counts=True)
4540
+
4541
+ # drop background (label 0) from *both* arrays
4542
+ keep = labels > 0
4543
+ labels = labels[keep]
4544
+ counts = counts[keep]
4545
+
4546
+ if labels.size: # at least one non-zero overlap
4547
+ cells_with_nuc.add(labels[np.argmax(counts)])
4548
+
4549
+ # ----------------------------------------------------------------- #
4550
+ # 2 — Build an adjacency map between neighbouring cell IDs
4551
+ # ----------------------------------------------------------------- #
4552
+ boundaries = find_boundaries(adj_cell_mask, mode="thick")
4553
+ adj_map = defaultdict(set)
4554
+
4555
+ ys, xs = np.where(boundaries)
4556
+ h, w = adj_cell_mask.shape
4557
+ for y, x in zip(ys, xs):
4558
+ src = adj_cell_mask[y, x]
4559
+ if src == 0:
4560
+ continue
4561
+ for dy in (-1, 0, 1):
4562
+ for dx in (-1, 0, 1):
4563
+ ny, nx = y + dy, x + dx
4564
+ if 0 <= ny < h and 0 <= nx < w:
4565
+ dst = adj_cell_mask[ny, nx]
4566
+ if dst != 0 and dst != src:
4567
+ adj_map[src].add(dst)
4568
+
4569
+ # ----------------------------------------------------------------- #
4570
+ # 3 — Relabel nucleus-free cells that touch nucleus-bearing neighbours
4571
+ # ----------------------------------------------------------------- #
4572
+ cells_no_nuc = set(np.unique(adj_cell_mask)) - {0} - cells_with_nuc
4573
+ for cell_id in cells_no_nuc:
4574
+ neighbours = adj_map.get(cell_id, set()) & cells_with_nuc
4575
+ if neighbours:
4576
+ # Choose the first nucleus-bearing neighbour deterministically
4577
+ target = sorted(neighbours)[0]
4578
+ out[out == cell_id] = target
4579
+
4580
+ return out.astype(np.uint16)
4581
+
4510
4582
  def adjust_cell_masks(parasite_folder, cell_folder, nuclei_folder, overlap_threshold=5, perimeter_threshold=30):
4511
4583
 
4512
4584
  """
@@ -4541,12 +4613,12 @@ def adjust_cell_masks(parasite_folder, cell_folder, nuclei_folder, overlap_thres
4541
4613
  parasite_mask = np.load(parasite_path, allow_pickle=True)
4542
4614
  cell_mask = np.load(cell_path, allow_pickle=True)
4543
4615
  nuclei_mask = np.load(nuclei_path, allow_pickle=True)
4616
+
4544
4617
  # Merge and relabel cells
4545
4618
  merged_cell_mask = _merge_cells_based_on_parasite_overlap(parasite_mask, cell_mask, nuclei_mask, overlap_threshold, perimeter_threshold)
4546
4619
 
4547
- # Force 16 bit
4548
- #merged_cell_mask = merged_cell_mask.astype(np.uint16)
4549
-
4620
+ #merged_cell_mask = _merge_cells_without_nucleus(merged_cell_mask, nuclei_mask)
4621
+
4550
4622
  # Overwrite the original cell mask file with the merged result
4551
4623
  np.save(cell_path, merged_cell_mask)
4552
4624
 
@@ -4836,7 +4908,7 @@ def correct_masks(src):
4836
4908
 
4837
4909
  from .io import _load_and_concatenate_arrays
4838
4910
 
4839
- cell_path = os.path.join(src,'norm_channel_stack', 'cell_mask_stack')
4911
+ cell_path = os.path.join(src,'masks', 'cell_mask_stack')
4840
4912
  convert_and_relabel_masks(cell_path)
4841
4913
  _load_and_concatenate_arrays(src, [0,1,2,3], 1, 0, 2)
4842
4914
 
@@ -5107,6 +5179,39 @@ def control_filelist(folder, mode='columnID', values=['01','02']):
5107
5179
  return filtered_files
5108
5180
 
5109
5181
  def rename_columns_in_db(db_path):
5182
+ # map old column names → new names
5183
+ rename_map = {
5184
+ 'row': 'rowID',
5185
+ 'column': 'columnID',
5186
+ 'col': 'columnID',
5187
+ 'plate': 'plateID',
5188
+ 'field': 'fieldID',
5189
+ 'channel': 'chanID',
5190
+ }
5191
+
5192
+ con = sqlite3.connect(db_path)
5193
+ cur = con.cursor()
5194
+
5195
+ # 1) get all user tables
5196
+ cur.execute("SELECT name FROM sqlite_master WHERE type='table';")
5197
+ tables = [row[0] for row in cur.fetchall()]
5198
+
5199
+ for table in tables:
5200
+ # 2) get column names only
5201
+ cur.execute(f"PRAGMA table_info(`{table}`);")
5202
+ cols = [row[1] for row in cur.fetchall()]
5203
+
5204
+ # 3) for each old→new, if the old exists and new does not, rename it
5205
+ for old, new in rename_map.items():
5206
+ if old in cols and new not in cols:
5207
+ sql = f"ALTER TABLE `{table}` RENAME COLUMN `{old}` TO `{new}`;"
5208
+ cur.execute(sql)
5209
+ print(f"Renamed `{table}`.`{old}` → `{new}`")
5210
+
5211
+ con.commit()
5212
+ con.close()
5213
+
5214
+ def rename_columns_in_db_v1(db_path):
5110
5215
  with sqlite3.connect(db_path) as conn:
5111
5216
  cursor = conn.cursor()
5112
5217
 
@@ -5189,7 +5294,7 @@ def delete_intermedeate_files(settings):
5189
5294
  path_orig = os.path.join(settings['src'], 'orig')
5190
5295
  path_stack = os.path.join(settings['src'], 'stack')
5191
5296
  merged_stack = os.path.join(settings['src'], 'merged')
5192
- path_norm_chan_stack = os.path.join(settings['src'], 'norm_channel_stack')
5297
+ path_norm_chan_stack = os.path.join(settings['src'], 'masks')
5193
5298
  path_1 = os.path.join(settings['src'], '1')
5194
5299
  path_2 = os.path.join(settings['src'], '2')
5195
5300
  path_3 = os.path.join(settings['src'], '3')
@@ -5476,3 +5581,37 @@ def correct_metadata(df):
5476
5581
  df = df.rename(columns={'field_name': 'fieldID'})
5477
5582
 
5478
5583
  return df
5584
+
5585
+ def remove_outliers_by_group(df, group_col, value_col, method='iqr', threshold=1.5):
5586
+ """
5587
+ Removes outliers from `value_col` within each group defined by `group_col`.
5588
+
5589
+ Parameters:
5590
+ df (pd.DataFrame): The input DataFrame.
5591
+ group_col (str): Column name to group by.
5592
+ value_col (str): Column containing values to check for outliers.
5593
+ method (str): 'iqr' or 'zscore'.
5594
+ threshold (float): Threshold multiplier for IQR (default 1.5) or z-score.
5595
+
5596
+ Returns:
5597
+ pd.DataFrame: A DataFrame with outliers removed.
5598
+ """
5599
+ def iqr_filter(subdf):
5600
+ q1 = subdf[value_col].quantile(0.25)
5601
+ q3 = subdf[value_col].quantile(0.75)
5602
+ iqr = q3 - q1
5603
+ lower = q1 - threshold * iqr
5604
+ upper = q3 + threshold * iqr
5605
+ return subdf[(subdf[value_col] >= lower) & (subdf[value_col] <= upper)]
5606
+
5607
+ def zscore_filter(subdf):
5608
+ mean = subdf[value_col].mean()
5609
+ std = subdf[value_col].std()
5610
+ return subdf[(subdf[value_col] - mean).abs() <= threshold * std]
5611
+
5612
+ if method == 'iqr':
5613
+ return df.groupby(group_col, group_keys=False).apply(iqr_filter)
5614
+ elif method == 'zscore':
5615
+ return df.groupby(group_col, group_keys=False).apply(zscore_filter)
5616
+ else:
5617
+ raise ValueError("method must be 'iqr' or 'zscore'")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spacr
3
- Version: 0.5.0
3
+ Version: 0.9.0
4
4
  Summary: Spatial phenotype analysis of crisp screens (SpaCr)
5
5
  Home-page: https://github.com/EinarOlafsson/spacr
6
6
  Author: Einar Birnir Olafsson
@@ -10,75 +10,75 @@ Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Description-Content-Type: text/x-rst
12
12
  License-File: LICENSE
13
- Requires-Dist: numpy<2.0,>=1.26.4
14
- Requires-Dist: pandas<3.0,>=2.2.1
15
- Requires-Dist: scipy<2.0,>=1.12.0
16
- Requires-Dist: cellpose<4.0,>=3.0.6
17
- Requires-Dist: scikit-image<1.0,>=0.22.0
18
- Requires-Dist: scikit-learn<2.0,>=1.4.1
19
- Requires-Dist: scikit-posthocs<0.20,>=0.10.0
20
- Requires-Dist: mahotas<2.0,>=1.4.13
21
- Requires-Dist: btrack<1.0,>=0.6.5
22
- Requires-Dist: trackpy<1.0,>=0.6.2
23
- Requires-Dist: statsmodels<1.0,>=0.14.1
24
- Requires-Dist: shap<1.0,>=0.45.0
25
- Requires-Dist: torch<3.0,>=2.0
26
- Requires-Dist: torchvision<1.0,>=0.1
27
- Requires-Dist: torch-geometric<3.0,>=2.5
28
- Requires-Dist: torchcam<1.0,>=0.4.0
29
- Requires-Dist: transformers<5.0,>=4.45.2
30
- Requires-Dist: segmentation-models-pytorch>=0.3.3
31
- Requires-Dist: monai>=1.3.0
32
- Requires-Dist: captum<1.0,>=0.7.0
33
- Requires-Dist: seaborn<1.0,>=0.13.2
34
- Requires-Dist: matplotlib<4.0,>=3.8.3
35
- Requires-Dist: matplotlib-venn<2.0,>=1.1
36
- Requires-Dist: adjustText<2.0,>=1.2.0
37
- Requires-Dist: bottleneck<2.0,>=1.3.6
38
- Requires-Dist: numexpr<3.0,>=2.8.4
39
- Requires-Dist: opencv-python-headless<5.0,>=4.9.0.80
40
- Requires-Dist: pillow<11.0,>=10.2.0
41
- Requires-Dist: tifffile>=2023.4.12
42
- Requires-Dist: nd2reader<4.0,>=3.3.0
13
+ Requires-Dist: numpy <2.0,>=1.26.4
14
+ Requires-Dist: pandas <3.0,>=2.2.1
15
+ Requires-Dist: scipy <2.0,>=1.12.0
16
+ Requires-Dist: cellpose <4.0,>=3.0.6
17
+ Requires-Dist: scikit-image <1.0,>=0.22.0
18
+ Requires-Dist: scikit-learn <2.0,>=1.4.1
19
+ Requires-Dist: scikit-posthocs <0.20,>=0.10.0
20
+ Requires-Dist: mahotas <2.0,>=1.4.13
21
+ Requires-Dist: btrack <1.0,>=0.6.5
22
+ Requires-Dist: trackpy <1.0,>=0.6.2
23
+ Requires-Dist: statsmodels <1.0,>=0.14.1
24
+ Requires-Dist: shap <1.0,>=0.45.0
25
+ Requires-Dist: torch <3.0,>=2.0
26
+ Requires-Dist: torchvision <1.0,>=0.1
27
+ Requires-Dist: torch-geometric <3.0,>=2.5
28
+ Requires-Dist: torchcam <1.0,>=0.4.0
29
+ Requires-Dist: transformers <5.0,>=4.45.2
30
+ Requires-Dist: segmentation-models-pytorch >=0.3.3
31
+ Requires-Dist: monai >=1.3.0
32
+ Requires-Dist: captum <1.0,>=0.7.0
33
+ Requires-Dist: seaborn <1.0,>=0.13.2
34
+ Requires-Dist: matplotlib <4.0,>=3.8.3
35
+ Requires-Dist: matplotlib-venn <2.0,>=1.1
36
+ Requires-Dist: adjustText <2.0,>=1.2.0
37
+ Requires-Dist: bottleneck <2.0,>=1.3.6
38
+ Requires-Dist: numexpr <3.0,>=2.8.4
39
+ Requires-Dist: opencv-python-headless <5.0,>=4.9.0.80
40
+ Requires-Dist: pillow <11.0,>=10.2.0
41
+ Requires-Dist: tifffile >=2023.4.12
42
+ Requires-Dist: nd2reader <4.0,>=3.3.0
43
43
  Requires-Dist: czifile
44
- Requires-Dist: pylibCZIrw<6.0,>=5.0.0
44
+ Requires-Dist: pylibCZIrw <6.0,>=5.0.0
45
45
  Requires-Dist: aicspylibczi
46
46
  Requires-Dist: readlif
47
- Requires-Dist: imageio<3.0,>=2.34.0
48
- Requires-Dist: pingouin<1.0,>=0.5.5
49
- Requires-Dist: umap-learn<1.0,>=0.5.6
50
- Requires-Dist: ttkthemes<4.0,>=3.2.2
51
- Requires-Dist: xgboost<3.0,>=2.0.3
52
- Requires-Dist: PyWavelets<2.0,>=1.6.0
53
- Requires-Dist: ttf-opensans>=2020.10.30
54
- Requires-Dist: customtkinter<6.0,>=5.2.2
55
- Requires-Dist: biopython<2.0,>=1.80
56
- Requires-Dist: lxml<6.0,>=5.1.0
57
- Requires-Dist: psutil<6.0,>=5.9.8
58
- Requires-Dist: gputil<2.0,>=1.4.0
59
- Requires-Dist: gpustat<2.0,>=1.1.1
60
- Requires-Dist: pyautogui<1.0,>=0.9.54
61
- Requires-Dist: tables<4.0,>=3.8.0
62
- Requires-Dist: rapidfuzz<4.0,>=3.9
63
- Requires-Dist: keyring<16.0,>=15.1
64
- Requires-Dist: screeninfo<1.0,>=0.8.1
65
- Requires-Dist: fastremap>=1.14.1
66
- Requires-Dist: pytz>=2023.3.post1
67
- Requires-Dist: tqdm>=4.65.0
68
- Requires-Dist: wandb>=0.16.2
69
- Requires-Dist: openai<2.0,>=1.50.2
47
+ Requires-Dist: imageio <3.0,>=2.34.0
48
+ Requires-Dist: pingouin <1.0,>=0.5.5
49
+ Requires-Dist: umap-learn <1.0,>=0.5.6
50
+ Requires-Dist: ttkthemes <4.0,>=3.2.2
51
+ Requires-Dist: xgboost <3.0,>=2.0.3
52
+ Requires-Dist: PyWavelets <2.0,>=1.6.0
53
+ Requires-Dist: ttf-opensans >=2020.10.30
54
+ Requires-Dist: customtkinter <6.0,>=5.2.2
55
+ Requires-Dist: biopython <2.0,>=1.80
56
+ Requires-Dist: lxml <6.0,>=5.1.0
57
+ Requires-Dist: psutil <6.0,>=5.9.8
58
+ Requires-Dist: gputil <2.0,>=1.4.0
59
+ Requires-Dist: gpustat <2.0,>=1.1.1
60
+ Requires-Dist: pyautogui <1.0,>=0.9.54
61
+ Requires-Dist: tables <4.0,>=3.8.0
62
+ Requires-Dist: rapidfuzz <4.0,>=3.9
63
+ Requires-Dist: keyring <16.0,>=15.1
64
+ Requires-Dist: screeninfo <1.0,>=0.8.1
65
+ Requires-Dist: fastremap >=1.14.1
66
+ Requires-Dist: pytz >=2023.3.post1
67
+ Requires-Dist: tqdm >=4.65.0
68
+ Requires-Dist: wandb >=0.16.2
69
+ Requires-Dist: openai <2.0,>=1.50.2
70
70
  Requires-Dist: gdown
71
- Requires-Dist: IPython<9.0,>=8.18.1
71
+ Requires-Dist: IPython <9.0,>=8.18.1
72
72
  Requires-Dist: ipykernel
73
- Requires-Dist: ipywidgets<9.0,>=8.1.2
74
- Requires-Dist: brokenaxes<1.0,>=0.6.2
75
- Requires-Dist: huggingface-hub<0.25,>=0.24.0
73
+ Requires-Dist: ipywidgets <9.0,>=8.1.2
74
+ Requires-Dist: brokenaxes <1.0,>=0.6.2
75
+ Requires-Dist: huggingface-hub <0.25,>=0.24.0
76
76
  Provides-Extra: dev
77
- Requires-Dist: pytest<3.11,>=3.9; extra == "dev"
77
+ Requires-Dist: pytest <3.11,>=3.9 ; extra == 'dev'
78
78
  Provides-Extra: full
79
- Requires-Dist: opencv-python; extra == "full"
79
+ Requires-Dist: opencv-python ; extra == 'full'
80
80
  Provides-Extra: headless
81
- Requires-Dist: opencv-python-headless; extra == "headless"
81
+ Requires-Dist: opencv-python-headless ; extra == 'headless'
82
82
 
83
83
  .. |Documentation Status| image:: https://readthedocs.org/projects/spacr/badge/?version=latest
84
84
  :target: https://einarolafsson.github.io/spacr
@@ -0,0 +1,109 @@
1
+ spacr/__init__.py,sha256=EoGInYks0M4foZElYNhksrQK6aEO1au7cncWexWNhRw,1376
2
+ spacr/__main__.py,sha256=H4MjaMF9ohZL6xfl1kTxVn1Nt_vEhhZArENMMBv8f4E,77
3
+ spacr/app_annotate.py,sha256=W9eLPa_LZIvXsXx_-0iDFEU938LBDvRy6prXo0qF4KQ,2533
4
+ spacr/app_classify.py,sha256=urTP_wlZ58hSyM5a19slYlBxN0PdC-9-ga0hvq8CGWc,165
5
+ spacr/app_make_masks.py,sha256=pqDhRpluiHZz-kPX2Zh_KbYe4TsU43qYBa_7f-rsjpw,1694
6
+ spacr/app_mask.py,sha256=l-dBY8ftzCMdDe6-pXc2Nh_u-idNL9G7UOARiLJBtds,153
7
+ spacr/app_measure.py,sha256=_K7APYIeOKpV6e_LcqabBjvEi7mfq9Fch8175x1x0k8,162
8
+ spacr/app_sequencing.py,sha256=DjG26jy4cpddnV8WOOAIiExtOe9MleVMY4MFa5uTo5w,157
9
+ spacr/app_umap.py,sha256=ZWAmf_OsIKbYvolYuWPMYhdlVe-n2CADoJulAizMiEo,153
10
+ spacr/chat_bot.py,sha256=n3Fhqg3qofVXHmh3H9sUcmfYy9MmgRnr48663MVdY9E,1244
11
+ spacr/core.py,sha256=w4E3Pg-ZnA8BOK0iUMTjiNO0GeR5YCEs8fUTbESzqjY,47392
12
+ spacr/deep_spacr.py,sha256=055tIo3WP3elGFiIuSZaLURgu2XyUDxAdbw5ezASEqM,54526
13
+ spacr/gui.py,sha256=NhMh96KoArrSAaJBV6PhDQpIC1cQpxgb6SclhRbYG8s,8122
14
+ spacr/gui_core.py,sha256=jQPDQVP43YL_AW7Sm8cIQgdZVaB9Yig8U6ov9clCYOc,56180
15
+ spacr/gui_elements.py,sha256=5a3BOpctBPklsT1NungqS72h1Bg1FArUndE0OfvWD8Y,152646
16
+ spacr/gui_utils.py,sha256=vv_uBOA0n-04KCCicYHhNt3sRbm0IPLM5r8QX5EkJ1Q,40867
17
+ spacr/io.py,sha256=SYLhupKnOJJscNSGE4N67E32-ywhwrjRccIfZrL38Uk,157966
18
+ spacr/logger.py,sha256=lJhTqt-_wfAunCPl93xE65Wr9Y1oIHJWaZMjunHUeIw,1538
19
+ spacr/measure.py,sha256=Z3u4BU5RzcY82IZuboQ0OsxuXaPVwOlH65Rw6FrL5z4,55045
20
+ spacr/mediar.py,sha256=p0F515eFbm6_rePSnChsgqrgH-H5Sr_3zWrghtOnAUg,14863
21
+ spacr/ml.py,sha256=XCRZeX7UkbMctQICIoskeWVx8CCmmCoHNauUOAkfFq0,91692
22
+ spacr/openai.py,sha256=5vBZ3Jl2llYcW3oaTEXgdyCB2aJujMUIO5K038z7w_A,1246
23
+ spacr/plot.py,sha256=DGQulM2425DFVRMT9ZVvZW8EMxnc3hzjXhcL7fTMrGA,172668
24
+ spacr/sequencing.py,sha256=EY12RdW5QRKpHDRQCw1QoAlxCq8FK2v6WoVa5uuDBXQ,26745
25
+ spacr/settings.py,sha256=LzJbebCRkDVYJxbojZKQE88MJ8Fg8iR6HZNHjN_np28,88687
26
+ spacr/sim.py,sha256=1xKhXimNU3ukzIw-3l9cF3Znc_brW8h20yv8fSTzvss,71173
27
+ spacr/sp_stats.py,sha256=mbhwsyIqt5upsSD346qGjdCw7CFBa0tIS7zHU9e0jNI,9536
28
+ spacr/spacr_cellpose.py,sha256=RBHMs2vwXcfkj0xqAULpALyzJYXddSRycgZSzmwI7v0,14755
29
+ spacr/submodules.py,sha256=Z2i4kv_rWdxqoXsOKCF7BaSXtvaCZB69Ow8_FQBnZsY,83093
30
+ spacr/timelapse.py,sha256=YJciEQS15eVC9R9adcen62xx7uttGAr_Gaz1vGX2Ke8,46824
31
+ spacr/toxo.py,sha256=GoNfgyH-NJx3WOzNQPgzODir7Jp65fs7UM46XpzcrUo,26056
32
+ spacr/utils.py,sha256=ddeLh_KWA1bQsB9R3OtljFmsoWrriWjIJDq7x61J_XI,236185
33
+ spacr/version.py,sha256=axH5tnGwtgSnJHb5IDhiu4Zjk5GhLyAEDRe-rnaoFOA,409
34
+ spacr/resources/data/lopit.csv,sha256=ERI5f9W8RdJGiSx_khoaylD374f8kmvLia1xjhD_mII,4421709
35
+ spacr/resources/data/toxoplasma_metadata.csv,sha256=9TXx0VlClDHAxQmaLhoklE8NuETduXaGHZjhR_6lZfs,2969409
36
+ spacr/resources/font/open_sans/OFL.txt,sha256=bGMoWBRrE2RcdzDiuYiB8A9OVFlJ0sA2imWwce2DAdo,4484
37
+ "spacr/resources/font/open_sans/OpenSans-Italic-VariableFont_wdth,wght.ttf",sha256=QSoWv9h46CRX_fdlqFM3O2d3-PF3R1srnb4zUezcLm0,580280
38
+ "spacr/resources/font/open_sans/OpenSans-VariableFont_wdth,wght.ttf",sha256=E3RLvAefD0kuT7OxShXSQrjZYA-qzUI9WM35N_6nzms,529700
39
+ spacr/resources/font/open_sans/README.txt,sha256=-ZB4ocy30PWpgUpWm_djuTyBe_NiE1yEFG7H-zODBbA,3518
40
+ spacr/resources/font/open_sans/static/OpenSans-Bold.ttf,sha256=vHPEXlgQoJcevq7062w13shGB9vgLaZ1f59D2Vi22l8,130860
41
+ spacr/resources/font/open_sans/static/OpenSans-BoldItalic.ttf,sha256=tiGd9Fy-5vh25rKPZoNI4YB7H7mtEY6n1ocEHw0zI4Q,136360
42
+ spacr/resources/font/open_sans/static/OpenSans-ExtraBold.ttf,sha256=DAeBB3dmNBMRYr5Go4JFOZBAwr7MSV6T1p2bbt1lqY0,131244
43
+ spacr/resources/font/open_sans/static/OpenSans-ExtraBoldItalic.ttf,sha256=oDRGYhCusJ9__bySUKzNH1w-L7isv9O-iqFUmT7EPZs,136928
44
+ spacr/resources/font/open_sans/static/OpenSans-Italic.ttf,sha256=XqvWf-PYtbXu5kUE6p5KXvdmW2Q1d-8Rfzwy_aZ80p8,136604
45
+ spacr/resources/font/open_sans/static/OpenSans-Light.ttf,sha256=RurTiXjijzKtfcENRn7-jYtXhv-YAgw3GKKW-I738cw,130804
46
+ spacr/resources/font/open_sans/static/OpenSans-LightItalic.ttf,sha256=TqxQLBDa9mCOU-fbhteXaYkDc-u9VHKle7y3V4m8URA,136896
47
+ spacr/resources/font/open_sans/static/OpenSans-Medium.ttf,sha256=KrFWKUJKzobUKdvA5ae-sw0q89uZiisDpxYB7mllwzQ,130976
48
+ spacr/resources/font/open_sans/static/OpenSans-MediumItalic.ttf,sha256=v0NvTDTSySHQ8tSZfnhUBQpg_qqJu6zGBK6JatJUyos,136796
49
+ spacr/resources/font/open_sans/static/OpenSans-Regular.ttf,sha256=ZTBIAnfaYu_eBH6ybnin5TLRz67skWA-aNY4drlmnw0,130832
50
+ spacr/resources/font/open_sans/static/OpenSans-SemiBold.ttf,sha256=5gMTXMOxIAxyYLNPN_nLHyF4pCs2MDfiah4YJ2q3i_A,130760
51
+ spacr/resources/font/open_sans/static/OpenSans-SemiBoldItalic.ttf,sha256=sb8sWCggtXA9vNM5tdyXI1wUUYXQ-ruwnCJO-HIVJms,136724
52
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-Bold.ttf,sha256=CIWGlNIDGR-928YD8NguGNEEwnlBYir6S4_wzKyhK2A,130372
53
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-BoldItalic.ttf,sha256=dd_-wIDY3AM6l5T_JTYUo4D1H34Tmq5I2vEuvpqkrsQ,136240
54
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBold.ttf,sha256=98s7bdAITVn2b6nlI4tLuBkq1pSfmaFnPJELgyripT4,130812
55
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBoldItalic.ttf,sha256=Yh7na-RGr-rH4T_uNLv6cGefmQfyALsb1Qrf4c5xp30,136652
56
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-Italic.ttf,sha256=K8gjp2YPH9NLDCpX3ZrNRv7fCser4yoUbS6JXojzkQI,136588
57
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-Light.ttf,sha256=wcbhJiAM7-BGpJ82qwIMDcyEQJVnGXcTJzlFmAR4etY,130472
58
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-LightItalic.ttf,sha256=4eYPQJMjKmJ_QuIVuP6hQag4mVYxg5wVJFV8h28zd_c,136760
59
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-Medium.ttf,sha256=acH5RzYjKjt9ePPfhjwvdWHau9FxkgVNCCVzxUBUM6Y,130520
60
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-MediumItalic.ttf,sha256=vL_D1ucljgIr9sz4FSoWkg38QLVbxMglTBX0_01o3Vo,136700
61
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-Regular.ttf,sha256=9ZSB0mD3qvxsRpbdhgjMvhJxTJjmT41hQi7nWvuUl7U,130492
62
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBold.ttf,sha256=F5ld4DVfj5bpv37MfcrisKrdWosy6C85CVibgmFpMhw,130524
63
+ spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBoldItalic.ttf,sha256=bDVD8CkRaVOD96JJBURtnawSs8vspPKCNsBHW9SCBk0,136792
64
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Bold.ttf,sha256=saQFKWcgcpqcyyIV744l-gMfKKdKI6eC7gA7Eg2SqIc,131168
65
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-BoldItalic.ttf,sha256=wTHNHKW51uSs5WjuDM881pe51U25ezzIg4pKiQkkksE,137104
66
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBold.ttf,sha256=NWASkgz4LTrSPDAipCY41ul2Z5XDMeUleDE8C7Nt6RI,131744
67
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf,sha256=PZSxtpkBYq79eWqnTh4KcwtaoAd_QFA6AYfdtvZI-bc,137584
68
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Italic.ttf,sha256=bHPr5WeX4zrP-VaVVHquxysTBlnRog8lfrh2z2ydf1g,137000
69
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Light.ttf,sha256=ks1IgCjNng7ksZNOSKaqBefxvwTGXrgQTySGy0nfIJY,131128
70
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-LightItalic.ttf,sha256=-Xa1RlfcMxM1QYpjMNbNRv-a5ka8m5o5h-3P7gsMoRs,137220
71
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Medium.ttf,sha256=a-MrWOsGFqIGqpQXeaZyxruXqU3hMC2eHpWNa4wq8RE,130976
72
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-MediumItalic.ttf,sha256=vJfOBlOVmx_MXbkgSdxHdzSSeALkd253C4Srr84Qvq8,137068
73
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Regular.ttf,sha256=skg4DCl15zL9ZD4MAL9fOt4WjonKYBUOMj46ItSAe5Q,130848
74
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBold.ttf,sha256=uCiR97jg6sUHtGKVPNtJEg1zZG5Y9ArQ-raqBGjaeGg,130856
75
+ spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf,sha256=a5-0oOIrtJltQRa64uFKCdtcjzPvEJ71f_cYavG2i3E,137132
76
+ spacr/resources/icons/abort.png,sha256=avtIRT7aCJsdZ1WnY_rZStm6cCji5bYPLnlptdcTNcM,6583
77
+ spacr/resources/icons/annotate.png,sha256=GFgh7DiUMwPG_-xE6W1qU8V_qzSwBi1xKenfoaQxeFA,15495
78
+ spacr/resources/icons/cellpose_all.png,sha256=HVWOIOBF8p3-On-2UahwMyQXp7awsoC5yWExU1ahDag,20271
79
+ spacr/resources/icons/cellpose_masks.png,sha256=HVWOIOBF8p3-On-2UahwMyQXp7awsoC5yWExU1ahDag,20271
80
+ spacr/resources/icons/classify.png,sha256=-iv4sqAwUVJO3CG6fHKHf3_BB0s-I2i4prg-iR7dSBM,35897
81
+ spacr/resources/icons/convert.png,sha256=vLyTkQeUZ9q-pirhtZeXDq3-DzfjoPMjLlgKl5Wv6R0,7069
82
+ spacr/resources/icons/default.png,sha256=KoNhaSHukO4wDyivyYEgSbb5mGj-sAxmhKikLLtNpWs,20341
83
+ spacr/resources/icons/dna_matrix.mp4,sha256=NegOQkn4q4kHhFgqcIX2dd58wVytBtnkmbgg0ZegL8U,23462876
84
+ spacr/resources/icons/download.png,sha256=1nUoWRaTc4vIsK6gompdeqk0cIv2GdH-gCNHaEBX6Mc,20467
85
+ spacr/resources/icons/logo.pdf,sha256=VB4cS41V3VV_QxD7l6CwdQKQiYLErugLBxWoCoxjQU0,377925
86
+ spacr/resources/icons/logo_spacr.png,sha256=qG3e3bdrAefhl1281rfo0R2XP0qA-c-oaBCXjxMGXkw,42587
87
+ spacr/resources/icons/logo_spacr_1.png,sha256=g9y2ZmnV3hab8r1idDfytm8AaHbBiQdu_93Jd7YKzwA,610892
88
+ spacr/resources/icons/make_masks.png,sha256=iB4kaTgbgyygSJSNstVKhRIXKSgWYkeh7Gt3ox-kWDI,42493
89
+ spacr/resources/icons/map_barcodes.png,sha256=ED6yCopk3hP7tICSvT8U_qA1bOOb0WHqmxVkmRxnbtE,7896
90
+ spacr/resources/icons/mask.png,sha256=DcBes-3UJ7XjRfj_P4RttRp680ZKZeH9a-DSk7bIF5U,37658
91
+ spacr/resources/icons/measure.png,sha256=Gd-dlN-3Z8D_XngJnChNme8D63KEJMFs_cBv7wT2vOY,40938
92
+ spacr/resources/icons/ml_analyze.png,sha256=Wc9a_LpG2XffiMfXxn0yUmGP40IXzlAV7bHXQf7m_2o,15754
93
+ spacr/resources/icons/plaque.png,sha256=NWt7C8thV0iQ1YuRvW_NfUJSFG6XK_iGpoW0R9Xfsyc,45033
94
+ spacr/resources/icons/recruitment.png,sha256=dlVh2ebV_f3rhRFBiL0hDtlUeBSIeg0d4vny8A8IAdo,25067
95
+ spacr/resources/icons/regression.png,sha256=WIrKY4fSojBOCDkHno4Qb-KH7jcHh6G67dOKzczaU1I,42267
96
+ spacr/resources/icons/run.png,sha256=ICzyAvsRBCXNAbdn5N3PxCxxVyqxkfC4zOI5Zc8vbxQ,8974
97
+ spacr/resources/icons/sequencing.png,sha256=P9E_Y76ZysWMKst3_hAw-_4F510XPW1l1TsDElVzt4o,17775
98
+ spacr/resources/icons/settings.png,sha256=y5Ow5BxJDDsrqom0VNbOMDGGUs6odxbSMDy6y4r_F0w,22269
99
+ spacr/resources/icons/train_cellpose.png,sha256=_PZ_R_B6azuUACmscScAkugmgLZvCPKQFGIAsszqNLk,3858
100
+ spacr/resources/icons/umap.png,sha256=dOLF3DeLYy9k0nkUybiZMe1wzHQwLJFRmgccppw-8bI,27457
101
+ spacr/resources/images/plate1_E01_T0001F001L01A01Z01C02.tif,sha256=Tl0ZUfZ_AYAbu0up_nO0tPRtF1BxXhWQ3T3pURBCCRo,7958528
102
+ spacr/resources/images/plate1_E01_T0001F001L01A02Z01C01.tif,sha256=m8N-V71rA1TT4dFlENNg8s0Q0YEXXs8slIn7yObmZJQ,7958528
103
+ spacr/resources/images/plate1_E01_T0001F001L01A03Z01C03.tif,sha256=Pbhk7xn-KUP6RSIhJsxQcrHFImBm3GEpLkzx7WOc-5M,7958528
104
+ spacr-0.9.0.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
105
+ spacr-0.9.0.dist-info/METADATA,sha256=mk6s6xqwjy95ZgAc3fxWVNAoK_XsAceqHtB6e2PaRwE,6208
106
+ spacr-0.9.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
107
+ spacr-0.9.0.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
108
+ spacr-0.9.0.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
109
+ spacr-0.9.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.2.0)
2
+ Generator: setuptools (72.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,18 +0,0 @@
1
- config/
2
- *.log
3
- *.ipynb
4
- *.ipynb_checkpoints/
5
- __pycache__/
6
- results/
7
- weights/
8
- wandb/
9
- data/
10
- submissions/
11
- /.vscode
12
- *.npy
13
- *.pth
14
- *.sh
15
- *.json
16
- *.out
17
- *.zip
18
- *.tiff
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2022 opcrisis
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.