pymmcore_plus.experimental.simulate
¶
Simulated microscope sample for testing and development.
This module provides tools for creating virtual microscope samples that integrate with CMMCorePlus. When a sample is installed on a core, image acquisition returns rendered images based on the sample objects and current microscope state (stage position, exposure, pixel size, etc.).
Examples:
Create a sample with some objects and use it with a core:
>>> from pymmcore_plus import CMMCorePlus
>>> from pymmcore_plus.experimental.simulate import (
... Sample,
... Point,
... Line,
... Rectangle,
... RenderConfig,
... )
>>>
>>> # Create core and load config
>>> core = CMMCorePlus.instance()
>>> core.loadSystemConfiguration()
>>>
>>> # Define sample objects (coordinates in microns)
>>> sample = Sample(
... [
... Point(0, 0, intensity=200, radius=5),
... Point(50, 50, intensity=150, radius=3),
... Line((0, 0), (100, 100), intensity=100),
... Rectangle((20, 20), width=30, height=20, intensity=180, fill=True),
... ]
... )
>>>
>>> # Use as context manager
>>> with sample.patch(core):
... core.snapImage()
... img = core.getImage() # Returns rendered simulation
... print(img.shape, img.dtype)
Custom render configuration:
>>> config = RenderConfig(
... noise_std=5.0, # More noise
... defocus_scale=0.2, # More blur with Z
... shot_noise=False, # Disable shot noise
... bit_depth=16, # 16-bit output
... )
>>> sample = Sample([Point(0, 0)], config=config)
Manual install/uninstall:
Classes
| Name | Description |
|---|---|
Arc |
An arc (partial ellipse outline) in the sample. |
Bitmap |
A bitmap image placed in the sample. |
Ellipse |
An ellipse in the sample. |
Line |
A line segment in the sample. |
Point |
A circular point/spot in the sample. |
Polygon |
A polygon in the sample. |
Rectangle |
A rectangle in the sample. |
RegularPolygon |
A regular polygon inscribed in a circle. |
RenderConfig |
Configuration for the rendering engine. |
Sample |
A simulated microscope sample that integrates with CMMCorePlus. |
SampleObject |
Base class for drawable sample objects. |
Functions
| Name | Description |
|---|---|
rects_intersect |
Check if two rectangles intersect. |
Attributes
| Name | Description |
|---|---|
Bounds |
Classes¶
Arc
dataclass
¶
Arc(
center: tuple[float, float],
rx: float,
ry: float,
start_angle: float,
end_angle: float,
intensity: int = 255,
width: int = 1,
)
Bases: SampleObject
An arc (partial ellipse outline) in the sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
tuple[float, float]
|
Center (x, y) in world units. |
required |
rx
|
float
|
X radius in world units. |
required |
ry
|
float
|
Y radius in world units. |
required |
start_angle
|
float
|
Start angle in degrees. |
required |
end_angle
|
float
|
End angle in degrees. |
required |
intensity
|
int
|
Brightness value (0-255). Default 255. |
255
|
width
|
int
|
Arc width in pixels. Default 1. |
1
|
Bitmap
dataclass
¶
Bases: SampleObject
A bitmap image placed in the sample.
The bitmap is placed at a fixed position and scale in world coordinates. Each pixel of the bitmap corresponds to one world unit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
top_left
|
tuple[float, float]
|
Top-left corner (x, y) in world units. |
required |
data
|
ndarray | Image | str
|
Image data as numpy array, PIL Image, or path to image file. |
required |
bitmap_scale
|
float
|
World units per bitmap pixel. Default 1.0 (1 pixel = 1 world unit). |
1.0
|
Ellipse
dataclass
¶
Ellipse(
center: tuple[float, float],
rx: float,
ry: float,
intensity: int = 255,
fill: bool = False,
width: int = 1,
)
Bases: SampleObject
An ellipse in the sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
tuple[float, float]
|
Center (x, y) in world units. |
required |
rx
|
float
|
X radius in world units. |
required |
ry
|
float
|
Y radius in world units. |
required |
intensity
|
int
|
Brightness value (0-255). Default 255. |
255
|
fill
|
bool
|
If True, fill the ellipse. If False, draw outline only. Default False. |
False
|
width
|
int
|
Outline width in pixels (only used if fill=False). Default 1. |
1
|
Line
dataclass
¶
Bases: SampleObject
A line segment in the sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
tuple[float, float]
|
Start point (x, y) in world units. |
required |
end
|
tuple[float, float]
|
End point (x, y) in world units. |
required |
intensity
|
int
|
Brightness value (0-255). Default 255. |
255
|
width
|
int
|
Line width in pixels. Default 1. |
1
|
Point
dataclass
¶
Bases: SampleObject
A circular point/spot in the sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
float
|
X coordinate in world units. |
required |
y
|
float
|
Y coordinate in world units. |
required |
intensity
|
int
|
Brightness value (0-255). Default 255. |
255
|
radius
|
float
|
Radius in world units. Default 2.0. |
2.0
|
Polygon
dataclass
¶
Polygon(
vertices: Sequence[tuple[float, float]],
intensity: int = 255,
fill: bool = False,
width: int = 1,
)
Bases: SampleObject
A polygon in the sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vertices
|
Sequence[tuple[float, float]]
|
List of (x, y) vertices in world units. |
required |
intensity
|
int
|
Brightness value (0-255). Default 255. |
255
|
fill
|
bool
|
If True, fill the polygon. Default False. |
False
|
width
|
int
|
Outline width in pixels (only used if fill=False). Default 1. |
1
|
Rectangle
dataclass
¶
Rectangle(
top_left: tuple[float, float],
width: float,
height: float,
intensity: int = 255,
fill: bool = False,
corner_radius: float = 0,
line_width: int = 1,
)
Bases: SampleObject
A rectangle in the sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
top_left
|
tuple[float, float]
|
Top-left corner (x, y) in world units. |
required |
width
|
float
|
Width in world units. |
required |
height
|
float
|
Height in world units. |
required |
intensity
|
int
|
Brightness value (0-255). Default 255. |
255
|
fill
|
bool
|
If True, fill the rectangle. If False, draw outline only. Default False. |
False
|
corner_radius
|
float
|
Corner radius for rounded rectangles, in world units. Default 0. |
0
|
line_width
|
int
|
Outline width in pixels (only used if fill=False). Default 1. |
1
|
RegularPolygon
dataclass
¶
RegularPolygon(
center: tuple[float, float],
radius: float,
n_sides: int,
rotation: float = 0,
intensity: int = 255,
fill: bool = False,
width: int = 1,
_vertices: list[tuple[float, float]] = list(),
)
Bases: SampleObject
A regular polygon inscribed in a circle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
tuple[float, float]
|
Center (x, y) in world units. |
required |
radius
|
float
|
Radius of bounding circle in world units. |
required |
n_sides
|
int
|
Number of sides. |
required |
rotation
|
float
|
Rotation angle in degrees. Default 0. |
0
|
intensity
|
int
|
Brightness value (0-255). Default 255. |
255
|
fill
|
bool
|
If True, fill the polygon. Default False. |
False
|
width
|
int
|
Outline width in pixels (only used if fill=False). Default 1. |
1
|
SampleObject
¶
Bases: ABC
Base class for drawable sample objects.
All coordinates are in world-space (typically microns). Objects are rendered
by calling draw() with a transform function that converts world coordinates
to pixel coordinates.
Subclasses must implement:
- draw(): Render the object onto a PIL ImageDraw context
- get_bounds(): Return the bounding box in world coordinates
- intensity: Property returning the object's intensity value
draw
abstractmethod
¶
draw(draw_context: ImageDraw, transform: TransformFn, scale: float) -> None
Draw this object onto the given context.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
draw_context
|
ImageDraw
|
PIL ImageDraw context to draw on. |
required |
transform
|
TransformFn
|
Function to convert (world_x, world_y) to (pixel_x, pixel_y). |
required |
scale
|
float
|
Pixels per world unit (e.g., pixels per micron). |
required |
get_bounds
abstractmethod
¶
get_bounds() -> Bounds
Return bounding box in world coordinates.
Returns:
| Type | Description |
|---|---|
Bounds
|
Tuple of (left, top, right, bottom) in world units. |
draw_cv2
¶
Draw this object using OpenCV (optional, for performance).
Default implementation falls back to PIL via a temporary image. Subclasses can override for better performance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
ndarray
|
Image array to draw on (modified in-place). |
required |
transform
|
TransformFn
|
Function to convert (world_x, world_y) to (pixel_x, pixel_y). |
required |
scale
|
float
|
Pixels per world unit. |
required |
RenderConfig
dataclass
¶
RenderConfig(
shot_noise: bool = True,
defocus_scale: float = 0.125,
base_blur: float = 1.5,
random_seed: int | None = None,
backend: Backend = "auto",
)
Configuration for the rendering engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shot_noise
|
bool
|
Whether to apply Poisson (shot) noise. Default True. |
True
|
defocus_scale
|
float
|
Blur radius per unit of Z distance from focus. Default 0.125. blur_radius = base_blur + abs(z) * defocus_scale |
0.125
|
base_blur
|
float
|
Minimum blur radius (at perfect focus). Default 1.0. |
1.5
|
random_seed
|
int | None
|
Random seed for reproducible noise. Default None (random). |
None
|
backend
|
Backend
|
Rendering backend: "auto" (default), "pil", or "cv2". "auto" uses cv2 if available, otherwise PIL. "cv2" raises ImportError if opencv-python is not installed. |
'auto'
|
Sample
¶
Sample(objects: Iterable[SampleObject], config: RenderConfig | None = None)
A simulated microscope sample that integrates with CMMCorePlus.
Use sample.patch(core) as a context manager to intercept image acquisition
calls and return rendered images based on microscope state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
objects
|
Iterable[SampleObject]
|
Sample objects to render (points, lines, shapes, etc.). |
required |
config
|
RenderConfig | None
|
Rendering configuration. If None, uses default config. |
None
|
patch
¶
patch(core: CMMCorePlus) -> Generator[Sample, None, None]
Patch the core to use this sample for image generation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core
|
CMMCorePlus
|
The core instance to patch. |
required |
Yields:
| Type | Description |
|---|---|
Sample
|
This sample instance. |