Remove flash from stage baseclass, add to sim config
This commit is contained in:
parent
5682b4d28d
commit
4d788a2817
5 changed files with 26 additions and 26 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
"stage": "openflexure_microscope_server.things.stage.dummy:DummyStage",
|
"stage": "openflexure_microscope_server.things.stage.dummy:DummyStage",
|
||||||
"autofocus": "openflexure_microscope_server.things.autofocus:AutofocusThing",
|
"autofocus": "openflexure_microscope_server.things.autofocus:AutofocusThing",
|
||||||
"camera_stage_mapping": "openflexure_microscope_server.things.camera_stage_mapping:CameraStageMapper",
|
"camera_stage_mapping": "openflexure_microscope_server.things.camera_stage_mapping:CameraStageMapper",
|
||||||
|
"illumination": "openflexure_microscope_server.things.illumination.SimulatorIllumination",
|
||||||
"system": "openflexure_microscope_server.things.system:OpenFlexureSystem",
|
"system": "openflexure_microscope_server.things.system:OpenFlexureSystem",
|
||||||
"smart_scan": {
|
"smart_scan": {
|
||||||
"class": "openflexure_microscope_server.things.smart_scan:SmartScanThing",
|
"class": "openflexure_microscope_server.things.smart_scan:SmartScanThing",
|
||||||
|
|
|
||||||
|
|
@ -341,19 +341,21 @@ class SimulatedCamera(BaseCamera):
|
||||||
return pl_img.resize((self.shape[1], self.shape[0]), Image.Resampling.BILINEAR)
|
return pl_img.resize((self.shape[1], self.shape[0]), Image.Resampling.BILINEAR)
|
||||||
|
|
||||||
@lt.action
|
@lt.action
|
||||||
def set_led(self, led_on: bool = True, led_channel=None):
|
def set_led(self, led_on: bool = True, led_channel: str = None) -> None: # noqa: ARG002
|
||||||
|
"""Set the simulated LED to on or off."""
|
||||||
if led_on:
|
if led_on:
|
||||||
self.mult = 1
|
self.mult = 1
|
||||||
else:
|
else:
|
||||||
self.mult = 0
|
self.mult = 0
|
||||||
|
|
||||||
|
|
||||||
def generate_frame(self) -> Image.Image:
|
def generate_frame(self) -> Image.Image:
|
||||||
"""Generate a frame with blobs based on the stage coordinates."""
|
"""Generate a frame with blobs based on the stage coordinates."""
|
||||||
pos = self._stage.instantaneous_position
|
pos = self._stage.instantaneous_position
|
||||||
frame = self.generate_image((pos["y"], pos["x"], pos["z"]))
|
frame = self.generate_image((pos["y"], pos["x"], pos["z"]))
|
||||||
# Simulate LED turning off by setting all channels to 0
|
# Simulate LED turning off by setting all channels to 0
|
||||||
return frame * self.mult
|
if self.mult == 0:
|
||||||
|
return Image.new(frame.mode, frame.size, 0)
|
||||||
|
return frame
|
||||||
|
|
||||||
def __enter__(self) -> Self:
|
def __enter__(self) -> Self:
|
||||||
"""Start the capture thread when the Thing context manager is opened."""
|
"""Start the capture thread when the Thing context manager is opened."""
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
|
"""A module to handle the illumination in LabThings."""
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
import labthings_fastapi as lt
|
import labthings_fastapi as lt
|
||||||
|
|
||||||
|
from .camera import BaseCamera
|
||||||
from .stage import BaseStage
|
from .stage import BaseStage
|
||||||
from .camera import BaseCam
|
|
||||||
|
|
||||||
class Illumination(lt.Thing):
|
class Illumination(lt.Thing):
|
||||||
"""Abstract illumination controller."""
|
"""Abstract illumination controller."""
|
||||||
|
|
@ -17,9 +20,10 @@ class Illumination(lt.Thing):
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Flash the illumination source."""
|
"""Flash the illumination source."""
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
'Flashing the LED can only be done from the simulator or sangaboard'
|
"Flashing the LED can only be done from the simulator or sangaboard"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class SangaIllumination(Illumination):
|
class SangaIllumination(Illumination):
|
||||||
"""Illumination driven by a Sangaboard."""
|
"""Illumination driven by a Sangaboard."""
|
||||||
|
|
||||||
|
|
@ -32,16 +36,22 @@ class SangaIllumination(Illumination):
|
||||||
dt: float = 0.5,
|
dt: float = 0.5,
|
||||||
led_channel: Literal["cc"] = "cc",
|
led_channel: Literal["cc"] = "cc",
|
||||||
) -> None:
|
) -> None:
|
||||||
|
"""Flash an LED a given number of times.
|
||||||
|
|
||||||
|
Flashes the LED on channel led_channel number_of_flashes times,
|
||||||
|
for a duration of dt each.
|
||||||
|
"""
|
||||||
for _ in range(number_of_flashes):
|
for _ in range(number_of_flashes):
|
||||||
self._stage.set_led(False, led_channel)
|
self._stage.set_led(False, led_channel)
|
||||||
time.sleep(dt)
|
time.sleep(dt)
|
||||||
self._stage.set_led(True, led_channel)
|
self._stage.set_led(True, led_channel)
|
||||||
time.sleep(dt)
|
time.sleep(dt)
|
||||||
|
|
||||||
|
|
||||||
class SimulatorIllumination(Illumination):
|
class SimulatorIllumination(Illumination):
|
||||||
"""Illumination control in the simulator."""
|
"""Illumination control in the simulator."""
|
||||||
|
|
||||||
_cam: BaseCam = lt.thing_slot()
|
_cam: BaseCamera = lt.thing_slot()
|
||||||
|
|
||||||
@lt.action
|
@lt.action
|
||||||
def flash(
|
def flash(
|
||||||
|
|
@ -50,6 +60,11 @@ class SimulatorIllumination(Illumination):
|
||||||
dt: float = 0.5,
|
dt: float = 0.5,
|
||||||
led_channel: Literal["cc"] = "cc",
|
led_channel: Literal["cc"] = "cc",
|
||||||
) -> None:
|
) -> None:
|
||||||
|
"""Flash an LED a given number of times.
|
||||||
|
|
||||||
|
Flashes the LED on channel led_channel number_of_flashes times,
|
||||||
|
for a duration of dt each.
|
||||||
|
"""
|
||||||
for _ in range(number_of_flashes):
|
for _ in range(number_of_flashes):
|
||||||
self._cam.set_led(False, led_channel)
|
self._cam.set_led(False, led_channel)
|
||||||
time.sleep(dt)
|
time.sleep(dt)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from types import TracebackType
|
from types import TracebackType
|
||||||
from typing import Any, Literal, Optional, Self
|
from typing import Any, Optional, Self
|
||||||
|
|
||||||
import labthings_fastapi as lt
|
import labthings_fastapi as lt
|
||||||
|
|
||||||
|
|
@ -18,8 +18,6 @@ class DummyStage(BaseStage):
|
||||||
hardware attached.
|
hardware attached.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
led_on: bool = lt.property(default=True)
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
thing_server_interface: lt.ThingServerInterface,
|
thing_server_interface: lt.ThingServerInterface,
|
||||||
|
|
@ -117,18 +115,3 @@ class DummyStage(BaseStage):
|
||||||
"""
|
"""
|
||||||
self._hardware_position = dict.fromkeys(self.axis_names, 0)
|
self._hardware_position = dict.fromkeys(self.axis_names, 0)
|
||||||
self.instantaneous_position = self._hardware_position
|
self.instantaneous_position = self._hardware_position
|
||||||
|
|
||||||
# led_channel is unused in the simulation, but must exist to match the real API
|
|
||||||
@lt.action
|
|
||||||
def flash_led(
|
|
||||||
self,
|
|
||||||
number_of_flashes: int = 10,
|
|
||||||
dt: float = 0.5,
|
|
||||||
led_channel: Literal["cc"] = "cc", # noqa: ARG002
|
|
||||||
) -> None:
|
|
||||||
"""Flash the LED to identify the board (simulated)."""
|
|
||||||
for _ in range(number_of_flashes):
|
|
||||||
self.led_on = False
|
|
||||||
time.sleep(dt)
|
|
||||||
self.led_on = True
|
|
||||||
time.sleep(dt)
|
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,5 @@ class SangaboardThing(BaseStage):
|
||||||
if led_on:
|
if led_on:
|
||||||
on_brightness = 0.32
|
on_brightness = 0.32
|
||||||
sb.query(f"{led_command} {on_brightness}")
|
sb.query(f"{led_command} {on_brightness}")
|
||||||
else:
|
else:
|
||||||
sb.query(f"{led_command} 0")
|
sb.query(f"{led_command} 0")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue