Spaces:
Sleeping
Sleeping
Fix segment_tissue unpacking in batch analysis
Browse filesThe analyze_slide_with_models function was incorrectly calling
segment_tissue and unpacking its return value. segment_tissue returns
4 values (polygon, _, coords, attrs) but we were only unpacking 2.
This fix:
- Converts seg_config string to config object (BiopsySegConfig, etc.)
- Calls segment_tissue with proper individual parameters
- Correctly unpacks all 4 return values
- Uses polygon for slide mask visualization
Fixes: ValueError: too many values to unpack (expected 2)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- src/mosaic/analysis.py +36 -3
src/mosaic/analysis.py
CHANGED
|
@@ -635,13 +635,42 @@ def analyze_slide_with_models(
|
|
| 635 |
sex_idx = encode_sex(sex) if sex else None
|
| 636 |
tissue_site_idx = encode_tissue_site(tissue_site) if tissue_site else None
|
| 637 |
|
| 638 |
-
# Step 1:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 639 |
progress(0.0, desc="Segmenting tissue")
|
| 640 |
logger.info(f"Segmenting tissue for slide: {slide_path}")
|
| 641 |
start_time = pd.Timestamp.now()
|
| 642 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 643 |
end_time = pd.Timestamp.now()
|
| 644 |
logger.info(f"Tissue segmentation took {end_time - start_time}")
|
|
|
|
| 645 |
|
| 646 |
if len(coords) == 0:
|
| 647 |
logger.warning("No tissue tiles found in slide")
|
|
@@ -649,7 +678,11 @@ def analyze_slide_with_models(
|
|
| 649 |
|
| 650 |
# Step 2: Create slide mask visualization (CPU operation)
|
| 651 |
progress(0.2, desc="Creating slide mask")
|
| 652 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 653 |
|
| 654 |
# Step 3: Run inference pipeline with pre-loaded models
|
| 655 |
aeon_results, paladin_results = _run_inference_pipeline_with_models(
|
|
|
|
| 635 |
sex_idx = encode_sex(sex) if sex else None
|
| 636 |
tissue_site_idx = encode_tissue_site(tissue_site) if tissue_site else None
|
| 637 |
|
| 638 |
+
# Step 1: Convert seg_config string to config object
|
| 639 |
+
if isinstance(seg_config, str):
|
| 640 |
+
if seg_config == "Biopsy":
|
| 641 |
+
seg_config = BiopsySegConfig()
|
| 642 |
+
elif seg_config == "Resection":
|
| 643 |
+
seg_config = ResectionSegConfig()
|
| 644 |
+
elif seg_config == "TCGA":
|
| 645 |
+
seg_config = TcgaSegConfig()
|
| 646 |
+
else:
|
| 647 |
+
raise ValueError(f"Unknown segmentation configuration: {seg_config}")
|
| 648 |
+
|
| 649 |
+
# Step 2: Tissue segmentation (CPU operation, not affected by model caching)
|
| 650 |
progress(0.0, desc="Segmenting tissue")
|
| 651 |
logger.info(f"Segmenting tissue for slide: {slide_path}")
|
| 652 |
start_time = pd.Timestamp.now()
|
| 653 |
+
|
| 654 |
+
if values := segment_tissue(
|
| 655 |
+
slide_path=slide_path,
|
| 656 |
+
patch_size=224,
|
| 657 |
+
mpp=0.5,
|
| 658 |
+
seg_level=-1,
|
| 659 |
+
segment_threshold=seg_config.segment_threshold,
|
| 660 |
+
median_blur_ksize=seg_config.median_blur_ksize,
|
| 661 |
+
morphology_ex_kernel=seg_config.morphology_ex_kernel,
|
| 662 |
+
tissue_area_threshold=seg_config.tissue_area_threshold,
|
| 663 |
+
hole_area_threshold=seg_config.hole_area_threshold,
|
| 664 |
+
max_num_holes=seg_config.max_num_holes,
|
| 665 |
+
):
|
| 666 |
+
polygon, _, coords, attrs = values
|
| 667 |
+
else:
|
| 668 |
+
logger.warning("No tissue detected in slide")
|
| 669 |
+
return None, None, None
|
| 670 |
+
|
| 671 |
end_time = pd.Timestamp.now()
|
| 672 |
logger.info(f"Tissue segmentation took {end_time - start_time}")
|
| 673 |
+
logger.info(f"Found {len(coords)} tissue tiles")
|
| 674 |
|
| 675 |
if len(coords) == 0:
|
| 676 |
logger.warning("No tissue tiles found in slide")
|
|
|
|
| 678 |
|
| 679 |
# Step 2: Create slide mask visualization (CPU operation)
|
| 680 |
progress(0.2, desc="Creating slide mask")
|
| 681 |
+
logger.info("Drawing slide mask")
|
| 682 |
+
slide_mask = draw_slide_mask(
|
| 683 |
+
slide_path, polygon, outline="black", fill=(255, 0, 0, 80), vis_level=-1
|
| 684 |
+
)
|
| 685 |
+
logger.info("Slide mask drawn")
|
| 686 |
|
| 687 |
# Step 3: Run inference pipeline with pre-loaded models
|
| 688 |
aeon_results, paladin_results = _run_inference_pipeline_with_models(
|