From 63e0b4515aeca2101f83d729d816dc46721d3a29 Mon Sep 17 00:00:00 2001 From: Alexander Hillsley Date: Fri, 17 Apr 2026 17:05:59 -0700 Subject: [PATCH 1/2] WIP Alex --- src/ops_model/features/cp_extraction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ops_model/features/cp_extraction.py b/src/ops_model/features/cp_extraction.py index 5e635ea..1517232 100644 --- a/src/ops_model/features/cp_extraction.py +++ b/src/ops_model/features/cp_extraction.py @@ -187,7 +187,7 @@ def single_object_features( f"{prefix}_{feat_name}": v for feat_name, v in features.items() } results.update(features_prefixed) - except (ValueError, IndexError): + except (ValueError, IndexError, UnboundLocalError): # Mask is empty or invalid - generate NaN features return _generate_feature_names_with_nan(measurements, prefix, "single_object") From f89aa85b5d672ac5b2b15c488a8fa5dda3c289a2 Mon Sep 17 00:00:00 2001 From: Alexander Hillsley Date: Tue, 21 Apr 2026 09:06:38 -0700 Subject: [PATCH 2/2] Add catch for cells near the boundary of the well-image. Mask and image can be slightly different chapes causing a mismatch in array sizes. Fix by taking min of either bounding box --- src/ops_model/data/data_loader.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ops_model/data/data_loader.py b/src/ops_model/data/data_loader.py index ab85aae..4da36da 100644 --- a/src/ops_model/data/data_loader.py +++ b/src/ops_model/data/data_loader.py @@ -41,7 +41,7 @@ # Add new entries here to support additional experiment types. COLUMN_ALIASES: dict[str, str] = { "minibinder_perturbation": "gene_name", # minibinder experiments - "AA_sequence": "sgRNA", # minibinder experiments + "AA_sequence": "sgRNA", # minibinder experiments } @@ -451,9 +451,17 @@ def __getitem__(self, index): nuc_mask = np.expand_dims(nuc_mask, axis=0) sc_mask = cell_mask == ci.segmentation_id + # cell_seg and nuclear_seg zarr arrays can differ by a few pixels at FOV + # boundaries due to independent segmentation pipelines. Clip to the smaller + # extent so downstream mask multiplication doesn't broadcast-error. + min_h = min(nuc_mask.shape[1], sc_mask.shape[1]) + min_w = min(nuc_mask.shape[2], sc_mask.shape[2]) + nuc_mask = nuc_mask[:, :min_h, :min_w] + sc_mask = sc_mask[:, :min_h, :min_w] + # ensure that all output masks as binary if self.cell_masks: - data = data * sc_mask + data = data[:, :min_h, :min_w] nuc_mask = (nuc_mask * sc_mask) > 0 cyto_mask = sc_mask & (nuc_mask == 0)