Skip to content

Commit 026a28d

Browse files
timtreisclaude
andcommitted
Add tests for 5-channel compositing and per-channel normalization
- 5-channel auto-color composite (path 2B, n>3): untested path - 5-channel fluorescence palette (DAPI + 4 markers): path 2C with n>3 - Per-channel norm list: new feature, independent contrast per channel - Single-element norm list: verifies list[Normalize] works for 1 channel Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ca7882b commit 026a28d

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

tests/pl/test_render_images.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,43 @@ def test_plot_can_stick_to_zorder(self, sdata_blobs: SpatialData):
134134
def test_plot_can_render_multiscale_image_with_custom_cmap(self, sdata_blobs: SpatialData):
135135
sdata_blobs.pl.render_images("blobs_multiscale_image", channel=0, scale="scale2", cmap="Greys").pl.show()
136136

137+
# --- Multichannel compositing (path 2B for 4+ channels) ---
138+
# Uses sdata_blobs_str which has 5 named channels, simulating e.g. a
139+
# multiplexed immunofluorescence panel (DAPI + 4 markers).
140+
141+
def test_plot_can_composite_five_channels(self, sdata_blobs_str: SpatialData):
142+
"""5-channel additive blend with auto-assigned colors (path 2B, n>3)."""
143+
sdata_blobs_str.pl.render_images(element="blobs_image").pl.show()
144+
145+
def test_plot_can_composite_five_channels_with_palette(self, sdata_blobs_str: SpatialData):
146+
"""5-channel fluorescence-style overlay: DAPI + 4 markers (path 2C)."""
147+
sdata_blobs_str.pl.render_images(
148+
element="blobs_image",
149+
palette=["blue", "green", "red", "magenta", "cyan"],
150+
).pl.show()
151+
152+
# --- Per-channel normalization ---
153+
# Common in multiplexed imaging where markers have very different intensity
154+
# ranges (e.g. bright DAPI vs dim cytokine stain).
155+
156+
def test_plot_can_normalize_channels_independently(self, sdata_blobs: SpatialData):
157+
"""Per-channel norm: each channel gets its own contrast window."""
158+
sdata_blobs.pl.render_images(
159+
element="blobs_image",
160+
channel=[0, 1, 2],
161+
palette=["red", "green", "blue"],
162+
norm=[Normalize(vmin=0, vmax=0.5), Normalize(vmin=0.2, vmax=0.8), Normalize(vmin=0, vmax=1)],
163+
).pl.show()
164+
165+
def test_plot_can_normalize_single_channel_via_list(self, sdata_blobs: SpatialData):
166+
"""Single-element norm list works the same as a scalar norm."""
167+
sdata_blobs.pl.render_images(
168+
element="blobs_image",
169+
channel=0,
170+
norm=[Normalize(vmin=0.1, vmax=0.5)],
171+
cmap="Greys",
172+
).pl.show()
173+
137174
def test_plot_correctly_normalizes_multichannel_images(self, sdata_raccoon: SpatialData):
138175
sdata_raccoon["raccoon_int16"] = Image2DModel.parse(
139176
sdata_raccoon["raccoon"].data.astype(np.uint16) * 257, # 255 * 257 = 65535,

0 commit comments

Comments
 (0)