small-fish-gui 1.3.5__py3-none-any.whl → 1.4.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.
@@ -0,0 +1,65 @@
1
+ List of keys for batch 'values' dict instance :
2
+
3
+ Batch_folder
4
+ 0
5
+ image path
6
+ 3D stack
7
+ multichannel
8
+ Dense regions deconvolution
9
+ Cluster computation
10
+ Segmentation
11
+ Napari correction
12
+ x
13
+ y
14
+ z
15
+ c
16
+ t
17
+ cyto_model_name
18
+ cytoplasm channel
19
+ cytoplasm diameter
20
+ nucleus_model_name
21
+ nucleus channel
22
+ nucleus diameter
23
+ Segment only nuclei
24
+ show segmentation
25
+ saving path
26
+ filename
27
+ threshold
28
+ threshold penalty
29
+ channel to compute
30
+ voxel_size_z
31
+ voxel_size_y
32
+ voxel_size_x
33
+ spot_size_z
34
+ spot_size_y
35
+ spot_size_x
36
+ log_kernel_size_z
37
+ log_kernel_size_y
38
+ log_kernel_size_x
39
+ minimum_distance_z
40
+ minimum_distance_y
41
+ minimum_distance_x
42
+ nucleus channel signal
43
+ alpha
44
+ beta
45
+ gamma
46
+ deconvolution_kernel_z
47
+ deconvolution_kernel_y
48
+ deconvolution_kernel_x
49
+ cluster size
50
+ min number of spots
51
+ Interactive threshold selector
52
+ spots_extraction_folder
53
+ spots_filename
54
+ do_spots_csv
55
+ do_spots_excel
56
+ do_spots_feather
57
+ output_folder
58
+ batch_name
59
+ save segmentation
60
+ save detection
61
+ extract spots
62
+ csv
63
+ xlsx
64
+ feather
65
+ 2
@@ -10,21 +10,30 @@ WAITING_TEXT = [
10
10
 
11
11
  def add_default_loading(funct) :
12
12
  def inner(*args,**kwargs) :
13
- random_text = np.random.randint(0,len(WAITING_TEXT))
14
- waiting_layout = [
15
- [sg.Text(WAITING_TEXT[random_text], font= '10')]
16
- ]
17
- window = sg.Window(
18
- title= 'small_fish',
19
- layout= waiting_layout,
20
- grab_anywhere= True,
21
- finalize=True
22
- )
23
-
24
- window.read(timeout= 30, close= False)
25
- try :
13
+
14
+ hide_loading = kwargs.get("hide_loading")
15
+ if 'hide_loading' in kwargs : del kwargs['hide_loading']
16
+
17
+ if not hide_loading :
18
+ random_text = np.random.randint(0,len(WAITING_TEXT))
19
+ waiting_layout = [
20
+ [sg.Text(WAITING_TEXT[random_text], font= '10')]
21
+ ]
22
+ window = sg.Window(
23
+ title= 'small_fish',
24
+ layout= waiting_layout,
25
+ grab_anywhere= True,
26
+ finalize=True
27
+ )
28
+
29
+ window.read(timeout= 30, close= False)
30
+ try :
31
+ return funct(*args, **kwargs)
32
+ finally :
33
+ window.close()
34
+
35
+ else :
26
36
  return funct(*args, **kwargs)
27
- finally :
28
- window.close()
37
+
29
38
  return inner
30
39
 
@@ -246,7 +246,12 @@ def _detection_layout(
246
246
  unit = {'voxel_size' : 'nm', 'minimum_distance' : 'nm', 'spot_size' : 'radius(nm)', 'log_kernel_size' : 'px'}
247
247
 
248
248
  layout += tuple_layout(opt=opt, unit=unit, default_dict=default_dict, voxel_size= tuple_shape, spot_size= tuple_shape, log_kernel_size= tuple_shape, minimum_distance= tuple_shape)
249
-
249
+
250
+ if (do_segmentation and is_multichannel) or (is_multichannel and segmentation_done):
251
+ default_segmentation = [default_dict.setdefault('nucleus channel signal', default_dict.setdefault('nucleus channel',0))]
252
+ layout += [[sg.Text("nucleus channel signal "), sg.InputText(default_text=default_segmentation, key= "nucleus channel signal", size= 5, tooltip= "Channel from which signal will be measured for nucleus features, \nallowing you to measure signal from a different channel than the one used for segmentation.")]]
253
+ # layout += parameters_layout(['nucleus channel signal'], default_values=default_segmentation) + [[sg.Text("Channel from which signal will be measured for nucleus features, allowing you to measure signal from a different channel than the one used for segmentation.")]]
254
+
250
255
  #Deconvolution
251
256
  if do_dense_region_deconvolution :
252
257
  default_dense_regions_deconvolution = [default_dict.setdefault('alpha',0.5), default_dict.setdefault('beta',1)]
@@ -259,9 +264,7 @@ def _detection_layout(
259
264
  layout += parameters_layout(['cluster size'], unit="radius(nm)", default_values=[default_dict.setdefault('cluster size',400)])
260
265
  layout += parameters_layout(['min number of spots'], default_values=[default_dict.setdefault('min number of spots', 5)])
261
266
 
262
- if (do_segmentation and is_multichannel) or (is_multichannel and segmentation_done):
263
- default_segmentation = [default_dict.setdefault('nucleus channel signal', default_dict.setdefault('nucleus channel',0))]
264
- layout += parameters_layout(['nucleus channel signal'], default_values=default_segmentation) + [[sg.Text(" channel from which signal will be measured for nucleus features.")]]
267
+
265
268
 
266
269
  layout += bool_layout(['Interactive threshold selector'], preset=[False])
267
270
  layout += path_layout(
@@ -300,7 +300,7 @@ def hub_prompt(fov_results, do_segmentation=False) :
300
300
  layout = [
301
301
  [sg.Text('RESULTS', font= 'bold 13')],
302
302
  [sg.Table(values= list(sumup_df.values), headings= list(sumup_df.columns), row_height=20, num_rows= 5, vertical_scroll_only=False, key= "result_table"), segmentation_object],
303
- [sg.Button('Add detection'), sg.Button('Compute colocalisation')],#, sg.Button('Batch detection')],
303
+ [sg.Button('Add detection'), sg.Button('Compute colocalisation'), sg.Button('Batch detection')],
304
304
  [sg.Button('Save results', button_color= 'green'), sg.Button('Delete acquisitions',button_color= 'gray'), sg.Button('Reset segmentation',button_color= 'gray'), sg.Button('Reset results',button_color= 'gray')]
305
305
  # [sg.Button('Save results', button_color= 'green'), sg.Button('Reset results',button_color= 'gray')]
306
306
  ]
@@ -333,7 +333,7 @@ def ask_detection_confirmation(used_threshold) :
333
333
  [sg.Button("Ok"), sg.Button("Restart detection")]
334
334
  ]
335
335
 
336
- event, value = prompt(layout, add_ok_cancel=False)
336
+ event, value = prompt(layout, add_ok_cancel=False, add_scrollbar=False)
337
337
 
338
338
  if event == 'Restart detection' :
339
339
  return False
@@ -346,7 +346,7 @@ def ask_cancel_detection() :
346
346
  [sg.Button("Yes"), sg.Button("No")]
347
347
  ]
348
348
 
349
- event, value = prompt(layout, add_ok_cancel=False)
349
+ event, value = prompt(layout, add_ok_cancel=False, add_scrollbar=False)
350
350
 
351
351
  if event == 'No' :
352
352
  return False
@@ -10,9 +10,11 @@ def _cast_spot_to_tuple(spot) :
10
10
  def _cast_spots_to_tuple(spots) :
11
11
  return tuple(list(map(_cast_spot_to_tuple, spots)))
12
12
 
13
- def write_results(dataframe: pd.DataFrame, path:str, filename:str, do_excel= True, do_feather= False, do_csv=False) :
13
+ def write_results(dataframe: pd.DataFrame, path:str, filename:str, do_excel= True, do_feather= False, do_csv=False, overwrite=False) :
14
14
  check_parameter(dataframe= pd.DataFrame, path= str, filename = str, do_excel = bool, do_feather = bool)
15
15
 
16
+ dataframe.columns = dataframe.columns.astype(str) # assert columns header are string for feather
17
+
16
18
  if len(dataframe) == 0 : return True
17
19
  if not do_excel and not do_feather and not do_csv :
18
20
  return False
@@ -23,9 +25,11 @@ def write_results(dataframe: pd.DataFrame, path:str, filename:str, do_excel= Tru
23
25
 
24
26
  new_filename = filename
25
27
  i= 1
26
- while new_filename + '.xlsx' in os.listdir(path) or new_filename + '.feather' in os.listdir(path) or new_filename + '.csv' in os.listdir(path) :
27
- new_filename = filename + '_{0}'.format(i)
28
- i+=1
28
+
29
+ if not overwrite :
30
+ while new_filename + '.xlsx' in os.listdir(path) or new_filename + '.feather' in os.listdir(path) or new_filename + '.csv' in os.listdir(path) :
31
+ new_filename = filename + '_{0}'.format(i)
32
+ i+=1
29
33
 
30
34
  if 'image' in dataframe.columns :
31
35
  dataframe = dataframe.drop(['image'], axis=1)
@@ -0,0 +1,21 @@
1
+ """
2
+ Module containing main pipeline for user mode as well as calls for pipeline functions.
3
+ """
4
+
5
+ from ._preprocess import reorder_shape
6
+ from ._preprocess import reorder_image_stack
7
+ from ._preprocess import prepare_image_detection
8
+ from ._preprocess import convert_parameters_types
9
+
10
+ from ._segmentation import launch_segmentation
11
+ from ._segmentation import _cast_segmentation_parameters
12
+ from ._segmentation import cell_segmentation
13
+ from ._segmentation import plot_segmentation
14
+
15
+ from .detection import launch_detection
16
+ from .detection import launch_features_computation
17
+ from .detection import launch_cell_extraction
18
+ from .detection import get_nucleus_signal
19
+ from .detection import output_spot_tiffvisual
20
+
21
+ from .spots import launch_spots_extraction
@@ -67,7 +67,7 @@ def map_channels(user_parameters) :
67
67
  multichannel = user_parameters['multichannel']
68
68
 
69
69
  try :
70
- map = _auto_map_channels(image, is_3D_stack, is_time_stack, multichannel)
70
+ map = _auto_map_channels(is_3D_stack, is_time_stack, multichannel, image=image)
71
71
  except MappingError as e :
72
72
  sg.popup("Automatic dimension mapping went wrong. Please indicate manually dimensions positions in the array.")
73
73
  map = _ask_channel_map(image.shape, is_3D_stack, is_time_stack, multichannel, preset_map= e.get_map())
@@ -77,8 +77,9 @@ def map_channels(user_parameters) :
77
77
 
78
78
  return map
79
79
 
80
- def _auto_map_channels(image: np.ndarray, is_3D_stack, is_time_stack, multichannel) :
81
- shape = image.shape
80
+ def _auto_map_channels(is_3D_stack, is_time_stack, multichannel, image: np.ndarray=None, shape=None) :
81
+ if type(shape) == type(None) :
82
+ shape = image.shape
82
83
  reducing_list = list(shape)
83
84
 
84
85
  #Set the biggest dimension to y
@@ -194,8 +195,8 @@ def convert_parameters_types(values:dict) :
194
195
  else : values[tuple_parameter] = tuple_values
195
196
 
196
197
  #Parameters
197
- int_list = ['threshold', 'channel_to_compute', 'min number of spots', 'cluster size','nucleus channel signal']
198
- float_list = ['time_step', 'alpha', 'beta', 'gamma', 'threshold penalty']
198
+ int_list = ['threshold', 'channel_to_compute', 'channel to compute', 'min number of spots', 'cluster size','nucleus channel signal']
199
+ float_list = ['alpha', 'beta', 'gamma', 'threshold penalty']
199
200
 
200
201
  for parameter in int_list :
201
202
  try :
@@ -213,7 +214,15 @@ def convert_parameters_types(values:dict) :
213
214
 
214
215
  return values
215
216
 
216
- def check_integrity(values: dict, do_dense_region_deconvolution, multichannel,segmentation_done, map, shape):
217
+ def check_integrity(
218
+ values: dict,
219
+ do_dense_region_deconvolution,
220
+ do_clustering,
221
+ multichannel,
222
+ segmentation_done,
223
+ map,
224
+ shape
225
+ ):
217
226
  """
218
227
  Checks that parameters given in input by user are fit to be used for bigfish detection.
219
228
  """
@@ -233,10 +242,22 @@ def check_integrity(values: dict, do_dense_region_deconvolution, multichannel,se
233
242
  _warning_popup('No gamma found; image will not be denoised before deconvolution.')
234
243
  values['gamma'] = 0
235
244
 
245
+ if values['alpha'] > 1 or values['alpha'] < 0 :
246
+ raise ParameterInputError("alpha must be set between 0 and 1.")
247
+
248
+ if do_clustering :
249
+ if not isinstance(values['min number of spots'], (int)) :
250
+ raise ParameterInputError("Incorrect min spot number parameter.")
251
+ if not isinstance(values['cluster size'], (int)) :
252
+ raise ParameterInputError("Incorrect cluster size parameter.")
253
+
236
254
  #channel
237
255
  if multichannel :
238
256
  ch_len = shape[int(map['c'])]
239
- if segmentation_done :
257
+
258
+ if type(segmentation_done) == type(None) :
259
+ pass
260
+ elif segmentation_done :
240
261
  try : nuc_signal_ch = int(values['nucleus channel signal'])
241
262
  except Exception :
242
263
  raise ParameterInputError("Incorrect channel for nucleus signal measure.")
@@ -259,7 +280,6 @@ def check_integrity(values: dict, do_dense_region_deconvolution, multichannel,se
259
280
 
260
281
  return values
261
282
 
262
-
263
283
  def reorder_shape(shape, map) :
264
284
  x = [int(map['x']),]
265
285
  y = [int(map['y']),]
@@ -275,6 +295,40 @@ def reorder_shape(shape, map) :
275
295
 
276
296
  return new_shape
277
297
 
298
+ def _check_segmentation_parameters(
299
+ user_parameters,
300
+ shape,
301
+ is_multichannel,
302
+ ) :
303
+
304
+ available_channels = list(range(len(shape)))
305
+ do_only_nuc = user_parameters['Segment only nuclei']
306
+ cyto_model_name = user_parameters['cyto_model_name']
307
+ cyto_size = user_parameters['cytoplasm diameter']
308
+ cytoplasm_channel = user_parameters['cytoplasm channel']
309
+ nucleus_model_name = user_parameters['nucleus_model_name']
310
+ nucleus_size = user_parameters['nucleus diameter']
311
+ nucleus_channel = user_parameters['nucleus channel']
312
+
313
+
314
+ if type(cyto_model_name) != str and not do_only_nuc:
315
+ raise ParameterInputError('Invalid cytoplasm model name.')
316
+ if cytoplasm_channel not in available_channels and not do_only_nuc and is_multichannel:
317
+ raise ParameterInputError('For given input image please select channel in {0}\ncytoplasm channel : {1}'.format(available_channels, cytoplasm_channel))
318
+
319
+ if type(cyto_size) not in [int, float] and not do_only_nuc:
320
+ raise ParameterInputError("Incorrect cytoplasm size.")
321
+
322
+ if type(nucleus_model_name) != str :
323
+ raise ParameterInputError('Invalid nucleus model name.')
324
+
325
+ if nucleus_channel not in available_channels and is_multichannel:
326
+ raise ParameterInputError('For given input image please select channel in {0}\nnucleus channel : {1}'.format(available_channels, nucleus_channel))
327
+
328
+ if type(nucleus_size) not in [int, float] :
329
+ raise ParameterInputError("Incorrect nucleus size.")
330
+
331
+
278
332
  def clean_unused_parameters_cache(user_parameters: dict) :
279
333
  """
280
334
  Clean unused parameters that were set to None in previous run.
@@ -351,3 +351,39 @@ def remove_disjoint(image):
351
351
  image_cleaned = image_cleaned.astype(bool)
352
352
 
353
353
  return image_cleaned
354
+
355
+ def plot_segmentation(
356
+ cyto_image : np.ndarray,
357
+ cyto_label : np.ndarray,
358
+ nuc_image : np.ndarray,
359
+ nuc_label : np.ndarray,
360
+ path :str,
361
+ do_only_nuc=False
362
+ ) :
363
+
364
+ if nuc_image.ndim == 3 :
365
+ nuc_image = np.max(nuc_image,axis=0)
366
+
367
+ plot.plot_segmentation_boundary(
368
+ image=nuc_image,
369
+ nuc_label= nuc_label,
370
+ boundary_size= 3,
371
+ contrast=True,
372
+ path_output=path + "_nuclei_segmentation.png",
373
+ show=False,
374
+ )
375
+
376
+
377
+ if not do_only_nuc :
378
+ if cyto_image.ndim == 3 :
379
+ cyto_image = np.max(cyto_image,axis=0)
380
+
381
+ plot.plot_segmentation_boundary(
382
+ image=cyto_image,
383
+ cell_label= cyto_label,
384
+ nuc_label= nuc_label,
385
+ boundary_size= 3,
386
+ contrast=True,
387
+ path_output=path + "_cytoplasm_segmentation.png",
388
+ show=False,
389
+ )
@@ -26,6 +26,7 @@ import bigfish.classification as classification
26
26
  from bigfish.detection.spot_detection import get_object_radius_pixel
27
27
  from types import GeneratorType
28
28
  from skimage.measure import regionprops
29
+ from scipy.ndimage import binary_dilation
29
30
 
30
31
 
31
32
  def ask_input_parameters(ask_for_segmentation=True) :
@@ -282,7 +283,15 @@ def initiate_detection(user_parameters, segmentation_done, map, shape) :
282
283
  if type(user_parameters) == type(None) : return user_parameters
283
284
  try :
284
285
  user_parameters = convert_parameters_types(user_parameters)
285
- user_parameters = check_integrity(user_parameters, do_dense_region_deconvolution, is_multichannel, segmentation_done, map, shape)
286
+ user_parameters = check_integrity(
287
+ user_parameters,
288
+ do_dense_region_deconvolution,
289
+ do_clustering,
290
+ is_multichannel,
291
+ segmentation_done,
292
+ map,
293
+ shape
294
+ )
286
295
  except ParameterInputError as error:
287
296
  sg.popup(error)
288
297
  else :
@@ -592,7 +601,8 @@ def launch_detection(
592
601
  other_image,
593
602
  user_parameters,
594
603
  cell_label= None,
595
- nucleus_label = None
604
+ nucleus_label = None,
605
+ hide_loading=False,
596
606
  ) :
597
607
  """
598
608
  Main call for features computation :
@@ -618,18 +628,18 @@ def launch_detection(
618
628
  do_dense_region_deconvolution = user_parameters['Dense regions deconvolution']
619
629
  do_clustering = user_parameters['Cluster computation']
620
630
 
621
- spots, threshold = _launch_detection(image, user_parameters)
631
+ spots, threshold = _launch_detection(image, user_parameters, hide_loading = hide_loading)
622
632
 
623
633
  if do_dense_region_deconvolution :
624
- spots = launch_dense_region_deconvolution(image, spots, user_parameters)
634
+ spots = launch_dense_region_deconvolution(image, spots, user_parameters, hide_loading = hide_loading)
625
635
 
626
636
  if do_clustering :
627
- clusters = launch_clustering(spots, user_parameters) #012 are coordinates #3 is number of spots per cluster, #4 is cluster index
637
+ clusters = launch_clustering(spots, user_parameters, hide_loading = hide_loading) #012 are coordinates #3 is number of spots per cluster, #4 is cluster index
628
638
  clusters = _update_clusters(clusters, spots, voxel_size=user_parameters['voxel_size'], cluster_size=user_parameters['cluster size'], min_spot_number= user_parameters['min number of spots'], shape=image.shape)
629
639
 
630
640
  else : clusters = None
631
641
 
632
- spots, post_detection_dict = launch_post_detection(image, spots, user_parameters)
642
+ spots, post_detection_dict = launch_post_detection(image, spots, user_parameters, hide_loading = hide_loading)
633
643
  user_parameters['threshold'] = threshold
634
644
 
635
645
  if user_parameters['Napari correction'] :
@@ -825,4 +835,55 @@ def _local_maxima_mask(
825
835
  ndim=ndim)
826
836
  mask_local_max = detection.local_maximum_detection(image_filtered, minimum_distance)
827
837
 
828
- return mask_local_max.astype(bool)
838
+ return mask_local_max.astype(bool)
839
+
840
+ def output_spot_tiffvisual(channel,spots_list, path_output, dot_size = 3, rescale = True):
841
+
842
+ """
843
+ Outputs a tiff image with one channel being {channel} and the other a mask containing dots where sports are located.
844
+
845
+ Parameters
846
+ ----------
847
+ channel : np.ndarray
848
+ 3D monochannel image
849
+ spots : list[np.ndarray] or np.ndarray
850
+ Spots arrays are ndarray where each element corresponds is a tuple(z,y,x) corresponding to 3D coordinate of a spot
851
+ To plot different spots on different channels a list of spots ndarray can be passed.
852
+ path_output : str
853
+ dot_size : int
854
+ in pixels
855
+ """
856
+
857
+ stack.check_parameter(channel = (np.ndarray), spots_list= (list, np.ndarray), path_output = (str), dot_size = (int))
858
+ stack.check_array(channel, ndim= [2,3])
859
+ if isinstance(spots_list, np.ndarray) : spots_list = [spots_list]
860
+
861
+ if channel.ndim == 3 :
862
+ channel = stack.maximum_projection(channel)
863
+
864
+ im = np.zeros([1 + len(spots_list)] + list(channel.shape))
865
+ im[0,:,:] = channel
866
+
867
+ for level in range(len(spots_list)) :
868
+ if len(spots_list[level]) == 0 : continue
869
+ else :
870
+ spots_mask = np.zeros_like(channel)
871
+
872
+ #Unpacking spots
873
+ if len(spots_list[level][0]) == 2 :
874
+ Y,X = zip(*spots_list[level])
875
+ elif len(spots_list[level][0]) == 3 :
876
+ Z,Y,X = zip(*spots_list[level])
877
+ del Z
878
+ else :
879
+ Z,Y,X,*_ = zip(*spots_list[level])
880
+ del Z,_
881
+
882
+ #Reconstructing signal
883
+ spots_mask[Y,X] = 1
884
+ if dot_size > 1 : spots_mask = binary_dilation(spots_mask, iterations= dot_size-1)
885
+ spots_mask = stack.rescale(np.array(spots_mask, dtype = channel.dtype))
886
+ im[level + 1] = spots_mask
887
+
888
+ if rescale : channel = stack.rescale(channel, channel_to_stretch= 0)
889
+ stack.save_image(im, path_output, extension= 'tif')
@@ -4,6 +4,7 @@ import PySimpleGUI as sg
4
4
  from ..gui import hub_prompt
5
5
  from .actions import add_detection, save_results, compute_colocalisation, delete_acquisitions
6
6
  from ._preprocess import clean_unused_parameters_cache
7
+ from ..batch import batch_promp
7
8
 
8
9
  #'Global' parameters
9
10
  user_parameters = dict() # Very important object containg all choice from user that will influence the behavior of the main loop.
@@ -24,7 +25,6 @@ while True : #Break this loop to close small_fish
24
25
 
25
26
  if event == 'Add detection' :
26
27
  user_parameters = clean_unused_parameters_cache(user_parameters)
27
-
28
28
 
29
29
  new_result_df, new_cell_result_df, acquisition_id, user_parameters, segmentation_done, cytoplasm_label, nucleus_label = add_detection(
30
30
  user_parameters=user_parameters,
@@ -74,8 +74,12 @@ while True : #Break this loop to close small_fish
74
74
  result_df, cell_result_df, coloc_df = delete_acquisitions(selected_acquisitions, result_df, cell_result_df, coloc_df)
75
75
 
76
76
  elif event == "Batch detection" :
77
- #TODO
78
- pass
77
+ result_df, cell_result_df, acquisition_id, user_parameters, segmentation_done, cytoplasm_label,nucleus_label = batch_promp(
78
+ result_df,
79
+ cell_result_df,
80
+ acquisition_id=acquisition_id,
81
+ preset=user_parameters,
82
+ )
79
83
 
80
84
  else :
81
85
  break
small_fish_gui/utils.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import inspect
2
+ import datetime as dt
2
3
 
3
4
  def check_parameter(**kwargs):
4
5
  """Check dtype of the function's parameters.
@@ -52,4 +53,8 @@ def compute_anisotropy_coef(voxel_size) :
52
53
  return (z_anisotropy, xy_anisotropy, 1)
53
54
 
54
55
  else :
55
- return (voxel_size[0] / voxel_size[1], 1)
56
+ return (voxel_size[0] / voxel_size[1], 1)
57
+
58
+
59
+ def get_datetime():
60
+ return dt.datetime.now().strftime("%Y%m%d %H-%M-%S")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: small_fish_gui
3
- Version: 1.3.5
3
+ Version: 1.4.0
4
4
  Summary: Small Fish is a python application for the analysis of smFish images. It provides a ready to use graphical interface to combine famous python packages for cell analysis without any need for coding.
5
5
  Project-URL: Homepage, https://github.com/2Echoes/small_fish
6
6
  Project-URL: Issues, https://github.com/2Echoes/small_fish/issues
@@ -1,39 +1,49 @@
1
1
  small_fish_gui/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
2
2
  small_fish_gui/README.md,sha256=2c_homYDJXX6VsBiEs5obhBh3HpcTSMdyjLo-35WzE4,4062
3
3
  small_fish_gui/Segmentation example.jpg,sha256=opfiSbjmfF6z8kBs08sg_FNR2Om0AcMPU5sSwSLHdoQ,215038
4
- small_fish_gui/__init__.py,sha256=EnnsjHc4PvOZYdCT6JvKMiKDF_I6MMyBvj9TIDeOWco,1941
4
+ small_fish_gui/__init__.py,sha256=bAy5AbCcDOo7LXgavAnPpRWrr5bCcI8KVqQZX1nb1L0,1941
5
5
  small_fish_gui/__main__.py,sha256=EzSCoJ7jpSdK-QbzUwQLGZeQWjybNeq8VnCBucA8MZw,1372
6
6
  small_fish_gui/napari_detection_example.png,sha256=l5EZlrbXemLiGqb5inSVsD6Kko1Opz528-go-fBfrw8,977350
7
7
  small_fish_gui/requirements.txt,sha256=9OMfUAnLdHevq6w_fVoDmVmkSMJeFofkOK_86_fu9C0,321
8
- small_fish_gui/utils.py,sha256=tSoMb8N69WdKTtMItPb1DYZiIAz1mjI26BCKJAi6vuc,1798
8
+ small_fish_gui/utils.py,sha256=LM6QW2ono_LIRv7JXIIq7ZxxbDXqBtZ5uR9gjKJfwM8,1903
9
9
  small_fish_gui/.github/workflows/python-publish.yml,sha256=5Ltnuhw9TevhzndlBmdUgYMnS73xEAxSyd1u8DHdn5s,1084
10
+ small_fish_gui/batch/__init__.py,sha256=ku2_Yate-UG89Q0BmE2B9kFV4kOz-u9Lf2lj6VsdFXs,127
11
+ small_fish_gui/batch/input.py,sha256=mqnP8LBhyNbtlcqjVlUiVeuHw4YxOX3GgzJbq03isKE,1477
12
+ small_fish_gui/batch/integrity.py,sha256=yzVWBwm4Mxftd1sDziQwKc7d3ALdgWOhkqQrU5-p430,4849
13
+ small_fish_gui/batch/output.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ small_fish_gui/batch/pipeline.py,sha256=uZCwkoiSnTHWAf7C4XPNXg4ldIjbpRiULpzZWq7R1i0,8798
15
+ small_fish_gui/batch/prompt.py,sha256=K3Vb1ebcNe6JieXPDL1btrZR-4ASjs_HIklXx5B9lYU,18608
16
+ small_fish_gui/batch/test.py,sha256=q04a1YstnDsxy2Bi5563BfcOU-O3VPE9c5WSJjvFjMg,211
17
+ small_fish_gui/batch/update.py,sha256=hR4kZ7tP2tvn1tmDa4oJb2e7-SUqN1Lf8JR6OCIOMS8,5037
18
+ small_fish_gui/batch/utils.py,sha256=HgfPwfhqWXOGtCny_nTdGs8csWB1BQp7-hYgrNVLB70,1774
19
+ small_fish_gui/batch/values.py,sha256=C1hRlCpTIDsg89DMKIIW5NUxeK876ODRUuJ2D-mJv6o,1519
20
+ small_fish_gui/batch/values.txt,sha256=PVxzIaaF6DGFRx_CMaStXZI6OrbjNub1-jR3pklXVjc,991
10
21
  small_fish_gui/gui/__init__.py,sha256=xQ_BfYcnQmKZtx_0leO4OmbkLNLv49ZPqEu_UXMgmDc,867
11
- small_fish_gui/gui/animation.py,sha256=6_Y15_NzJ_TYBYseu3sSKaVkYRp2UCsVClAWOk3dESY,714
12
- small_fish_gui/gui/batch.py,sha256=aCd3UvzH6ljaWMdjQzOHA_D6QttWYIuv9iDK8iISSdg,10831
22
+ small_fish_gui/gui/animation.py,sha256=rnNP5FPp06Hu-R33c4AVTCknALBbxT2YlsKFCXHAp9k,981
13
23
  small_fish_gui/gui/general_help_screenshot.png,sha256=X4E6Td5f04K-pBUPDaBJRAE3D5b8fuEdiAUKhkIDr-0,54210
14
24
  small_fish_gui/gui/help_module.py,sha256=PmgkkDs7bZ2-po83A_PK9uldQcHjehYmqre21nYb6DQ,9600
15
- small_fish_gui/gui/layout.py,sha256=iLlSW40yBKoi4oW0TaWqbMV6ykr3P0Ar2ybf6X7VW3g,13139
25
+ small_fish_gui/gui/layout.py,sha256=k_ATlpkzqzo7UotXwq6WkuqnevKT6UgFjfDH0UzHAOM,13563
16
26
  small_fish_gui/gui/mapping_help_screenshot.png,sha256=HcuRh5TYciUogUasza5vZ_QSshaiHsskQK23mh9vQS8,34735
17
- small_fish_gui/gui/prompts.py,sha256=KKDeinZ2qOD-zNDTUndmnff5hDrcwt0B4blkzozr1Wc,13319
27
+ small_fish_gui/gui/prompts.py,sha256=WFxXLx-M3TM685iiQcNNNVX4Tpttn5JXPm6yM9eBRV4,13358
18
28
  small_fish_gui/gui/segmentation_help_screenshot.png,sha256=rbSgIydT0gZtfMh1qk4mdMbEIyCaakvHmxa2eOrLwO0,118944
19
- small_fish_gui/gui/test.py,sha256=6P8tnND4wHOE1bF7BGx26wWgE-WjaSCH9Mej7ZzauSg,101
20
29
  small_fish_gui/interface/__init__.py,sha256=PB86R4Y9kV80aGZ-vP0ZW2KeaCwGbBbCtFCmbN2yl28,275
21
30
  small_fish_gui/interface/image.py,sha256=X1L7S5svxUwdoDcI3QM1PbN-c4Nz5w30hixq3IgqSn8,1130
22
- small_fish_gui/interface/output.py,sha256=dyhpO1YrRCIbQYpqU_52E1DTNPf0wdktd--CB15iT3k,1712
31
+ small_fish_gui/interface/output.py,sha256=5jC37tobgXgsiVJYx3RWaES09I-YFmbXKk65lHflTHc,1867
23
32
  small_fish_gui/interface/parameters.py,sha256=lUugD-4W2TZyJF3TH1q70TlktEYhhPtcPCrvxm5Dk50,36
24
33
  small_fish_gui/interface/testing.py,sha256=MY5-GcPOUHagcrwR8A7QOjAmjZIDVC8Wz3NibLe3KQw,321
34
+ small_fish_gui/pipeline/__init__.py,sha256=_Ey20GG8fJtqZvixbXNNYX6wTWMnCUArmARPqsNEhuQ,743
25
35
  small_fish_gui/pipeline/_colocalisation.py,sha256=peBw2Qz5m6wSejDkDz240UgvWl8ohNelrnmEgznbEsw,9635
26
36
  small_fish_gui/pipeline/_custom_errors.py,sha256=tQ-AUhgzIFpK30AZiQQrtHCHyGVRDdAoIjzL0Fk-1pA,43
27
37
  small_fish_gui/pipeline/_napari_wrapper.py,sha256=_FkkY7IBKn1QgNvyea-x6XPjw_AwsLEVzdRKzg65oCE,9290
28
- small_fish_gui/pipeline/_preprocess.py,sha256=cbgXUx8yn3Wi_R7hFy64VuEXbbTbYw9p0qKG9cigyaM,10760
29
- small_fish_gui/pipeline/_segmentation.py,sha256=abltW2dKHarpDvM45TgkSJ4OzQV-b63VnA1PK4w1C_g,12998
38
+ small_fish_gui/pipeline/_preprocess.py,sha256=9Ns0el109qeRD1I7HmKpuljyKZfYLwPapvrKYl9ebdc,12943
39
+ small_fish_gui/pipeline/_segmentation.py,sha256=jcNf_GxNov_O16Xt6XyDIfYC7JsdiAxGeqLMJCwEy5I,13925
30
40
  small_fish_gui/pipeline/_signaltonoise.py,sha256=7A9t7xu7zghI6cr201Ldm-LjJ5NOuP56VSeJ8KIzcUo,8497
31
41
  small_fish_gui/pipeline/actions.py,sha256=EIGIOlwJ_DADX1NcLWwrTP_AidDX-4f4ggZV0gkIb58,7988
32
- small_fish_gui/pipeline/detection.py,sha256=yMD9PGLJHH96PpXQRWbB5gv1EwQhtMWQ1a95g_0WU0E,32075
33
- small_fish_gui/pipeline/main.py,sha256=AAW-zK3b7Ece9cdHn9y6QG8lTa1HXG-8JtnvJ3m0HwA,3149
42
+ small_fish_gui/pipeline/detection.py,sha256=La8hCO2WvZgHjvgUIjwQbqKYhDHI5ZtLhYrxFc62qbs,34429
43
+ small_fish_gui/pipeline/main.py,sha256=QamUbM4pfLLWGAC8AkJ-vTcUNHpWeu9bBB1g5pBBoNY,3433
34
44
  small_fish_gui/pipeline/spots.py,sha256=yHvqf1eD25UltELpzcouYXhLkxiXI_mOL1ANSzXK5pw,1907
35
45
  small_fish_gui/pipeline/test.py,sha256=w4ZMGDmUDXxVgWTlZ2TKw19W8q5gcE9gLMKe0SWnRrw,2827
36
- small_fish_gui-1.3.5.dist-info/METADATA,sha256=K4HY1GO44LtO6PXUZmK3_jNNFmDXMsS9LpWa3l8WDB8,2567
37
- small_fish_gui-1.3.5.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
38
- small_fish_gui-1.3.5.dist-info/licenses/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
39
- small_fish_gui-1.3.5.dist-info/RECORD,,
46
+ small_fish_gui-1.4.0.dist-info/METADATA,sha256=ga-XNAKMcj2t0XMTxUoj3aIMuIRE9DuiBPKQbmuadMk,2567
47
+ small_fish_gui-1.4.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
48
+ small_fish_gui-1.4.0.dist-info/licenses/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
49
+ small_fish_gui-1.4.0.dist-info/RECORD,,