@@ -28,11 +28,9 @@ def __init__(self):
2828
2929 self .image_selector_name = "Distances to Structure"
3030 self .image_selector_name1 = "Vesicles Segmentation"
31- self .image_selector_name2 = "Vesicles Morphology"
3231 # # Create the image selection dropdown.
3332 self .image_selector_widget = self ._create_layer_selector (self .image_selector_name , layer_type = "Shapes" )
3433 self .segmentation1_selector_widget = self ._create_layer_selector (self .image_selector_name1 , layer_type = "Labels" )
35- self .image_selector_widget2 = self ._create_layer_selector (self .image_selector_name2 , layer_type = "Shapes" )
3634
3735 # Create new layer name
3836 self .new_layer_name_param , new_layer_name_layout = self ._add_string_param (
@@ -62,25 +60,20 @@ def __init__(self):
6260
6361 # Add the widgets to the layout.
6462 layout .addWidget (self .image_selector_widget )
65- layout .addWidget (self .image_selector_widget2 )
6663 layout .addWidget (self .segmentation1_selector_widget )
6764 layout .addLayout (query_layout )
6865 layout .addLayout (new_layer_name_layout )
6966 layout .addLayout (pooled_group_name_layout )
70- # layout.addWidget(self.settings)
7167 layout .addWidget (self .measure_button1 )
72- # layout.addWidget(self.measure_button2)
7368
7469 self .setLayout (layout )
7570
7671 def on_pool_vesicles (self ):
7772 distances_layer = self ._get_layer_selector_layer (self .image_selector_name )
7873 distances = distances_layer .properties
7974 segmentation = self ._get_layer_selector_data (self .image_selector_name1 )
80- morphology_layer = self ._get_layer_selector_layer (self .image_selector_name2 )
75+ morphology_layer = self ._get_layer_selector_layer (self .image_selector_name1 )
8176 morphology = morphology_layer .properties
82- print ("distances" , distances )
83- print ("morphology" , morphology )
8477
8578 if segmentation is None :
8679 show_info ("INFO: Please choose a segmentation." )
@@ -99,25 +92,12 @@ def on_pool_vesicles(self):
9992 show_info ("INFO: Please enter a pooled group name." )
10093 return
10194 pooled_group_name = self .pooled_group_name_param .text ()
102-
103- # Get distances layer
104- # distance_layer_name = # query.get("distance_layer_name", None)
105- # if distance_layer_name in self.viewer.layers:
106- # distances = self._get_layer_selector_data(self.image_selector_name1, return_metadata=True)
95+
10796 if distances is None :
10897 show_info ("INFO: Distances layer could not be found or has no values." )
10998 return
11099 vesicle_pool = self ._compute_vesicle_pool (segmentation , distances , morphology , new_layer_name , pooled_group_name , query )
111100
112- # # get metadata from layer if available
113- # metadata = self._get_layer_selector_data(self.image_selector_name1, return_metadata=True)
114- # resolution = metadata.get("voxel_size", None)
115- # if resolution is not None:
116- # resolution = [v for v in resolution.values()]
117- # # if user input is present override metadata
118- # if self.voxel_size_param.value() != 0.0: # changed from default
119- # resolution = segmentation.ndim * [self.voxel_size_param.value()]
120-
121101 def _compute_vesicle_pool (self , segmentation , distances , morphology , new_layer_name , pooled_group_name , query ):
122102 """
123103 Compute a vesicle pool based on the provided query parameters.
@@ -128,7 +108,7 @@ def _compute_vesicle_pool(self, segmentation, distances, morphology, new_layer_n
128108 morphology (dict): Properties from the morphology layer.
129109 new_layer_name (str): Name for the new layer to be created.
130110 pooled_group_name (str): Name for the pooled group to be assigned.
131- query (dict): Query parameters with keys "min_radius" and "max_distance" .
111+ query (dict): Query parameters.
132112
133113 Returns:
134114 dict: Updated properties for the new vesicle pool.
@@ -147,73 +127,63 @@ def _compute_vesicle_pool(self, segmentation, distances, morphology, new_layer_n
147127
148128 # Merge dataframes on the 'id' column
149129 merged_df = morphology .merge (distances , left_on = "label_id" , right_on = "id" , suffixes = ("_morph" , "_dist" ))
150- # Filter rows based on query parameters
130+
151131 # Apply the query string to filter the data
152132 filtered_df = self ._parse_query (query , merged_df )
153133
154134 # Extract valid vesicle IDs
155135 valid_vesicle_ids = filtered_df ["label_id" ].tolist ()
156136
157- # Debugging output
158- for _ , row in filtered_df .iterrows ():
159- print (f"Vesicle { row ['label_id' ]} : Passed (Radius: { row ['radius' ]} , Distance: { row ['distance' ]} )" )
160-
161- # Update segmentation layer with valid vesicles
162137 new_layer_data = np .zeros (segmentation .shape , dtype = np .uint8 )
138+ pool_id = 1
139+ layer = None
140+
141+ # check if group already exists
142+ if new_layer_name in self .viewer .layers :
143+ layer = self .viewer .layers [new_layer_name ]
144+ if pooled_group_name not in layer .properties ["pool" ]:
145+ new_layer_data = layer .data
146+ pool_id = len (np .unique (layer .properties ["pool" ])) + 1
147+ # compute vesicles with new pool_id and properties
163148 for vesicle_id in valid_vesicle_ids :
164- new_layer_data [segmentation == vesicle_id ] = 1 # Highlight pooled vesicles
165-
166- # Create a new layer in the viewer
167- self .viewer .add_labels (
168- new_layer_data ,
169- name = new_layer_name ,
170- properties = {
171- "id" : valid_vesicle_ids ,
172- "radius" : filtered_df ["radius" ].tolist (),
173- "distance" : filtered_df ["distance" ].tolist (),
174- },
175- )
176- show_info (f"Vesicle pool created with { len (valid_vesicle_ids )} vesicles." )
149+ new_layer_data [segmentation == vesicle_id ] = pool_id
150+ new_properties = {
151+ "id" : valid_vesicle_ids ,
152+ "radius" : filtered_df ["radius" ].tolist (),
153+ "distance" : filtered_df ["distance" ].tolist (),
154+ "pool" : [pooled_group_name ] * len (valid_vesicle_ids )
155+ }
156+ if new_layer_name in self .viewer .layers :
157+ layer = self .viewer .layers [new_layer_name ]
158+ # override current vesicles with new pooled vesicles
159+ if pooled_group_name in layer .properties ["pool" ]:
160+ layer .data = new_layer_data
161+ layer .properties = new_properties
162+ show_info (f"Vesicle pool '{ pooled_group_name } ' overriden with { len (valid_vesicle_ids )} vesicles." )
163+ else :
164+ # add new vesicles and pool to existing layer
165+ current_properties = pd .DataFrame (layer .properties )
166+ new_properties = pd .DataFrame (new_properties )
167+ merged = pd .concat ([current_properties , new_properties ], ignore_index = True )
168+ layer .data = new_layer_data
169+ layer .properties = merged
170+ show_info (f"Vesicle pool '{ pooled_group_name } ' updated with { len (valid_vesicle_ids )} vesicles." )
171+ else :
172+ # Create a new layer in the viewer
173+ self .viewer .add_labels (
174+ new_layer_data ,
175+ name = new_layer_name ,
176+ properties = new_properties
177+ )
178+ show_info (f"Added new layer '{ new_layer_name } ' with { len (valid_vesicle_ids )} vesicles in group '{ pooled_group_name } '." )
179+ if add_table is not None :
180+ add_table (self .viewer .layers [new_layer_name ], self .viewer )
177181 return {
178182 "id" : valid_vesicle_ids ,
179183 "radius" : filtered_df ["radius" ].tolist (),
180184 "distance" : filtered_df ["distance" ].tolist (),
181185 }
182186
183- # # Filter vesicles based on the query
184- # valid_vesicles = []
185- # for i in distances_ids:
186- # distance = distances.get("distance", [])[i]
187- # radius = morphology.get("radius", [])[i]
188- # if radius >= min_radius and distance <= max_distance:
189- # print(f"Vesicle {i}: Passed (Radius: {radius}, Distance: {distance})")
190- # valid_vesicles.append(i)
191- # else:
192- # print(f"Vesicle {i}: Failed (Radius: {radius}, Distance: {distance})")
193-
194- # Create pooled properties
195- # pooled_properties = {
196- # "id": [i for i in valid_vesicles],
197- # "radius": [morphology["radius"][i] for i in valid_vesicles],
198- # "distance": [distances["distance"][i] for i in valid_vesicles],
199- # }
200- # print("pooled_properties", pooled_properties)
201- # print("np.unique(segmenation)", np.unique(segmentation))
202-
203- # # Create a new layer in the viewer
204- # new_layer_data = np.zeros(segmentation.shape, dtype=np.uint8)
205- # for vesicle_id in valid_vesicles:
206- # new_layer_data[segmentation == vesicle_id] = 1
207-
208- # self.viewer.add_labels(
209- # new_layer_data,
210- # name=new_layer_name,
211- # properties=pooled_properties,
212- # )
213-
214- # show_info(f"INFO: Created pooled vesicle layer '{new_layer_name}' with {len(valid_vesicles)} vesicles.")
215- # return pooled_properties
216-
217187 def _parse_query (self , query , data ):
218188 """
219189 Parse and apply a query string to filter data.
0 commit comments