spacr 0.4.3__py3-none-any.whl → 0.4.4__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.
spacr/core.py CHANGED
@@ -33,9 +33,15 @@ def preprocess_generate_masks(settings):
33
33
 
34
34
  print(f'Processing folder: {source_folder}')
35
35
 
36
+ source_folder = format_path_for_system(source_folder)
37
+ settings['src'] = source_folder
38
+ src = source_folder
39
+ settings = set_default_settings_preprocess_generate_masks(settings)
40
+
36
41
  if settings['metadata_type'] == 'auto':
37
- if settings['custom_regex'] == None:
42
+ if settings['custom_regex'] != None:
38
43
  try:
44
+ print(f"using regex: {settings['custom_regex']}")
39
45
  convert_separate_files_to_yokogawa(folder=source_folder, regex=settings['custom_regex'])
40
46
  except:
41
47
  try:
@@ -52,11 +58,6 @@ def preprocess_generate_masks(settings):
52
58
  print(f'Error: {e}')
53
59
  return
54
60
 
55
- source_folder = format_path_for_system(source_folder)
56
- settings['src'] = source_folder
57
- src = source_folder
58
- settings = set_default_settings_preprocess_generate_masks(settings)
59
-
60
61
  if settings['cell_channel'] is None and settings['nucleus_channel'] is None and settings['pathogen_channel'] is None:
61
62
  print(f'Error: At least one of cell_channel, nucleus_channel or pathogen_channel must be defined')
62
63
  return
spacr/io.py CHANGED
@@ -647,7 +647,7 @@ def load_images_from_paths(images_by_key):
647
647
 
648
648
  return images_dict
649
649
 
650
- #@log_function_call
650
+ #@log_function_call
651
651
  def _rename_and_organize_image_files(src, regex, batch_size=100, pick_slice=False, skip_mode='01', metadata_type='', img_format='.tif'):
652
652
  """
653
653
  Convert z-stack images to maximum intensity projection (MIP) images.
@@ -664,13 +664,16 @@ def _rename_and_organize_image_files(src, regex, batch_size=100, pick_slice=Fals
664
664
  None
665
665
  """
666
666
 
667
+ if isinstance(img_format, str):
668
+ img_format = [img_format]
669
+
667
670
  from .utils import _extract_filename_metadata, print_progress
668
671
 
669
672
  regular_expression = re.compile(regex)
670
673
  stack_path = os.path.join(src, 'stack')
671
674
  files_processed = 0
672
675
  if not os.path.exists(stack_path) or (os.path.isdir(stack_path) and len(os.listdir(stack_path)) == 0):
673
- all_filenames = [filename for filename in os.listdir(src) if filename.endswith(img_format)]
676
+ all_filenames = [filename for filename in os.listdir(src) if any(filename.endswith(ext) for ext in img_format)]
674
677
  print(f'All files: {len(all_filenames)} in {src}')
675
678
  time_ls = []
676
679
  image_paths_by_key = _extract_filename_metadata(all_filenames, src, regular_expression, metadata_type, pick_slice, skip_mode)
@@ -729,11 +732,11 @@ def _rename_and_organize_image_files(src, regex, batch_size=100, pick_slice=Fals
729
732
  images_by_key.clear()
730
733
 
731
734
  # Move original images to a new directory
732
- valid_exts = [img_format]
733
735
  newpath = os.path.join(src, 'orig')
734
736
  os.makedirs(newpath, exist_ok=True)
735
737
  for filename in os.listdir(src):
736
- if os.path.splitext(filename)[1] in valid_exts:
738
+ #print(f"{filename}: {os.path.splitext(filename)[1]}")
739
+ if os.path.splitext(filename)[1] in img_format:
737
740
  move = os.path.join(newpath, filename)
738
741
  if os.path.exists(move):
739
742
  print(f'WARNING: A file with the same name already exists at location {move}')
@@ -1628,6 +1631,7 @@ def preprocess_img_data(settings):
1628
1631
  if timelapse:
1629
1632
  _move_to_chan_folder(src, regex, timelapse, metadata_type)
1630
1633
  else:
1634
+ img_format = ['.tif', '.tiff', '.png', '.jpg', '.jpeg', '.bmp', '.nd2', '.czi', '.lif']
1631
1635
  _rename_and_organize_image_files(src, regex, batch_size, pick_slice, skip_mode, metadata_type, img_format)
1632
1636
 
1633
1637
  #Make sure no batches will be of only one image
@@ -3105,6 +3109,7 @@ def generate_dataset_from_lists(dst, class_data, classes, test_split=0.1):
3105
3109
  return os.path.join(dst, 'train'), os.path.join(dst, 'test')
3106
3110
 
3107
3111
  def convert_separate_files_to_yokogawa(folder, regex):
3112
+
3108
3113
  ROWS = "ABCDEFGHIJKLMNOP"
3109
3114
  COLS = [f"{i:02d}" for i in range(1, 25)]
3110
3115
  WELLS = [f"{r}{c}" for r in ROWS for c in COLS]
@@ -3121,13 +3126,13 @@ def convert_separate_files_to_yokogawa(folder, regex):
3121
3126
 
3122
3127
  pattern = re.compile(regex, re.I)
3123
3128
 
3124
- files_by_fov = {}
3129
+ files_by_region = {}
3125
3130
  rename_log = []
3126
3131
  csv_path = os.path.join(folder, "rename_log.csv")
3127
- used_wells = set(os.listdir(folder))
3128
- fov_to_well = {}
3132
+ used_wells = set()
3133
+ region_to_well = {}
3129
3134
 
3130
- # Group files by FOV
3135
+ # Group files by (plateID, wellID, fieldID, timeID, chanID)
3131
3136
  for file in os.listdir(folder):
3132
3137
  match = pattern.match(file)
3133
3138
  if not match:
@@ -3136,37 +3141,63 @@ def convert_separate_files_to_yokogawa(folder, regex):
3136
3141
 
3137
3142
  meta = match.groupdict()
3138
3143
 
3139
- # Extract required metadata
3140
- fov = meta['fov']
3141
- channel = int(meta['channel'])
3144
+ # Mandatory metadata
3145
+ if 'wellID' not in meta or meta['wellID'] is None:
3146
+ print(f"Skipping {file}: missing mandatory wellID.")
3147
+ continue
3148
+ wellID = meta['wellID']
3142
3149
 
3143
3150
  # Optional metadata with defaults
3144
- time = int(meta.get('time', 1))
3145
- z_slice = int(meta.get('slice', 1))
3146
-
3147
- files_by_fov.setdefault(fov, []).append((file, channel, time, z_slice))
3148
-
3149
- # Assign wells per FOV
3150
- for fov, file_list in files_by_fov.items():
3151
- if fov not in fov_to_well:
3152
- fov_to_well[fov] = _get_next_well(used_wells)
3153
- used_wells.add(fov_to_well[fov])
3154
-
3155
- well = fov_to_well[fov]
3151
+ plateID = meta.get('plateID', '1') or '1'
3152
+ fieldID = meta.get('fieldID', '1') or '1'
3153
+ timeID = int(meta.get('timeID', 1) or 1)
3154
+ chanID = int(meta.get('chanID', 1) or 1)
3155
+ sliceID = meta.get('sliceID')
3156
+ sliceID = int(sliceID) if sliceID is not None else None
3157
+
3158
+ region_key = (plateID, wellID, fieldID, timeID, chanID)
3159
+
3160
+ files_by_region.setdefault(region_key, []).append((file, sliceID))
3161
+
3162
+ # Assign wells and process files per region
3163
+ for region, file_list in files_by_region.items():
3164
+ if region[:3] not in region_to_well:
3165
+ next_well = _get_next_well(used_wells)
3166
+ region_to_well[region[:3]] = next_well
3167
+ used_wells.add(next_well)
3168
+
3169
+ assigned_well = region_to_well[region[:3]]
3170
+ plateID, wellID, fieldID, timeID, chanID = region
3171
+
3172
+ # Check if multiple slices exist and are meaningful
3173
+ slice_ids = [sid for _, sid in file_list if sid is not None]
3174
+ unique_slices = set(slice_ids)
3175
+
3176
+ images = []
3177
+ for filename, _ in sorted(file_list, key=lambda x: x[1] or 1):
3178
+ img = tifffile.imread(os.path.join(folder, filename))
3179
+ images.append(img)
3180
+
3181
+ # Perform MIP only if multiple unique slices are present
3182
+ if len(unique_slices) > 1:
3183
+ img_to_save = np.max(np.stack(images), axis=0)
3184
+ else:
3185
+ img_to_save = images[0]
3156
3186
 
3157
- for original_file, channel, time, z_slice in file_list:
3158
- img = tifffile.imread(os.path.join(folder, original_file))
3159
- dtype = img.dtype
3187
+ dtype = img_to_save.dtype
3160
3188
 
3161
- filename = f"{well}_T{time:04d}F001L01C{channel:02d}Z{z_slice:03d}.tif"
3162
- filepath = os.path.join(folder, filename)
3163
- tifffile.imwrite(filepath, img.astype(dtype))
3189
+ new_filename = f"{assigned_well}_T{timeID:04d}F{int(fieldID):03d}L01C{chanID:02d}.tif"
3190
+ new_filepath = os.path.join(folder, new_filename)
3191
+ tifffile.imwrite(new_filepath, img_to_save.astype(dtype))
3164
3192
 
3165
- rename_log.append({"Original File": original_file, "Renamed TIFF": filename})
3193
+ # Log original filenames involved in MIP or single file rename
3194
+ original_files = ";".join(f[0] for f in file_list)
3195
+ rename_log.append({"Original File(s)": original_files, "Renamed TIFF": new_filename})
3166
3196
 
3167
3197
  pd.DataFrame(rename_log).to_csv(csv_path, index=False)
3168
3198
  print(f"Processing complete. Files saved in {folder} and rename log saved as {csv_path}.")
3169
3199
 
3200
+
3170
3201
  def convert_to_yokogawa(folder):
3171
3202
  """
3172
3203
  Detects file type in the folder and converts them
spacr/settings.py CHANGED
@@ -1213,16 +1213,25 @@ def generate_fields(variables, scrollable_frame):
1213
1213
  "black_background": "(bool) - Whether to use a black background for plots.",
1214
1214
  "calculate_correlation": "(bool) - Whether to calculate correlations between features.",
1215
1215
  "cell_CP_prob": "(float) - The cellpose probability threshold for the cell channel. This will be used in cell segmentation.",
1216
+ "nucleus_CP_prob": "(float) - The cellpose probability threshold for the nucleus channel. This will be used in cell segmentation.",
1217
+ "pathogen_CP_prob": "(float) - The cellpose probability threshold for the pathogen channel. This will be used in cell segmentation.",
1216
1218
  "cell_FT": "(float) - The flow threshold for cell objects. This will be used to segment the cells.",
1217
- "cell_background": "(float) - The background intensity for the cell channel. This will be used to remove background noise.",
1219
+ "nucleus_FT": "(float) - The flow threshold for nucleus objects. This will be used to segment the cells.",
1220
+ "pathogen_FT": "(float) - The flow threshold for pathogen objects. This will be used to segment the cells.",
1221
+ "cell_background": "(int) - The background intensity for the cell channel. This will be used to remove background noise.",
1222
+ "nucleus_background": "(int) - The background intensity for the nucleus channel. This will be used to remove background noise.",
1223
+ "pathogen_background": "(int) - The background intensity for the pathogen channel. This will be used to remove background noise.",
1218
1224
  "cell_chann_dim": "(int) - Dimension of the channel to use for cell segmentation.",
1219
- "cell_channel": "(int) - The channel to use for the cell. If None, the cell will not be segmented.",
1225
+ "cell_channel": "(int) - The channel to use for generatin cell masks. If None, cell masks will not be generated.",
1226
+ "nucleus_channel": "(int) - The channel to use for generatin nucleus masks. If None, nucleus masks will not be generated.",
1227
+ "pathogen_channel": "(int) - The channel to use for generatin pathogen masks. If None, pathogen masks will not be generated.",
1220
1228
  "cell_intensity_range": "(list) - Intensity range for cell segmentation.",
1221
1229
  "cell_loc": "(list) - The locations of the cell types in the images.",
1222
- "cell_mask_dim": "(int) - The dimension of the array the cell mask is saved in.",
1230
+ "cell_mask_dim": "(int) - The dimension of the array the cell mask is saved in (array order:channels,cell, nucleus, pathogen, cytoplasm) array starts at dimension 0.",
1231
+ "nucleus_mask_dim": "(int) - The dimension of the array the nucleus mask is saved in (array order:channels,cell, nucleus, pathogen, cytoplasm) array starts at dimension 0.",
1223
1232
  "cell_min_size": "(int) - The minimum size of cell objects in pixels^2.",
1224
1233
  "cell_plate_metadata": "(str) - Metadata for the cell plate.",
1225
- "cell_Signal_to_noise": "(float) - The signal-to-noise ratio for the cell channel. This will be used to determine the range of intensities to normalize images to for cell segmentation.",
1234
+ "cell_Signal_to_noise": "(int) - The signal-to-noise ratio for the cell channel. This will be used to determine the range of intensities to normalize images to for cell segmentation.",
1226
1235
  "cell_size_range": "(list) - Size range for cell segmentation.",
1227
1236
  "cell_types": "(list) - Types of cells to include in the analysis.",
1228
1237
  "cells": "(list of lists) - The cell types to include in the analysis.",
@@ -1240,10 +1249,13 @@ def generate_fields(variables, scrollable_frame):
1240
1249
  "CP_prob": "(float) - Cellpose probability threshold for segmentation.",
1241
1250
  "crop_mode": "(str) - Mode to use for cropping images (cell, nucleus, pathogen, cytoplasm).",
1242
1251
  "custom_model": "(str) - Path to a custom Cellpose model.",
1243
- "custom_regex": "(str) - Custom regex pattern to extract metadata from the image names. This will only be used if 'custom' is selected for 'metadata_type'.",
1252
+ "custom_regex": "(str) - Custom regex pattern to extract metadata from the image names. This will only be used if 'custom' or 'auto' is selected for 'metadata_type'.",
1244
1253
  "cytoplasm": "(bool) - Whether to segment the cytoplasm (Cell - Nucleus + Pathogen).",
1245
1254
  "cytoplasm_min_size": "(int) - The minimum size of cytoplasm objects in pixels^2.",
1255
+ "nucleus_min_size": "(int) - The minimum size of nucleus objects in pixels^2.",
1256
+ "normalize_by": "(str) - Normalize cropped png images by png or by field of view.",
1246
1257
  "dependent_variable": "(str) - The dependent variable for the regression analysis.",
1258
+ "delete_intermediate": "(bool) - Delete intermediate folders (stack, channel, norm_channel_stack).",
1247
1259
  "diameter": "(float) - Diameter of the objects to segment.",
1248
1260
  "dialate_png_ratios": "(list) - The ratios to use for dilating the PNG images. This will determine the amount of dilation applied to the images before cropping.",
1249
1261
  "dialate_pngs": "(bool) - Whether to dilate the PNG images before saving.",
@@ -1291,7 +1303,7 @@ def generate_fields(variables, scrollable_frame):
1291
1303
  "manders_thresholds": "(list) - Thresholds for Manders' coefficients.",
1292
1304
  "mask": "(bool) - Whether to generate masks for the segmented objects. If True, masks will be generated for the nucleus, cell, and pathogen.",
1293
1305
  "measurement": "(str) - The measurement to use for the analysis.",
1294
- "metadata_type": "(str) - Type of metadata to expect in the images. This will determine how the images are processed. If 'custom' is selected, you can provide a custom regex pattern to extract metadata from the image names.",
1306
+ "metadata_type": "(str) - Type of metadata to expect in the images. If 'custom' is selected, you can provide a custom regex pattern to extract metadata from the image names. auto will attempt to automatically extract metadata from the image names. cellvoyager and cq1 will use the default metadata extraction for CellVoyager and CQ1 images.",
1295
1307
  "metadata_types": "(list) - Types of metadata to include in the analysis.",
1296
1308
  "merge_edge_pathogen_cells": "(bool) - Whether to merge cells that share pathogen objects.",
1297
1309
  "merge_pathogens": "(bool) - Whether to merge pathogen objects that share more than 75 percent of their perimeter.",
@@ -1312,7 +1324,8 @@ def generate_fields(variables, scrollable_frame):
1312
1324
  "n_jobs": "(int) - The number of n_jobs to use for processing the images. This will determine how many images are processed in parallel. Increase to speed up processing.",
1313
1325
  "n_neighbors": "(int) - Number of neighbors for UMAP.",
1314
1326
  "n_repeats": "(int) - Number of repeats for the pathogen plate.",
1315
- "pathogen_Signal_to_noise": "(float) - The signal-to-noise ratio for the pathogen channel. This will be used to determine the range of intensities to normalize images to for pathogen segmentation.",
1327
+ "pathogen_Signal_to_noise": "(int) - The signal-to-noise ratio for the pathogen channel. This will be used to determine the range of intensities to normalize images to for pathogen segmentation.",
1328
+ "nucleus_Signal_to_noise": "(int) - The signal-to-noise ratio for the nucleus channel. This will be used to determine the range of intensities to normalize images to for nucleus segmentation.",
1316
1329
  "pathogen_size_range": "(list) - Size range for pathogen segmentation.",
1317
1330
  "pathogen_types": "(list) - Types of pathogens to include in the analysis.",
1318
1331
  "pc": "(str) - Positive control identifier.",
@@ -1359,10 +1372,11 @@ def generate_fields(variables, scrollable_frame):
1359
1372
  "save_measurements": "(bool) - Whether to save the measurements to disk.",
1360
1373
  "save_png": "(bool) - Whether to save the segmented objects as PNG images.",
1361
1374
  "schedule": "(str) - Schedule for processing the data.",
1362
- "Signal_to_noise": "(float) - Signal-to-noise ratio for the images.",
1375
+ "Signal_to_noise": "(int) - Signal-to-noise ratio for the images.",
1363
1376
  "skip_mode": "(str) - The mode to use for skipping images. This will determine how to handle images that cannot be processed.",
1364
1377
  "smooth_lines": "(bool) - Whether to smooth lines in the plots.",
1365
1378
  "src": "(str, path) - Path to source directory.",
1379
+ "segmentation_mode": "(str) - Algorithm to use for segmentation (cellpose or mediar).",
1366
1380
  "target": "(str) - Target variable for the analysis.",
1367
1381
  "target_height": "(int) - Target height for resizing the images.",
1368
1382
  "target_intensity_min": "(float) - Minimum intensity for the target objects.",
@@ -1412,7 +1426,7 @@ def generate_fields(variables, scrollable_frame):
1412
1426
  "masks": "(bool) - Whether to generate masks for the segmented objects.",
1413
1427
  "timelapse": "(bool) - Whether to analyze images as a timelapse.",
1414
1428
  "pathogen_min_size": "(int) - The minimum size of pathogen objects in pixels^2.",
1415
- "pathogen_mask_dim": "(int) - The dimension of the array the pathogen mask is saved in.",
1429
+ "pathogen_mask_dim": "(int) - The dimension of the array the pathogen mask is saved in (array order:channels,cell, nucleus, pathogen, cytoplasm) array starts at dimension 0.",
1416
1430
  "use_bounding_box": "(bool) - Whether to use the bounding box for cropping the images.",
1417
1431
  "plot_points": "(bool) - Whether to plot scatterplot points.",
1418
1432
  "embedding_by_controls": "(bool) - Use the controlls to greate the embedding, then apply this embedding to all of the data.",
@@ -1442,6 +1456,7 @@ def generate_fields(variables, scrollable_frame):
1442
1456
  "shuffle": "(bool) - Shuffle the dataset bufore generating the activation maps",
1443
1457
  "correlation": "(bool) - Calculate correlation between image channels and activation maps. Data is saved to .db.",
1444
1458
  "normalize_input": "(bool) - Normalize the input images before passing them to the model.",
1459
+ "normalize_plots": "(bool) - Normalize images before plotting.",
1445
1460
  }
1446
1461
 
1447
1462
  for key, (var_type, options, default_value) in variables.items():
spacr/utils.py CHANGED
@@ -554,7 +554,7 @@ def _get_cellpose_batch_size():
554
554
  def _extract_filename_metadata(filenames, src, regular_expression, metadata_type='cellvoyager', pick_slice=False, skip_mode='01'):
555
555
 
556
556
  images_by_key = defaultdict(list)
557
-
557
+
558
558
  for filename in filenames:
559
559
  match = regular_expression.match(filename)
560
560
  if match:
@@ -597,7 +597,7 @@ def _extract_filename_metadata(filenames, src, regular_expression, metadata_type
597
597
  except IndexError:
598
598
  print(f"Could not extract information from filename {filename} using provided regex")
599
599
  else:
600
- print(f"Filename {filename} did not match provided regex")
600
+ print(f"Filename {filename} did not match provided regex: {regular_expression}")
601
601
  continue
602
602
 
603
603
  return images_by_key
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spacr
3
- Version: 0.4.3
3
+ Version: 0.4.4
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
@@ -9,13 +9,13 @@ spacr/app_sequencing.py,sha256=DjG26jy4cpddnV8WOOAIiExtOe9MleVMY4MFa5uTo5w,157
9
9
  spacr/app_umap.py,sha256=ZWAmf_OsIKbYvolYuWPMYhdlVe-n2CADoJulAizMiEo,153
10
10
  spacr/cellpose.py,sha256=RBHMs2vwXcfkj0xqAULpALyzJYXddSRycgZSzmwI7v0,14755
11
11
  spacr/chat_bot.py,sha256=n3Fhqg3qofVXHmh3H9sUcmfYy9MmgRnr48663MVdY9E,1244
12
- spacr/core.py,sha256=2VPM-nemOoYI3dbDudsvFGg4F_y2OlCcXKos5vWNKeU,50422
12
+ spacr/core.py,sha256=KYPG28Z-AX1nzZ2Fd6F5RrBU_canp_vyEzZINLYpElw,50496
13
13
  spacr/deep_spacr.py,sha256=WN64EaQqF87JZg3Uan46t5Y28xsAGD2KMjr2ht6CyDs,54563
14
14
  spacr/gui.py,sha256=ARyn9Q_g8HoP-cXh1nzMLVFCKqthY4v2u9yORyaQqQE,8230
15
15
  spacr/gui_core.py,sha256=qMHQPY7LZEKQ5c7dIQtRyVBy03xNmwYWO8S85btVeEw,60170
16
16
  spacr/gui_elements.py,sha256=Or38I_X9-lJRsyIAtbEfZPXzls0IORagf7vEe6IlI5Y,152647
17
17
  spacr/gui_utils.py,sha256=dWVPFwDj793Z3ERG4mMC0hI0MKkOrvXJpUYlcjpCBsU,41357
18
- spacr/io.py,sha256=R_cIPJYzzd1clpQ3mpYOXaSLPYsaU7apx1739RC27Dw,147018
18
+ spacr/io.py,sha256=bkpBQiLsd69w4GpvrY2NNbZbqHfuRCrbjELlkXBIok8,148414
19
19
  spacr/logger.py,sha256=lJhTqt-_wfAunCPl93xE65Wr9Y1oIHJWaZMjunHUeIw,1538
20
20
  spacr/measure.py,sha256=Z3u4BU5RzcY82IZuboQ0OsxuXaPVwOlH65Rw6FrL5z4,55045
21
21
  spacr/mediar.py,sha256=FwLvbLQW5LQzPgvJZG8Lw7GniA2vbZx6Jv6vIKu7I5c,14743
@@ -23,14 +23,14 @@ spacr/ml.py,sha256=MrIAtUUxMOibWVL1SjCUnYlizawCp3l3SeY4Y9yEsPw,97251
23
23
  spacr/openai.py,sha256=5vBZ3Jl2llYcW3oaTEXgdyCB2aJujMUIO5K038z7w_A,1246
24
24
  spacr/plot.py,sha256=Q5TbsR2NUWhA7z4HyF_2_FAEBFSNMU-G3UNDbRzW6mM,169485
25
25
  spacr/sequencing.py,sha256=ClUfwPPK6rNUbUuiEkzcwakzVyDKKUMv9ricrxT8qQY,25227
26
- spacr/settings.py,sha256=72bhOwr0U83uoWwaKtSNZucYhpgwTP1_GItRk9f6A6c,87592
26
+ spacr/settings.py,sha256=mEei8vZXMtUXVRliLGHEXbNWqgrFXA6AX3Tv6s4RmUY,89796
27
27
  spacr/sim.py,sha256=1xKhXimNU3ukzIw-3l9cF3Znc_brW8h20yv8fSTzvss,71173
28
28
  spacr/sp_stats.py,sha256=mbhwsyIqt5upsSD346qGjdCw7CFBa0tIS7zHU9e0jNI,9536
29
29
  spacr/stats.py,sha256=mbhwsyIqt5upsSD346qGjdCw7CFBa0tIS7zHU9e0jNI,9536
30
30
  spacr/submodules.py,sha256=jFlJeVNuIEf63TtCOpTlOZ4iiSLr238kRBiGAAAgKE4,67626
31
31
  spacr/timelapse.py,sha256=KGfG4L4-QnFfgbF7L6C5wL_3gd_rqr05Foje6RsoTBg,39603
32
32
  spacr/toxo.py,sha256=TmuhejSIPLBvsgeblsUgSvBFCR1gOkApyTKidooJ5Us,26044
33
- spacr/utils.py,sha256=v13vzgEQwUnQAtQya_akKIkem26-0Nn5j9uhx_NcJXQ,228599
33
+ spacr/utils.py,sha256=jjNCA3O7nF-Y_2c2OsAkAm5WdyD1SZ6eqV7PI3WcLdo,228617
34
34
  spacr/version.py,sha256=axH5tnGwtgSnJHb5IDhiu4Zjk5GhLyAEDRe-rnaoFOA,409
35
35
  spacr/resources/MEDIAR/.gitignore,sha256=Ff1q9Nme14JUd-4Q3jZ65aeQ5X4uttptssVDgBVHYo8,152
36
36
  spacr/resources/MEDIAR/LICENSE,sha256=yEj_TRDLUfDpHDNM0StALXIt6mLqSgaV2hcCwa6_TcY,1065
@@ -153,9 +153,9 @@ spacr/resources/icons/umap.png,sha256=dOLF3DeLYy9k0nkUybiZMe1wzHQwLJFRmgccppw-8b
153
153
  spacr/resources/images/plate1_E01_T0001F001L01A01Z01C02.tif,sha256=Tl0ZUfZ_AYAbu0up_nO0tPRtF1BxXhWQ3T3pURBCCRo,7958528
154
154
  spacr/resources/images/plate1_E01_T0001F001L01A02Z01C01.tif,sha256=m8N-V71rA1TT4dFlENNg8s0Q0YEXXs8slIn7yObmZJQ,7958528
155
155
  spacr/resources/images/plate1_E01_T0001F001L01A03Z01C03.tif,sha256=Pbhk7xn-KUP6RSIhJsxQcrHFImBm3GEpLkzx7WOc-5M,7958528
156
- spacr-0.4.3.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
157
- spacr-0.4.3.dist-info/METADATA,sha256=IAsmOAnJO0zAZ1eMw6KDX2IjKA5w4poSFur3-7GDcMs,6095
158
- spacr-0.4.3.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
159
- spacr-0.4.3.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
160
- spacr-0.4.3.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
161
- spacr-0.4.3.dist-info/RECORD,,
156
+ spacr-0.4.4.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
157
+ spacr-0.4.4.dist-info/METADATA,sha256=EhQ8CvDWMbq7bJ18Pt_cAcz2uiRz1X7PH5gzwZdw5gw,6095
158
+ spacr-0.4.4.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
159
+ spacr-0.4.4.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
160
+ spacr-0.4.4.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
161
+ spacr-0.4.4.dist-info/RECORD,,
File without changes
File without changes