small-fish-gui 1.5.0__tar.gz → 1.6.0__tar.gz

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 (52) hide show
  1. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/PKG-INFO +1 -1
  2. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/pyproject.toml +1 -1
  3. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/__init__.py +1 -1
  4. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/__main__.py +3 -3
  5. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/gui/prompts.py +10 -6
  6. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/_colocalisation.py +9 -0
  7. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/_napari_wrapper.py +7 -11
  8. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/actions.py +30 -1
  9. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/detection.py +10 -2
  10. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/main.py +5 -1
  11. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/LICENSE +0 -0
  12. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/README.md +0 -0
  13. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/.github/workflows/python-publish.yml +0 -0
  14. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/.readthedocs.yaml +0 -0
  15. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/LICENSE +0 -0
  16. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/README.md +0 -0
  17. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/Segmentation example.jpg +0 -0
  18. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/__init__.py +0 -0
  19. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/input.py +0 -0
  20. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/integrity.py +0 -0
  21. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/output.py +0 -0
  22. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/pipeline.py +0 -0
  23. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/prompt.py +0 -0
  24. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/test.py +0 -0
  25. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/update.py +0 -0
  26. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/utils.py +0 -0
  27. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/values.py +0 -0
  28. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/batch/values.txt +0 -0
  29. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/docs/conf.py +0 -0
  30. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/gui/__init__.py +0 -0
  31. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/gui/animation.py +0 -0
  32. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/gui/general_help_screenshot.png +0 -0
  33. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/gui/help_module.py +0 -0
  34. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/gui/layout.py +0 -0
  35. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/gui/mapping_help_screenshot.png +0 -0
  36. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/gui/segmentation_help_screenshot.png +0 -0
  37. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/interface/__init__.py +0 -0
  38. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/interface/image.py +0 -0
  39. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/interface/output.py +0 -0
  40. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/interface/parameters.py +0 -0
  41. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/interface/testing.py +0 -0
  42. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/napari_detection_example.png +0 -0
  43. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/__init__.py +0 -0
  44. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/_custom_errors.py +0 -0
  45. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/_preprocess.py +0 -0
  46. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/_segmentation.py +0 -0
  47. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/_signaltonoise.py +0 -0
  48. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/spots.py +0 -0
  49. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/test.py +0 -0
  50. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/pipeline/utils.py +0 -0
  51. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/requirements.txt +0 -0
  52. {small_fish_gui-1.5.0 → small_fish_gui-1.6.0}/src/small_fish_gui/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: small_fish_gui
3
- Version: 1.5.0
3
+ Version: 1.6.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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "small_fish_gui"
7
- version = "1.5.0"
7
+ version = "1.6.0"
8
8
  authors = [
9
9
  { name="Slimani Floric", email="floric.slimani@live.com" },
10
10
  ]
@@ -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__ = "1.5.0"
41
+ __version__ = "1.6.0"
@@ -1,6 +1,8 @@
1
1
  import sys, subprocess
2
2
  import PySimpleGUI as sg
3
3
 
4
+ from small_fish_gui import __version__
5
+
4
6
  def main():
5
7
  import small_fish_gui.pipeline.main
6
8
 
@@ -10,9 +12,7 @@ def is_last_version() :
10
12
  latest_version = latest_version[:latest_version.find(')')]
11
13
  latest_version = latest_version.replace(' ','').split(',')[-1]
12
14
 
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(' ','')
15
+ current_version = __version__
16
16
 
17
17
  return current_version == latest_version
18
18
 
@@ -280,7 +280,7 @@ def _warning_popup(warning:str) :
280
280
 
281
281
  def _sumup_df(results: pd.DataFrame) :
282
282
 
283
- COLUMNS = ['acquisition_id','threshold', 'spot_number', 'cell_number', 'filename', 'channel to compute']
283
+ COLUMNS = ['acquisition_id','name','threshold', 'spot_number', 'cell_number', 'filename', 'channel to compute']
284
284
 
285
285
  if len(results) > 0 :
286
286
  if 'channel to compute' not in results : results['channel to compute'] = np.NaN
@@ -303,7 +303,7 @@ def hub_prompt(fov_results, do_segmentation=False) :
303
303
  [sg.Text('RESULTS', font= 'bold 13')],
304
304
  [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],
305
305
  [sg.Button('Add detection'), sg.Button('Compute colocalisation'), sg.Button('Batch detection')],
306
- [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')]
306
+ [sg.Button('Rename acquisition', button_color= 'green'), 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')]
307
307
  # [sg.Button('Save results', button_color= 'green'), sg.Button('Reset results',button_color= 'gray')]
308
308
  ]
309
309
 
@@ -318,16 +318,20 @@ def hub_prompt(fov_results, do_segmentation=False) :
318
318
  return event, values
319
319
 
320
320
  def coloc_prompt() :
321
- layout = [
322
- [parameters_layout(['colocalisation distance'], header= 'Colocalisation', default_values= 0)]
323
- ]
324
-
321
+ layout = parameters_layout(['colocalisation distance'], unit= 'nm', header= 'Colocalisation', default_values= 0)
325
322
  event, values = prompt_with_help(layout)
326
323
 
327
324
  if event == 'Ok' :
328
325
  return values['colocalisation distance']
329
326
  else : return False
330
327
 
328
+ def rename_prompt() :
329
+ layout = parameters_layout(['name'], header= "Rename acquisitions", size=12)
330
+ event, values = prompt_with_help(layout)
331
+ if event == 'Ok' :
332
+ return values['name']
333
+ else : return False
334
+
331
335
  def ask_detection_confirmation(used_threshold) :
332
336
  layout = [
333
337
  [sg.Text("Proceed with current detection ?", font= 'bold 10')],
@@ -263,4 +263,13 @@ def launch_colocalisation(result_tables, result_dataframe, colocalisation_distan
263
263
  'fraction_spots1_coloc_cluster2' : [fraction_spots1_coloc_cluster2],
264
264
  })
265
265
 
266
+ coloc_df['fraction_spots1_coloc_free2'] = coloc_df['fraction_spots1_coloc_spots2'] - coloc_df['fraction_spots1_coloc_cluster2']
267
+ coloc_df['fraction_spots2_coloc_free1'] = coloc_df['fraction_spots2_coloc_spots1'] - coloc_df['fraction_spots2_coloc_cluster1']
268
+
269
+ #Add names
270
+ coloc_df_col = list(coloc_df.columns)
271
+ coloc_df['name1'] = acquisition1.at['name']
272
+ coloc_df['name2'] = acquisition2.at['name']
273
+ coloc_df = coloc_df.loc[:,['name1','name2'] + coloc_df_col]
274
+
266
275
  return coloc_df
@@ -13,7 +13,7 @@ from ._colocalisation import spots_multicolocalisation
13
13
 
14
14
  def _update_clusters(new_clusters: np.ndarray, spots: np.ndarray, voxel_size, cluster_size, min_spot_number, shape) :
15
15
  if len(new_clusters) == 0 : return new_clusters
16
- if len(spots) == 0 : return new_clusters
16
+ if len(spots) == 0 : return np.empty(shape=(0,2+len(voxel_size)))
17
17
 
18
18
  if len(new_clusters[0]) in [2,3] :
19
19
  new_clusters = np.concatenate([
@@ -25,13 +25,10 @@ def _update_clusters(new_clusters: np.ndarray, spots: np.ndarray, voxel_size, cl
25
25
  assert len(new_clusters[0]) == 4 or len(new_clusters[0]) == 5, "Wrong number of coordinates for clusters should not happen."
26
26
 
27
27
  # Update spots clusters
28
- if len(voxel_size) == 3 :
29
- new_clusters[:,-2] = spots_multicolocalisation(new_clusters[:,:3], spots, radius_nm= cluster_size, voxel_size=voxel_size, image_shape=shape)
30
- elif len(voxel_size) == 2 :
31
- new_clusters[:,-2] = spots_multicolocalisation(new_clusters[:,:2], spots, radius_nm= cluster_size, voxel_size=voxel_size, image_shape=shape)
28
+ new_clusters[:,-2] = spots_multicolocalisation(new_clusters[:,:-2], spots, radius_nm= cluster_size, voxel_size=voxel_size, image_shape=shape)
32
29
 
33
30
  # delete too small clusters
34
- new_clusters = np.delete(new_clusters, new_clusters[:,-2] < min_spot_number, 0)
31
+ new_clusters = np.delete(new_clusters, new_clusters[:,-2] < min_spot_number, 0)
35
32
 
36
33
  return new_clusters
37
34
 
@@ -98,9 +95,8 @@ def correct_spots(image, spots, voxel_size= (1,1,1), clusters= None, cluster_siz
98
95
  new_spots = np.array(Viewer.layers['single spots'].data, dtype= int)
99
96
 
100
97
  if type(clusters) != type(None) :
101
- if len(clusters) > 0 :
102
- new_clusters = np.array(Viewer.layers['foci'].data, dtype= int)
103
- new_clusters = _update_clusters(new_clusters, new_spots, voxel_size=voxel_size, cluster_size=cluster_size, min_spot_number=min_spot_number, shape=image.shape)
98
+ new_clusters = np.array(Viewer.layers['foci'].data, dtype= int)
99
+ new_clusters = _update_clusters(new_clusters, new_spots, voxel_size=voxel_size, cluster_size=cluster_size, min_spot_number=min_spot_number, shape=image.shape)
104
100
  else : new_clusters = None
105
101
 
106
102
  return new_spots, new_clusters
@@ -152,9 +148,9 @@ def show_segmentation(
152
148
  Viewer.show(block=False)
153
149
  napari.run()
154
150
 
155
-
156
151
  new_nuc_label = Viewer.layers['nucleus_label'].data
157
- if type(cyto_label) != type(None) and not np.array_equal(cyto_label, nuc_label) : new_cyto_label = Viewer.layers['cytoplasm_label'].data
152
+ if 'cytoplasm_label' in Viewer.layers :
153
+ new_cyto_label = Viewer.layers['cytoplasm_label'].data
158
154
  else : new_cyto_label = new_nuc_label
159
155
 
160
156
  return new_nuc_label, new_cyto_label
@@ -2,7 +2,7 @@
2
2
  This submodule groups all the possible actions of the user in the main windows. It is the start of each action the user can do.
3
3
  """
4
4
 
5
- from ..gui.prompts import output_image_prompt, ask_detection_confirmation, ask_cancel_detection
5
+ from ..gui.prompts import output_image_prompt, ask_detection_confirmation, ask_cancel_detection, rename_prompt
6
6
  from ..interface.output import write_results
7
7
  from ._preprocess import map_channels, prepare_image_detection, reorder_shape, reorder_image_stack
8
8
  from .detection import ask_input_parameters, initiate_detection, launch_detection, launch_features_computation, get_nucleus_signal
@@ -177,3 +177,32 @@ def delete_acquisitions(selected_acquisitions : pd.DataFrame,
177
177
  result_df = result_df.drop(result_drop_idx, axis=0)
178
178
 
179
179
  return result_df, cell_result_df, coloc_df
180
+
181
+ def rename_acquisitions(
182
+ selected_acquisitions : pd.DataFrame,
183
+ result_df : pd.DataFrame,
184
+ cell_result_df : pd.DataFrame,
185
+ coloc_df : pd.DataFrame
186
+ ) :
187
+
188
+ if len(result_df) == 0 :
189
+ sg.popup("No acquisition to rename.")
190
+ return result_df, cell_result_df, coloc_df
191
+
192
+ if len(selected_acquisitions) == 0 :
193
+ sg.popup("Please select the acquisitions you would like to rename.")
194
+
195
+ else :
196
+ name = rename_prompt()
197
+ print("entered : ",name)
198
+ if not name : return result_df, cell_result_df, coloc_df #User didn't put a name or canceled
199
+ name : str = name.replace(' ','_')
200
+ acquisition_ids = list(result_df.iloc[list(selected_acquisitions)]['acquisition_id'])
201
+
202
+ result_df.loc[result_df['acquisition_id'].isin(acquisition_ids),['name']] = name
203
+ if len(cell_result_df) > 0 : cell_result_df.loc[cell_result_df['acquisition_id'].isin(acquisition_ids),['name']] = name
204
+ if len(coloc_df) > 0 :
205
+ coloc_df.loc[coloc_df['acquisition_id_1'].isin(acquisition_ids), ['name1']] = name
206
+ coloc_df.loc[coloc_df['acquisition_id_2'].isin(acquisition_ids), ['name2']] = name
207
+
208
+ return result_df, cell_result_df, coloc_df
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Contains code to handle detection as well as bigfish wrappers related to spot detection.
3
3
  """
4
+
4
5
  from ._preprocess import ParameterInputError
5
6
  from ._preprocess import check_integrity, convert_parameters_types
6
7
  from ._signaltonoise import compute_snr_spots
@@ -575,8 +576,6 @@ def launch_cell_extraction(acquisition_id, spots, clusters, image, nucleus_signa
575
576
 
576
577
  return result_frame
577
578
 
578
-
579
-
580
579
  @add_default_loading
581
580
  def launch_clustering(spots, user_parameters):
582
581
 
@@ -694,6 +693,15 @@ def launch_features_computation(acquisition_id, image, nucleus_signal, spots, cl
694
693
  frame_results['threshold'] = user_parameters['threshold']
695
694
 
696
695
  frame_results = pd.DataFrame(columns= frame_results.keys(), data= (frame_results.values(),))
696
+
697
+ #Adding name column
698
+ result_col = list(frame_results.columns)
699
+ cell_result_col = list(cell_result_dframe.columns)
700
+ name = "acquisition_{0}".format(acquisition_id)
701
+ frame_results['name'] = name
702
+ cell_result_dframe['name'] = name
703
+ frame_results = frame_results.loc[:,['name'] + result_col]
704
+ cell_result_dframe = cell_result_dframe.loc[:,['name'] + cell_result_col]
697
705
 
698
706
  return frame_results, cell_result_dframe
699
707
 
@@ -5,7 +5,7 @@ This script is called when software starts; it is the main loop.
5
5
  import pandas as pd
6
6
  import PySimpleGUI as sg
7
7
  from ..gui import hub_prompt
8
- from .actions import add_detection, save_results, compute_colocalisation, delete_acquisitions
8
+ from .actions import add_detection, save_results, compute_colocalisation, delete_acquisitions, rename_acquisitions
9
9
  from ._preprocess import clean_unused_parameters_cache
10
10
  from ..batch import batch_promp
11
11
 
@@ -84,6 +84,10 @@ while True : #Break this loop to close small_fish
84
84
  preset=user_parameters,
85
85
  )
86
86
 
87
+ elif event == "Rename acquisition" :
88
+ selected_acquisitions = values.setdefault('result_table', []) #Contains the lines selected by the user on the sum-up array.
89
+ result_df, cell_result_df, coloc_df = rename_acquisitions(selected_acquisitions, result_df, cell_result_df, coloc_df)
90
+
87
91
  else :
88
92
  break
89
93
 
File without changes
File without changes