LI-COR Odyssey Classic#
| Model | Support |
|---|---|
| 9120 | WIP |
pylabrobot.li_cor.OdysseyClassicProperty |
Value |
|---|---|
Model |
9120 |
Connection |
Ethernet, HTTP Basic Auth |
Acquisition |
700 and 800 nm fluorescence |
Length units |
millimeters, including resolution |
This port has not been verified on hardware. Review the protocol and scan settings before using an instrument. These cells are not executed by the documentation build.
Connection and sample preparation#
Connect the scanner and computer to the same network and use the instrument’s configured IP address. The driver uses the embedded web interface; no vendor desktop application is required. Set ODYSSEY_HOST, ODYSSEY_USER, and ODYSSEY_PASS in your environment. Load the sample on the scan bed and close the lid before starting acquisition.
The optional pylabrobot[odyssey] extra installs Pillow for inspecting TIFF images. Instrument communication uses the standard-library HTTP transport.
Setup#
Open the transport and read the authenticated status page.
from pylabrobot.li_cor import OdysseyClassic
odyssey = OdysseyClassic() # Host and credentials come from the environment.
await odyssey.setup()
Read status#
Status includes scanner state, progress in percent, remaining-time text, and the lid state when reported by the firmware.
await odyssey.request_status()
Configure the scan#
The rectangle and resolution are in millimeters. This example scans a 100 × 100 mm region at 0.169 mm resolution with both channels enabled. Configuration includes the firmware’s seven-step initialization sequence.
await odyssey.configure_scan(
"membrane_001",
group="odyssey",
width=100,
height=100,
resolution=0.169,
focus=0,
channel_700=True,
channel_800=True,
)
Acquire#
Start the configured scan and wait up to one hour for completion. The instrument returns to Idle on completion. Unknown states and firmware errors raise exceptions.
final_status = await odyssey.scan(timeout=3600)
final_status
Download the channel TIFFs#
Each channel remains a separate image. download_channel(group, name, 700) retrieves only one channel; download retrieves both.
from pathlib import Path
images = await odyssey.download("odyssey", "membrane_001")
for channel, tiff in images.items():
Path(f"membrane_001-{channel}.tif").write_bytes(tiff)
Pause or interrupt an active acquisition#
For interactive control, configure a scan and use await odyssey.start_scan() to start without waiting. During acquisition:
await odyssey.pause_scan()pauses;await odyssey.start_scan()resumes.await odyssey.stop_and_save()gracefully stops and reports available channel TIFFs.await odyssey.cancel_scan()aborts and discards partial output.
await odyssey.wait_until_done() polls for completion. It requires a fresh transition out of an initial terminal state by default; use require_fresh=False when you know which scan you are waiting for.
Disconnect#
Closing the transport does not stop acquisition. Use stop_and_save() or cancel_scan() first when an active scan needs to be interrupted.
await odyssey.stop()
Chatterbox#
The simulated HTTP transport runs the same scan-control code without opening a socket. Status reads advance progress and produce synthetic one-pixel TIFFs. It does not render JPEG previews.
from pylabrobot.li_cor import OdysseyChatterbox
async with OdysseyClassic(io=OdysseyChatterbox()) as simulated:
await simulated.configure_scan("demo")
await simulated.scan(poll_interval=0.01)
demo_tiff = await simulated.download_channel("odyssey", "demo", 700)