Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pylabrobot/bmg_labtech/clariostar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
CLARIOstarDriver,
CLARIOstarFluorescenceResult,
CLARIOstarFluorescenceSpectrumResult,
CLARIOstarLuminescenceResult,
CLARIOstarSimulationDriver,
CLARIOstarStatus,
CLARIOstarZProfileResult,
Expand All @@ -20,6 +21,8 @@
Fluorescence,
FluorescenceConfiguration,
FrameError,
Luminescence,
LuminescenceConfiguration,
MeasurementSettings,
ShakeSettings,
TemperatureController,
Expand Down
8 changes: 7 additions & 1 deletion pylabrobot/bmg_labtech/clariostar/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
from .driver.features.absorbance import Absorbance
from .driver.features.drawer import Drawer
from .driver.features.fluorescence import Fluorescence
from .driver.features.luminescence import Luminescence
from .driver.features.temperature_controller import TemperatureController
from .driver.master import CLARIOstarDriver
from .driver.simulator import CLARIOstarSimulationDriver

# Preliminary: the operating manuals' nominal size, rounded to the cm, the same for the CLARIOstar
# Preliminary: the nominal size, rounded to the cm, the same for the CLARIOstar
# and the CLARIOstar Plus; not yet measured.
SIZE_X = 450.0
SIZE_Y = 510.0
Expand Down Expand Up @@ -189,6 +190,11 @@ def fluorescence(self) -> Optional[Fluorescence]:
"""Fluorescence measurement, or None if the reader has none; known after `setup`."""
return self.driver.fluorescence

@property
def luminescence(self) -> Optional[Luminescence]:
"""Luminescence measurement, or None if the reader has none; known after `setup`."""
return self.driver.luminescence

async def setup(self) -> None:
"""Connect, initialize the reader (about 13 s), and check it is the model this device is.

Expand Down
3 changes: 3 additions & 0 deletions pylabrobot/bmg_labtech/clariostar/driver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
CLARIOstarAbsorbanceSpectrumResult,
CLARIOstarFluorescenceResult,
CLARIOstarFluorescenceSpectrumResult,
CLARIOstarLuminescenceResult,
CLARIOstarZProfileResult,
Drawer,
Fluorescence,
FluorescenceConfiguration,
Luminescence,
LuminescenceConfiguration,
MeasurementSettings,
ShakeSettings,
TemperatureController,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,10 @@
Fluorescence,
FluorescenceConfiguration,
)
from .luminescence import (
CLARIOstarLuminescenceResult,
Luminescence,
LuminescenceConfiguration,
)
from .measurement import MeasurementSettings, ShakeSettings
from .temperature_controller import TemperatureController
20 changes: 10 additions & 10 deletions pylabrobot/bmg_labtech/clariostar/driver/features/absorbance.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class AbsorbanceConfiguration(MeasurementConfiguration):
wavelength_range: Tuple[int, int] = (220, 1000)
"""Wavelengths a read accepts, in nm (the manufacturer's spectrometer range)."""
maximum_wavelengths: int = 8
"""Wavelengths per read (the vendor software manual: up to 8; 8 read on hardware)."""
"""Wavelengths per read (up to 8; 8 read on hardware)."""


# ----------------------------------------
Expand Down Expand Up @@ -155,10 +155,10 @@ def __init__(
# ----------------------------------------

# Water pathlength correction after the wavelength fields, in nm: two wavelengths, a third
# unused, and its bandwidth, as the vendor always sends them.
# unused, and its bandwidth, always sent.
_PATHLENGTH_CORRECTION = (900.0, 993.0, 0.0, 10.0)
# Pause, u16 BE each: when (0 off, 1 before plate reading), then seconds. Off, the vendor sends
# 5 s; on, 5 s captured.
# Pause, u16 BE each: when (0 off, 1 before plate reading), then seconds; off, 5 s are sent,
# and on, 5 s is verified.
_NO_PAUSE = bytes.fromhex("00000005")
_PAUSE_BEFORE_READING = 0x0001

Expand All @@ -177,7 +177,7 @@ def _encode_wavelengths(*nanometres: float) -> bytes:
# Decoding
# ----------------------------------------

# Data reply layout byte [6]: the only one captured, with the temperature controller on or off.
# Data reply layout byte [6]: the only one verified, with the temperature controller on or off.
_DATA_LAYOUT = 0xA9

@staticmethod
Expand All @@ -195,8 +195,8 @@ def _decode_data_reply(self, reply: bytes, wavelengths: List[int]) -> _Decoded:
"""The samples per wavelength and the references, in the reply's well order (row by row), the
wavelengths' calibration pairs and the reference's.

The reply holds n + 3 groups of one u32 per well (the n samples, chromatics 2 and 3, the
reference), then n + 3 calibration pairs, in the same order.
The reply holds n + 3 groups of one u32 per well (the n samples, two groups not decoded,
the reference), then n + 3 calibration pairs, in the same order.

Raises:
ValueError: if the reply is incomplete or not the layout of this read.
Expand Down Expand Up @@ -271,8 +271,8 @@ def _check_arguments(

Raises:
ValueError: listing every violation: not 1 to `maximum_wavelengths` wavelengths, a wavelength
not a whole nm within `wavelength_range`, an unknown report, a matrix well scan (captured
but not decoded), a timeout not positive.
not a whole nm within `wavelength_range`, an unknown report, a matrix well scan (not
decoded), a timeout not positive.
"""
errors = []
maximum = self.configuration.maximum_wavelengths
Expand Down Expand Up @@ -350,7 +350,7 @@ async def measure(
wells: the wells to measure, on the plate; None measures every well.
wavelengths: 1 to `configuration.maximum_wavelengths` wavelengths, each a whole nm within
`configuration.wavelength_range`; all read in one pass.
measurement_settings: how to read; None reads with the defaults (the vendor's).
measurement_settings: how to read; None reads with the defaults.
shake_settings: shake the plate before the read; None does not shake.
report: what the results hold: optical density, or the raw sample counts with the reference
counts and calibration pairs that compute it (`CLARIOstarAbsorbanceResult`).
Expand Down
Loading
Loading