Skip to content

Conversation

@bbean23
Copy link
Collaborator

@bbean23 bbean23 commented Nov 6, 2025

Purpose

This fixes the nested window dressings issue by clearing window dressings before rendering on visualizations that are dependencies of later visualizations.

Fixes #302

Summary of changes

  • Clears window dressings before rendering.
  • Sets the figure size to eliminate extra whitespace.

Implementation notes

Correctness was verified with the following example code (from the upcoming CrossSection example looking straight at the sun):

def centroid_pixel_locator(operable: SpotAnalysisOperable) -> tuple[int, int]:
    """Returns the x/y pixel location of the centroid center"""
    moments = filter(lambda a: isinstance(a, MomentsAnnotation), operable.annotations)
    mom_annotation: MomentsAnnotation = list(moments)[-1]
    ret = mom_annotation.centroid.astuple()
    return (int(ret[0]), int(ret[1]))

def hotspot_pixel_locator(operable: SpotAnalysisOperable) -> tuple[int, int]:
    """Returns the x/y pixel location of the hotspot center"""
    hotspots = filter(lambda a: isinstance(a, HotspotAnnotation), operable.annotations)
    hs_annotation: HotspotAnnotation = list(hotspots)[-1]
    ret = hs_annotation.origin.astuple()
    return (int(ret[0]), int(ret[1]))

def rgb2gray(operable: SpotAnalysisOperable) -> np.ndarray:
    grayscale_image = cv.cvtColor(operable.primary_image.nparray, cv.COLOR_RGB2GRAY)
    return grayscale_image

image_processors = {
    "EchoEcho": EchoImageProcessor(),
    "Original": ConvolutionImageProcessor(diameter=1),
    "Rgb2Gray": CustomSimpleImageProcessor(rgb2gray),
    "PopStats": PopulationStatisticsImageProcessor(),
    "Centroid": MomentsImageProcessor(
        include_visualization=True, centroid_style=rcps.default(color=color.cyan(), markersize=20)
    ),
    "VFalseCl": ViewFalseColorImageProcessor(),
    "VCentOrg": ViewAnnotationsImageProcessor(base_image_selector='visualization'),
    "CropCent": CroppingImageProcessor(centered_location=centroid_pixel_locator, width_height=(1500, 1500)),
    "HotSpotS": HotspotImageProcessor(
        21, draw_debug_view=False, record_visualization=False, record_debug_view=False
    ),
    "VFalseC2": ViewFalseColorImageProcessor(),
    "VHotspot": ViewAnnotationsImageProcessor([HotspotAnnotation], base_image_selector='visualization'),
    "CropHots": CroppingImageProcessor(centered_location=hotspot_pixel_locator, width_height=(250, 250)),
    "Centrod2": MomentsImageProcessor(
        include_visualization=True, centroid_style=rcps.default(color=color.cyan(), markersize=20)
    ),
    "SpotSize": SpotWidthImageProcessor(spot_width_technique="fwhm"),
    "VFalseC3": ViewFalseColorImageProcessor(),
    "VOverExp": ViewHighlightImageProcessor(black_highlight_color=(70, 0, 70), white_highlight_color=(70, 70, 0)),
    "VAnnotat": ViewAnnotationsImageProcessor(base_image_selector='visualization'),
    "VCrosSec": ViewCrossSectionImageProcessor(
        centroid_pixel_locator, single_plot=False, y_range=(0, 255), base_image_selector='visualization'
    ),
    "VFalseC4": ViewHighlightImageProcessor(base_image_selector='visualization'),
    'Ve3d': View3dImageProcessor(max_resolution=(100, 100)),
}
_p = image_processors
processors_per_slide = [
    [
        (_p["Original"], "Original"),
        (_p["Rgb2Gray"], "Grayscale"),
        (_p["Centroid"], "Centroid & Principle Axis"),
        (_p["CropCent"], "Cropped to Centroid"),
    ],
    [
        (_p["VFalseC2"], "Cropped to Centroid"),
        (_p["VHotspot"], "Hotspot"),
        (_p["CropHots"], "Cropped to Hotspot"),
        (_p["VFalseC4"], "Test view over cross section"),
    ],
    [(_p["CropHots"], "Cropped Image"), _p["VAnnotat"], _p["VCrosSec"], _p["Ve3d"]],
]
image_processors["PowerPnt"] = PowerpointImageProcessor(
    results_dir, save_name_prefix, overwrite=True, processors_per_slide=processors_per_slide
)
image_processors_list = list(image_processors.values())

spot_analysis = SpotAnalysis(experiment_name, image_processors_list, save_dir=results_dir, save_overwrite=True)
spot_analysis.set_primary_images(input_images[:1])

for result in spot_analysis:
    pass

Without this fix, the resulting images for the "VCrosSec" and "VFalseC4" visualization image processors had the window dressings duplicated. After the fix the window dressings were no longer inherited by the later visualizations.

Submission checklist

  • Target branch is develop, not main
  • Existing tests are updated or new tests were added
  • opencsp/test/test_DocStringsExist.py are verified to include this change or have been updated accordingly
  • .rst file(s) under doc/ are verified to include this change or have been updated accordingly

Additional information

This needs additional work to add unit tests and update the documentation.

@bbean23 bbean23 self-assigned this Nov 6, 2025
@bbean23 bbean23 added the bug Something isn't working label Nov 6, 2025
@bbean23 bbean23 linked an issue Nov 6, 2025 that may be closed by this pull request
1 task
Copy link
Collaborator

@jehsharp jehsharp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, thanks for fixing that bug, should it also include updates to the testing suite?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Code Bug]: spot analysis visualizations have nested window dressings

2 participants