-
Notifications
You must be signed in to change notification settings - Fork 1
Affinity updates #64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Affinity updates #64
Conversation
…d on mean affinity values and update initialization parameters for bias and filtering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request refactors the AffinityPostprocessor class to provide more granular control over segmentation parameters and improves channel handling utilities. The changes enhance the flexibility of affinity-based segmentation postprocessing and fix potential bugs in channel configuration.
- Replaced single
biasparameter with three separate bias controls (adjacent_edge_bias,lr_bias_ratio,filter_val) for more precise segmentation tuning - Added fragment filtering capability based on mean affinity values with a new
filter_fragmentsmethod - Enhanced the processing pipeline with data normalization, noise addition, and affinity smoothing
- Fixed channel reference bug and improved backward compatibility for DaCapo channel naming
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| cellmap_flow/post/postprocessors.py | Major refactor of AffinityPostprocessor with new bias parameters, fragment filtering method, and enhanced processing pipeline |
| cellmap_flow/utils/data.py | Fixed block_shape calculation bug and improved channel naming for AffinitiesTask backward compatibility |
| self.filter_val = float(filter_val) | ||
| self.neighborhood = ast.literal_eval(neighborhood) | ||
| self.use_exact = use_exact == "True" | ||
| self.use_exact = use_exact == "False" |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic appears inverted - setting use_exact = use_exact == "False" means use_exact will be True when the string is "False" and False otherwise. This seems counterintuitive and likely incorrect.
| self.use_exact = use_exact == "False" | |
| self.use_exact = use_exact == "True" |
| import numpy as np | ||
| from scipy.ndimage import measurements | ||
|
|
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imports should be at the top of the file, not inside a method. Move this import to the top of the file with other imports.
| import numpy as np | |
| from scipy.ndimage import measurements |
| self.neighborhood = self.neighborhood[:n_channels] | ||
| # raise Exception(data.max(), data.min(), self.neighborhood) | ||
| import numpy as np | ||
| from scipy.ndimage import measurements |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imports should be at the top of the file, not inside a method. This import is also redundant as measurements is already imported at the top.
| from scipy.ndimage import measurements |
| """ | ||
|
|
||
| filtered_fragments = [] | ||
| average_affs: float = np.mean(affs_data.data, axis=0) |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessing .data attribute on affs_data may fail if affs_data is a numpy array rather than an object with a .data attribute. Use affs_data directly instead of affs_data.data.
| average_affs: float = np.mean(affs_data.data, axis=0) | |
| average_affs: float = np.mean(affs_data, axis=0) |
|
|
||
| if data.max() < 1e-4: | ||
| segmentation = np.zeros( | ||
| data.shape, dtype=np.uint64 if self.use_exact else np.uint16 |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shape for the zeros array should match the spatial dimensions of the data, but data.shape includes the channel dimension. Use data.shape[1:] instead of data.shape to exclude the channel dimension.
| data.shape, dtype=np.uint64 if self.use_exact else np.uint16 | |
| data.shape[1:], dtype=np.uint64 if self.use_exact else np.uint16 |
| filtered_fragments: np.ndarray = np.array( | ||
| filtered_fragments, dtype=fragments_data.dtype | ||
| ) | ||
| # replace: np.ndarray = np.zeros_like(filtered_fragments) |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented-out code that is not being used. This line appears to be leftover development code.
| # replace: np.ndarray = np.zeros_like(filtered_fragments) |
| if self.filter_val > 0.0: | ||
| self.filter_fragments(data, segmentation, self.filter_val) | ||
|
|
||
| # fragment_ids = fastremap.unique(segmentation[segmentation > 0]) |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented-out code. These lines appear to be leftover from the previous implementation.
| # fragment_ids = fastremap.unique(segmentation[segmentation > 0]) |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@stuarteberg
This pull request introduces several improvements and refactors to the affinity postprocessing logic, particularly in the
AffinityPostprocessorclass, and also updates channel handling in utility functions. The main changes include enhanced fragment filtering, more flexible bias parameters for segmentation, and improved compatibility for channel naming.Affinity postprocessor improvements:
AffinityPostprocessorconstructor to replace the singlebiasparameter withadjacent_edge_bias,lr_bias_ratio, andfilter_valfor finer control over segmentation behavior. (cellmap_flow/post/postprocessors.py[1] [2]filter_fragmentsmethod to filter MWS fragments based on mean affinity values, improving postprocessing quality. (cellmap_flow/post/postprocessors.pycellmap_flow/post/postprocessors.pyL148-R250)_processmethod to include data normalization, noise addition, affinity smoothing, and application of the new bias parameters, as well as fragment filtering. (cellmap_flow/post/postprocessors.pycellmap_flow/post/postprocessors.pyL148-R250)Channel and block shape handling:
block_shapein_get_configto useconfig.output_channelsinstead of the possibly undefined localchannelsvariable, fixing a potential bug. (cellmap_flow/utils/data.pycellmap_flow/utils/data.pyL125-R125)get_dacapo_channelsfunction to generate channel names based on theneighborhoodattribute for better backward compatibility, instead of defaulting to ["x", "y", "z"]. (cellmap_flow/utils/data.pycellmap_flow/utils/data.pyL387-R388)