small-fish-gui 1.0.4__py3-none-any.whl → 1.2.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.
small_fish_gui/README.md CHANGED
@@ -1,19 +1,27 @@
1
1
  # Small Fish
2
2
  **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.
3
3
 
4
- Cell segmentation is peformed using *cellpose* (published work) : https://github.com/MouseLand/cellpose
4
+ Cell segmentation (**2D**) is peformed using *cellpose* (published work) : https://github.com/MouseLand/cellpose; compatible with your own cellpose models.
5
5
 
6
6
  Spot detection is performed via *big-fish* (published work) : https://github.com/fish-quant/big-fish
7
7
 
8
8
  Time stacks are not yet supported.
9
9
 
10
+ ## What can you do with small fish ?
11
+
12
+ - Single molecule quantification (including a lot of spatial features)
13
+ - Foci/Transcription site quantification
14
+ - Nuclear signal quantification
15
+ - Signal to noise analysis
16
+ - multichannel colocalisation
17
+
10
18
  ## Installation
11
19
 
12
20
  It is higly recommanded to create a specific [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) or [virtual](https://docs.python.org/3.6/library/venv.html) environnement to install small fish.
13
21
 
14
22
  ```bash
15
23
  conda create -n small_fish python=3.8
16
- activate small_fish
24
+ conda activate small_fish
17
25
  ```
18
26
  Then download the small_fish package :
19
27
  ```bash
@@ -35,6 +43,11 @@ Then launch Small fish :
35
43
  ```bash
36
44
  python -m small_fish_gui
37
45
  ```
46
+
47
+ ## Cellpose configuration
48
+
49
+ If you want to train your own cellpose model or set-up your GPU you can follow the official cellpose documentation, just remember to **first activate your small_fish environnement**.
50
+
38
51
  ## Developpement
39
52
 
40
53
  Optional features to include in future versions :
@@ -38,4 +38,4 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38
38
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
39
 
40
40
  """
41
- __version__ = "0.5.0"
41
+ __version__ = "1.2.0"
@@ -1,12 +1,26 @@
1
- import sys
2
- import os
1
+ import sys, subprocess
3
2
  import PySimpleGUI as sg
4
3
 
5
4
  def main():
6
5
  import small_fish_gui.pipeline.main
7
6
 
7
+ def is_last_version() :
8
+ latest_version = str(subprocess.run([sys.executable, '-m', 'pip', 'install', '{}==random'.format('small_fish_gui')], capture_output=True, text=True))
9
+ latest_version = latest_version[latest_version.find('(from versions:')+15:]
10
+ latest_version = latest_version[:latest_version.find(')')]
11
+ latest_version = latest_version.replace(' ','').split(',')[-1]
12
+
13
+ current_version = str(subprocess.run([sys.executable, '-m', 'pip', 'show', '{}'.format('small_fish_gui')], capture_output=True, text=True))
14
+ current_version = current_version[current_version.find('Version:')+8:]
15
+ current_version = current_version[:current_version.find('\\n')].replace(' ','')
16
+
17
+ return current_version == latest_version
8
18
 
9
19
  if __name__ == "__main__":
20
+
21
+ if not is_last_version() :
22
+ print("A new version of Small Fish is available. To update close small fish and type :\npip install --upgrade small_fish_gui")
23
+
10
24
  try :
11
25
  sys.exit(main())
12
26
  except Exception as error :
@@ -227,7 +227,7 @@ def _mapping_help() :
227
227
  This window present the shape of your image : example (1080,1080,4)
228
228
  1080x1080 are the xy dimension (pixel resolution); and 4 is the number of channel. Another example a 3D multichannel
229
229
  stack could be (18,4,1080,1080)...
230
- The machine understand the order of the information such as (1080,1080,4) positions are (0,1,2). /!\ It starts from zero! /!\
230
+ The machine understand the order of the information such as (1080,1080,4) positions are (0,1,2). It starts from zero!
231
231
  The mapping purpose is to link the position to the type of informations, in this case we want :
232
232
 
233
233
  x : 1
@@ -151,7 +151,7 @@ def radio_layout(values, header=None) :
151
151
  layout = add_header(header, layout=layout)
152
152
  return layout
153
153
 
154
- def _segmentation_layout(cytoplasm_model_preset= 'cyto2', nucleus_model_preset= 'nuclei', cytoplasm_channel_preset=0, nucleus_channel_preset=0, cyto_diameter_preset=30, nucleus_diameter_preset= 30, show_segmentation_preset= False, segment_only_nuclei_preset=False, saving_path_preset=os.getcwd(), filename_preset='cell_segmentation.png') :
154
+ def _segmentation_layout(multichannel, cytoplasm_model_preset= 'cyto2', nucleus_model_preset= 'nuclei', cytoplasm_channel_preset=0, nucleus_channel_preset=0, cyto_diameter_preset=30, nucleus_diameter_preset= 30, show_segmentation_preset= False, segment_only_nuclei_preset=False, saving_path_preset=os.getcwd(), filename_preset='cell_segmentation.png',) :
155
155
 
156
156
  USE_GPU = use_gpu()
157
157
 
@@ -165,14 +165,14 @@ def _segmentation_layout(cytoplasm_model_preset= 'cyto2', nucleus_model_preset=
165
165
  layout += [add_header("Cell Segmentation", [sg.Text("Choose cellpose model for cytoplasm: \n")]),
166
166
  [combo_layout(models_list, key='cyto_model_name', default_value= cytoplasm_model_preset)]
167
167
  ]
168
- layout += [parameters_layout(['cytoplasm channel'],default_values= [cytoplasm_channel_preset])]
168
+ if multichannel : layout += [parameters_layout(['cytoplasm channel'],default_values= [cytoplasm_channel_preset])]
169
169
  layout += [parameters_layout(['cytoplasm diameter'], unit= "px", default_values= [cyto_diameter_preset])]
170
170
  #Nucleus parameters
171
171
  layout += [
172
172
  add_header("Nucleus segmentation",[sg.Text("Choose cellpose model for nucleus: \n")]),
173
173
  combo_layout(models_list, key='nucleus_model_name', default_value= nucleus_model_preset)
174
174
  ]
175
- layout += [parameters_layout(['nucleus channel'], default_values= [nucleus_channel_preset])]
175
+ if multichannel : layout += [parameters_layout(['nucleus channel'], default_values= [nucleus_channel_preset])]
176
176
  layout += [parameters_layout([ 'nucleus diameter'],unit= "px", default_values= [nucleus_diameter_preset])]
177
177
  layout += [bool_layout(["Segment only nuclei"], preset=segment_only_nuclei_preset)]
178
178
 
@@ -1,6 +1,7 @@
1
1
  import PySimpleGUI as sg
2
2
  import pandas as pd
3
3
  import os
4
+ import numpy as np
4
5
  from .layout import path_layout, parameters_layout, bool_layout, tuple_layout, combo_layout, add_header
5
6
  from ..interface import open_image, check_format, FormatError
6
7
  from .help_module import ask_help
@@ -266,6 +267,7 @@ def _warning_popup(warning:str) :
266
267
  def _sumup_df(results: pd.DataFrame) :
267
268
 
268
269
  if len(results) > 0 :
270
+ if 'channel to compute' not in results : results['channel to compute'] = np.NaN
269
271
  res = results.loc[:,['acquisition_id', 'spot_number', 'cell_number', 'filename', 'channel to compute']]
270
272
  else :
271
273
  res = pd.DataFrame(columns= ['acquisition_id', 'spot_number', 'cell_number', 'filename', 'channel to compute'])
@@ -284,9 +286,9 @@ def hub_prompt(fov_results, do_segmentation=False) :
284
286
  layout = [
285
287
  [sg.Text('RESULTS', font= 'bold 13')],
286
288
  [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],
287
- [sg.Button('Add detection'), sg.Button('Compute colocalisation'), sg.Button('Batch detection')],
288
- # [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')]
289
- [sg.Button('Save results', button_color= 'green'), sg.Button('Reset results',button_color= 'gray')]
289
+ [sg.Button('Add detection'), sg.Button('Compute colocalisation')],#, sg.Button('Batch detection')],
290
+ [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')]
291
+ # [sg.Button('Save results', button_color= 'green'), sg.Button('Reset results',button_color= 'gray')]
290
292
  ]
291
293
 
292
294
  window = sg.Window('small fish', layout= layout, margins= (10,10))
@@ -204,13 +204,9 @@ def launch_colocalisation(result_tables, result_dataframe, colocalisation_distan
204
204
  voxel_size = voxel_size1
205
205
 
206
206
  if shape1 != shape2 :
207
- print(shape1)
208
- print(shape2)
209
207
  raise MissMatchError("shape 1 different than shape 2")
210
208
  else :
211
209
  shape = shape1
212
- print(shape1)
213
- print(shape2)
214
210
 
215
211
  acquisition_couple = (acquisition1.at['acquisition_id'], acquisition2.at['acquisition_id'])
216
212
 
@@ -235,6 +231,9 @@ def launch_colocalisation(result_tables, result_dataframe, colocalisation_distan
235
231
  except MissMatchError as e :
236
232
  sg.popup(str(e))
237
233
  fraction_spots2_coloc_cluster1 = np.NaN
234
+ except TypeError : # Clusters not computed
235
+ fraction_spots2_coloc_cluster1 = np.NaN
236
+
238
237
 
239
238
  else : fraction_spots2_coloc_cluster1 = np.NaN
240
239
 
@@ -242,9 +241,12 @@ def launch_colocalisation(result_tables, result_dataframe, colocalisation_distan
242
241
  try :
243
242
  clusters2 = acquisition2['clusters'][:,:len(voxel_size)]
244
243
  fraction_spots1_coloc_cluster2 = spots_colocalisation(image_shape=shape, spot_list1=spots1, spot_list2=clusters2, distance= colocalisation_distance, voxel_size=voxel_size) / spot1_total
245
- except MissMatchError as e :
244
+ except MissMatchError as e :# Clusters not computed
246
245
  sg.popup(str(e))
247
246
  fraction_spots1_coloc_cluster2 = np.NaN
247
+ except TypeError :
248
+ fraction_spots1_coloc_cluster2 = np.NaN
249
+
248
250
 
249
251
  else : fraction_spots1_coloc_cluster2 = np.NaN
250
252
 
@@ -261,6 +263,4 @@ def launch_colocalisation(result_tables, result_dataframe, colocalisation_distan
261
263
  'fraction_spots1_coloc_cluster2' : [fraction_spots1_coloc_cluster2],
262
264
  })
263
265
 
264
- print(coloc_df.loc[:,['fraction_spots1_coloc_spots2','fraction_spots2_coloc_spots1', 'fraction_spots2_coloc_cluster1', 'fraction_spots1_coloc_cluster2']])
265
-
266
266
  return coloc_df
@@ -269,4 +269,16 @@ def reorder_shape(shape, map) :
269
269
  np.array(shape)[source]
270
270
  )
271
271
 
272
- return new_shape
272
+ return new_shape
273
+
274
+ def clean_unused_parameters_cache(user_parameters: dict) :
275
+ """
276
+ Clean unused parameters that were set to None in previous run.
277
+ """
278
+ parameters = ['alpha', 'beta', 'gamma', 'cluster size', 'min number of spots']
279
+ for parameter in parameters :
280
+ if parameter in user_parameters.keys() :
281
+ if type(user_parameters[parameter]) == type(None) :
282
+ del user_parameters[parameter]
283
+
284
+ return user_parameters
@@ -31,7 +31,7 @@ def launch_segmentation(image: np.ndarray, user_parameters: dict) :
31
31
 
32
32
  while True : # Loop if show_segmentation
33
33
  #Default parameters
34
- cyto_model_name = user_parameters.setdefault('cyto_model_name', 'cyto2')
34
+ cyto_model_name = user_parameters.setdefault('cyto_model_name', 'cyto3')
35
35
  cyto_size = user_parameters.setdefault('cytoplasm diameter', 180)
36
36
  cytoplasm_channel = user_parameters.setdefault('cytoplasm channel', 0)
37
37
  nucleus_model_name = user_parameters.setdefault('nucleus_model_name', 'nuclei')
@@ -42,6 +42,7 @@ def launch_segmentation(image: np.ndarray, user_parameters: dict) :
42
42
  segment_only_nuclei = user_parameters.setdefault('Segment only nuclei', False)
43
43
  filename = user_parameters['filename']
44
44
  available_channels = list(range(image.shape[0]))
45
+ multichannel = user_parameters.get('multichannel')
45
46
 
46
47
 
47
48
  #Ask user for parameters
@@ -58,6 +59,7 @@ def launch_segmentation(image: np.ndarray, user_parameters: dict) :
58
59
  show_segmentation_preset=show_segmentation,
59
60
  segment_only_nuclei_preset=segment_only_nuclei,
60
61
  filename_preset=filename,
62
+ multichannel=multichannel,
61
63
  )
62
64
 
63
65
  event, values = prompt_with_help(layout, help='segmentation')
@@ -236,7 +238,10 @@ def _segmentate_object(im, model_name, object_size_px, channels = [0,0]) :
236
238
 
237
239
  return label
238
240
 
239
- def _cast_segmentation_parameters(values) :
241
+ def _cast_segmentation_parameters(values:dict) :
242
+
243
+ values.setdefault('cytoplasm channel',0)
244
+ values.setdefault('nucleus channel',0)
240
245
 
241
246
  if values['cyto_model_name'] == '' :
242
247
  values['cyto_model_name'] = None
@@ -31,7 +31,8 @@ def add_detection(user_parameters, segmentation_done, acquisition_id, cytoplasm_
31
31
  if user_parameters['Segmentation'] and not segmentation_done:
32
32
  im_seg = reorder_image_stack(map, user_parameters)
33
33
  cytoplasm_label, nucleus_label, user_parameters = launch_segmentation(im_seg, user_parameters=user_parameters)
34
-
34
+ elif segmentation_done :
35
+ pass
35
36
  else :
36
37
  cytoplasm_label, nucleus_label = None,None
37
38
 
@@ -124,4 +125,36 @@ def compute_colocalisation(result_tables, result_dataframe) :
124
125
  else :
125
126
  res_coloc = launch_colocalisation(result_tables, result_dataframe=result_dataframe, colocalisation_distance=colocalisation_distance)
126
127
 
127
- return res_coloc
128
+ return res_coloc
129
+
130
+ def delete_acquisitions(selected_acquisitions : pd.DataFrame,
131
+ result_df : pd.DataFrame,
132
+ cell_result_df : pd.DataFrame,
133
+ coloc_df : pd.DataFrame
134
+ ) :
135
+
136
+ if len(result_df) == 0 :
137
+ sg.popup("No acquisition to delete.")
138
+ return result_df, cell_result_df, coloc_df
139
+
140
+ if len(selected_acquisitions) == 0 :
141
+ sg.popup("Please select the acquisitions you would like to delete.")
142
+ else :
143
+ acquisition_ids = list(result_df.iloc[list(selected_acquisitions)]['acquisition_id'])
144
+ print("Acquisitions to delete : ", acquisition_ids)
145
+ result_drop_idx = result_df[result_df['acquisition_id'].isin(acquisition_ids)].index
146
+ print("{0} acquisitions to delete.".format(len(result_drop_idx)))
147
+
148
+ if len(cell_result_df) > 0 :
149
+ cell_result_df_drop_idx = cell_result_df[cell_result_df['acquisition_id'].isin(acquisition_ids)].index
150
+ print("{0} cells to delete.".format(len(cell_result_df_drop_idx)))
151
+ cell_result_df = cell_result_df.drop(cell_result_df_drop_idx, axis=0)
152
+
153
+ if len(coloc_df) > 0 :
154
+ coloc_df_drop_idx = coloc_df[(coloc_df["acquisition_id_1"].isin(acquisition_ids)) | (coloc_df['acquisition_id_2'].isin(acquisition_ids))].index
155
+ print("{0} coloc measurement to delete.".format(len(coloc_df_drop_idx)))
156
+ coloc_df = coloc_df.drop(coloc_df_drop_idx, axis=0)
157
+
158
+ result_df = result_df.drop(result_drop_idx, axis=0)
159
+
160
+ return result_df, cell_result_df, coloc_df
@@ -357,15 +357,17 @@ def launch_post_detection(image, spots, image_input_values: dict,) :
357
357
  #features
358
358
  fov_res['spot_number'] = len(spots)
359
359
  snr_res = compute_snr_spots(image, spots, voxel_size, spot_size)
360
-
361
- if dim == 3 :
362
- Z,Y,X = list(zip(*spots))
363
- spots_values = image[Z,Y,X]
360
+ if len(spots) == 0 :
361
+ fov_res['spotsSignal_median'], fov_res['spotsSignal_mean'], fov_res['spotsSignal_std'] = np.NaN, np.NaN, np.NaN
364
362
  else :
365
- Y,X = list(zip(*spots))
366
- spots_values = image[Y,X]
367
-
368
- fov_res['spotsSignal_median'], fov_res['spotsSignal_mean'], fov_res['spotsSignal_std'] = np.median(spots_values), np.mean(spots_values), np.std(spots_values)
363
+ if dim == 3 :
364
+ Z,Y,X = list(zip(*spots))
365
+ spots_values = image[Z,Y,X]
366
+ else :
367
+ Y,X = list(zip(*spots))
368
+ spots_values = image[Y,X]
369
+ fov_res['spotsSignal_median'], fov_res['spotsSignal_mean'], fov_res['spotsSignal_std'] = np.median(spots_values), np.mean(spots_values), np.std(spots_values)
370
+
369
371
  fov_res['median_pixel'] = np.median(image)
370
372
  fov_res['mean_pixel'] = np.mean(image)
371
373
 
@@ -374,6 +376,38 @@ def launch_post_detection(image, spots, image_input_values: dict,) :
374
376
 
375
377
  return spots, fov_res
376
378
 
379
+ def _compute_cell_snr(image: np.ndarray, bbox, spots, voxel_size, spot_size) :
380
+
381
+ min_y, min_x, max_y, max_x = bbox
382
+ image= image[min_y: max_y, min_x: max_x]
383
+
384
+ if len(spots) == 0 :
385
+ res = {
386
+ 'snr_mean' : np.NaN,
387
+ 'snr_median' : np.NaN,
388
+ 'snr_std' : np.NaN,
389
+ }
390
+
391
+ return res
392
+
393
+ if len(spots[0]) == 3 :
394
+ Z,Y,X = zip(*spots)
395
+ spots = np.array(
396
+ list(zip(Y,X)),
397
+ dtype= int
398
+ )
399
+ voxel_size = voxel_size[1:]
400
+ spot_size = spot_size[1:]
401
+
402
+ snr_dict = compute_snr_spots(
403
+ image= image,
404
+ spots= spots,
405
+ spot_radius= spot_size,
406
+ voxel_size=voxel_size
407
+ )
408
+
409
+ return snr_dict
410
+
377
411
  @add_default_loading
378
412
  def launch_cell_extraction(acquisition_id, spots, clusters, image, nucleus_signal, cell_label, nucleus_label, user_parameters) :
379
413
 
@@ -414,6 +448,7 @@ def launch_cell_extraction(acquisition_id, spots, clusters, image, nucleus_signa
414
448
 
415
449
  #Nucleus features : area is computed in bigfish
416
450
  features_names += ['nucleus_mean_signal', 'nucleus_median_signal', 'nucleus_max_signal', 'nucleus_min_signal']
451
+ features_names += ['snr_mean', 'snr_median', 'snr_std']
417
452
 
418
453
  result_frame = pd.DataFrame()
419
454
 
@@ -450,8 +485,22 @@ def launch_cell_extraction(acquisition_id, spots, clusters, image, nucleus_signa
450
485
  compute_topography=True
451
486
  )
452
487
 
488
+ #Signal to noise
489
+ snr_dict = _compute_cell_snr(
490
+ image,
491
+ cell_bbox,
492
+ spots=rna_coords,
493
+ voxel_size=voxel_size,
494
+ spot_size=user_parameters['spot_size']
495
+ )
496
+
497
+ snr_mean = snr_dict['snr_mean']
498
+ snr_median = snr_dict['snr_median']
499
+ snr_std = snr_dict['snr_std']
500
+
453
501
  features = list(features)
454
502
  features += [np.mean(nuc_signal), np.median(nuc_signal), np.max(nuc_signal), np.min(nuc_signal)]
503
+ features += [snr_mean, snr_median, snr_std]
455
504
 
456
505
  features = [acquisition_id, cell_id, cell_bbox] + features
457
506
 
@@ -554,9 +603,9 @@ def launch_features_computation(acquisition_id, image, nucleus_signal, spots, cl
554
603
  if user_parameters['Cluster computation'] :
555
604
  frame_results['cluster_number'] = len(clusters)
556
605
  if dim == 3 :
557
- frame_results['total_spots_in_clusters'] = clusters.sum(axis=0)[3]
606
+ frame_results['total_spots_in_clusters'] = clusters.sum(axis=0)[3] if len(clusters) >0 else 0
558
607
  else :
559
- frame_results['total_spots_in_clusters'] = clusters.sum(axis=0)[2]
608
+ frame_results['total_spots_in_clusters'] = clusters.sum(axis=0)[2] if len(clusters) >0 else 0
560
609
 
561
610
  if type(cell_label) != type(None) and type(nucleus_label) != type(None):
562
611
  cell_result_dframe = launch_cell_extraction(
@@ -626,7 +675,7 @@ def get_nucleus_signal(image, other_images, user_parameters) :
626
675
  return np.zeros(shape=image.shape)
627
676
 
628
677
  if rna_signal_channel == nucleus_signal_channel :
629
- nucleus_signal == image
678
+ nucleus_signal = image
630
679
 
631
680
  elif nucleus_signal_channel > rna_signal_channel :
632
681
  nucleus_signal_channel -=1
@@ -2,7 +2,8 @@
2
2
  import pandas as pd
3
3
  import PySimpleGUI as sg
4
4
  from ..gui import hub_prompt
5
- from .actions import add_detection, save_results, compute_colocalisation
5
+ from .actions import add_detection, save_results, compute_colocalisation, delete_acquisitions
6
+ from ._preprocess import clean_unused_parameters_cache
6
7
 
7
8
  #'Global' parameters
8
9
  user_parameters = dict() # Very important object containg all choice from user that will influence the behavior of the main loop.
@@ -15,10 +16,15 @@ cytoplasm_label = None
15
16
  nucleus_label = None
16
17
 
17
18
  while True : #Break this loop to close small_fish
19
+ result_df = result_df.reset_index(drop=True)
20
+ cell_result_df = cell_result_df.reset_index(drop=True)
21
+ coloc_df = coloc_df.reset_index(drop=True)
18
22
  try :
19
23
  event, values = hub_prompt(result_df, segmentation_done)
20
24
 
21
25
  if event == 'Add detection' :
26
+ user_parameters = clean_unused_parameters_cache(user_parameters)
27
+
22
28
 
23
29
  new_result_df, new_cell_result_df, acquisition_id, user_parameters, segmentation_done, cytoplasm_label, nucleus_label = add_detection(
24
30
  user_parameters=user_parameters,
@@ -64,8 +70,8 @@ while True : #Break this loop to close small_fish
64
70
  nucleus_label = None
65
71
 
66
72
  elif event == "Delete acquisitions" :
67
- #TODO
68
- pass
73
+ selected_acquisitions = values.setdefault('result_table', []) #Contains the lines selected by the user on the sum-up array.
74
+ result_df, cell_result_df, coloc_df = delete_acquisitions(selected_acquisitions, result_df, cell_result_df, coloc_df)
69
75
 
70
76
  elif event == "Batch detection" :
71
77
  #TODO
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: small_fish_gui
3
- Version: 1.0.4
3
+ Version: 1.2.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,7 +1,7 @@
1
1
  small_fish_gui/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
2
- small_fish_gui/README.md,sha256=ZTYZCvrjrC0380pYFrB_9IN-lDGIbwz4A174Spb0jyU,1320
3
- small_fish_gui/__init__.py,sha256=aAh4brM-eTSnFOWpYSFgMIqJzbjJX45RHIWi7ppl_nA,1941
4
- small_fish_gui/__main__.py,sha256=sQ_HejagRTOcVpMuwUnLSO4MTZwqZ8uEplLHgqVpa6o,464
2
+ small_fish_gui/README.md,sha256=LuvmYYwCVw7-rKhdhrtqxnxUfQxPUE-bbPlGNwzJh_4,1830
3
+ small_fish_gui/__init__.py,sha256=X2D6chgv6h8daHaMPwY_iCAscI86KwOkCCez6vsShPw,1941
4
+ small_fish_gui/__main__.py,sha256=EzSCoJ7jpSdK-QbzUwQLGZeQWjybNeq8VnCBucA8MZw,1372
5
5
  small_fish_gui/requirements.txt,sha256=9OMfUAnLdHevq6w_fVoDmVmkSMJeFofkOK_86_fu9C0,321
6
6
  small_fish_gui/start.py,sha256=HTbzsVcaMji1BZnWyjfn3bDGIQeXGG4zFzvCBepqFvA,108
7
7
  small_fish_gui/utils.py,sha256=tSoMb8N69WdKTtMItPb1DYZiIAz1mjI26BCKJAi6vuc,1798
@@ -9,10 +9,10 @@ small_fish_gui/.github/workflows/python-publish.yml,sha256=5Ltnuhw9TevhzndlBmdUg
9
9
  small_fish_gui/gui/__init__.py,sha256=178HC3t2z4EnP0iBnMcaP_pyh5xHwOkEE6p3WJwBQeU,911
10
10
  small_fish_gui/gui/animation.py,sha256=6_Y15_NzJ_TYBYseu3sSKaVkYRp2UCsVClAWOk3dESY,714
11
11
  small_fish_gui/gui/general_help_screenshot.png,sha256=X4E6Td5f04K-pBUPDaBJRAE3D5b8fuEdiAUKhkIDr-0,54210
12
- small_fish_gui/gui/help_module.py,sha256=pVSpGwhkI3bNr1EgBjnd-SukPTx6wcuFnAyyVNMZmWo,9608
13
- small_fish_gui/gui/layout.py,sha256=E_Z87S1YUR1gx2447OM0156dKXbzMA_q9joCO4hsZd8,7644
12
+ small_fish_gui/gui/help_module.py,sha256=PmgkkDs7bZ2-po83A_PK9uldQcHjehYmqre21nYb6DQ,9600
13
+ small_fish_gui/gui/layout.py,sha256=_ErOS2IUejeUuPLkDmPB3FzLkoHOWR-Iaxz-aUeETks,7695
14
14
  small_fish_gui/gui/mapping_help_screenshot.png,sha256=HcuRh5TYciUogUasza5vZ_QSshaiHsskQK23mh9vQS8,34735
15
- small_fish_gui/gui/prompts.py,sha256=mlw9NT5k3I8kTMB7w6W6QETbSIav_A7RhCmMVD7NFV0,12279
15
+ small_fish_gui/gui/prompts.py,sha256=74JPsGGtGMcHNdNQFjjHEN5XwdSd7hZKog_DTIcYaJ8,12389
16
16
  small_fish_gui/gui/segmentation_help_screenshot.png,sha256=rbSgIydT0gZtfMh1qk4mdMbEIyCaakvHmxa2eOrLwO0,118944
17
17
  small_fish_gui/gui/test.py,sha256=Pf-GW9AgW-0VL1mFbYtqRvPAaa8DgwCThv2dDUHCcmU,156
18
18
  small_fish_gui/interface/__init__.py,sha256=PB86R4Y9kV80aGZ-vP0ZW2KeaCwGbBbCtFCmbN2yl28,275
@@ -20,17 +20,17 @@ small_fish_gui/interface/image.py,sha256=X1L7S5svxUwdoDcI3QM1PbN-c4Nz5w30hixq3Ig
20
20
  small_fish_gui/interface/output.py,sha256=wqXJHk-PzqZwYr8NHLg9jcEJlZQXZk8R76aeWcTxsEw,1337
21
21
  small_fish_gui/interface/parameters.py,sha256=lUugD-4W2TZyJF3TH1q70TlktEYhhPtcPCrvxm5Dk50,36
22
22
  small_fish_gui/interface/testing.py,sha256=MY5-GcPOUHagcrwR8A7QOjAmjZIDVC8Wz3NibLe3KQw,321
23
- small_fish_gui/pipeline/_colocalisation.py,sha256=-zz_kvghpMSaBhQT0moHvwC6ee92S-oq-j9qZWqgZMY,9677
23
+ small_fish_gui/pipeline/_colocalisation.py,sha256=peBw2Qz5m6wSejDkDz240UgvWl8ohNelrnmEgznbEsw,9635
24
24
  small_fish_gui/pipeline/_custom_errors.py,sha256=tQ-AUhgzIFpK30AZiQQrtHCHyGVRDdAoIjzL0Fk-1pA,43
25
25
  small_fish_gui/pipeline/_detection_visualisation.py,sha256=CNxCQpiCzC9Uk-2RqSuTp55Glf1URCL_s8zidwljY9Y,5774
26
- small_fish_gui/pipeline/_preprocess.py,sha256=AlB86KuCA0UKA0XbTgXTJbg92Az34hzba_hsVs-uZl0,10035
27
- small_fish_gui/pipeline/_segmentation.py,sha256=IaeqsjwIweKH9LEm6qbDqssGW7R0MRZSh7PtF4etIEI,12772
26
+ small_fish_gui/pipeline/_preprocess.py,sha256=RHbMeYG6GPYyPJzxksgCQ8bs2O3qSXU0V-z4NZWQhrA,10487
27
+ small_fish_gui/pipeline/_segmentation.py,sha256=0f8M2Ujczm0tU5AVwxhfOyzRCi_P_gg1393S4RAvDFs,12968
28
28
  small_fish_gui/pipeline/_signaltonoise.py,sha256=7A9t7xu7zghI6cr201Ldm-LjJ5NOuP56VSeJ8KIzcUo,8497
29
- small_fish_gui/pipeline/actions.py,sha256=n6lr_LqV4PT5uw6KfovehUuUK-yTJ66G-IhY2uhHF_k,5472
30
- small_fish_gui/pipeline/detection.py,sha256=l4G2UHJmrzIg_alAge2GY0h5D34N_oqWzfgjfe2SI04,26032
31
- small_fish_gui/pipeline/main.py,sha256=4_Qk-NRhjOEsgN7T35NXOHj4OdDmZGS5kVeKde-yCiI,2593
29
+ small_fish_gui/pipeline/actions.py,sha256=eKKmT3SSDYKQz-zU8HKz9h0PPgqyYrj4qHbrw1hfpRQ,7118
30
+ small_fish_gui/pipeline/detection.py,sha256=n-uuk2cP9Ls3WaZnuQfNHWyPoJWZNh8k9yW_8ZDC3fA,27484
31
+ small_fish_gui/pipeline/main.py,sha256=AAW-zK3b7Ece9cdHn9y6QG8lTa1HXG-8JtnvJ3m0HwA,3149
32
32
  small_fish_gui/pipeline/test.py,sha256=w4ZMGDmUDXxVgWTlZ2TKw19W8q5gcE9gLMKe0SWnRrw,2827
33
- small_fish_gui-1.0.4.dist-info/METADATA,sha256=Ts0ZLtdXghljsj3JiBpsQcDsCtwUu76gvZhY91kd5pA,2567
34
- small_fish_gui-1.0.4.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
35
- small_fish_gui-1.0.4.dist-info/licenses/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
36
- small_fish_gui-1.0.4.dist-info/RECORD,,
33
+ small_fish_gui-1.2.0.dist-info/METADATA,sha256=ayA13aIDIc9K64nQLNlxWcTNNM7tO17BaK3kEycGiQw,2567
34
+ small_fish_gui-1.2.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
35
+ small_fish_gui-1.2.0.dist-info/licenses/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
36
+ small_fish_gui-1.2.0.dist-info/RECORD,,