{ "cells": [ { "cell_type": "markdown", "id": "8e130e6f", "metadata": {}, "source": [ "# BioTek Synergy HT\n", "\n", "```{device-card} biotek-synergy-ht\n", "```\n", "\n", "| Property | Supported behavior |\n", "| --- | --- |\n", "| Interface | USB FTDI serial adapter; 9600 baud, 8 data bits, no parity, 2 stop bits |\n", "| Assay | Single-wavelength endpoint absorbance |\n", "| Plates | Reader's built-in 24- and 96-well presets |\n", "| Results | `AbsorbanceResult` with OD data, wavelength, temperature, and timestamp |\n", "| Additional operations | Tray opening/closing, temperature measurement, incubation, shaking before reads |\n", "\n", "Tested on hardware with basecode `7090202`, firmware `2.24`, including\n", "[tray movement, absorbance, and incubation](https://github.com/PyLabRobot/pylabrobot/pull/1512#issuecomment-6277553171)\n", "and [shaking before reads](https://github.com/PyLabRobot/pylabrobot/pull/1512#issuecomment-6297127421).\n", "Other basecodes are rejected; other firmware versions must report the required capabilities.\n", "This driver does not support Synergy H1, HTX, or Epoch.\n", "\n", "Fluorescence, luminescence, standalone shaking, kinetics, 384-well plates, and custom geometry are not implemented.\n" ] }, { "cell_type": "markdown", "id": "38cbe07a", "metadata": {}, "source": [ "## Connection and physical setup\n", "\n", "Install `pylabrobot[ftdi]` and the platform's libftdi runtime as described in the\n", "[installation guide](../../getting-started/installation.md). Connect the reader's serial interface\n", "through its USB FTDI adapter and power on the reader. Wait for normal boot to finish. Close Gen5\n", "and other applications using the same adapter.\n", "\n", "Use an unlidded, optically suitable plate matching the reader's built-in preset. Check the plate dimensions\n", "and well spacing against that preset.\n", "\n", "Import the driver.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "1c9dcbb3", "metadata": {}, "outputs": [], "source": [ "from pylabrobot.agilent.biotek import SynergyHT" ] }, { "cell_type": "markdown", "id": "0cd76476", "metadata": {}, "source": [ "## Connect\n", "\n", "Create the connection. If several FTDI adapters are attached, set `device_id` to the adapter's USB\n", "serial number, which can differ from the reader's serial number. The measurement timeout is in seconds.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "c865ffd8", "metadata": {}, "outputs": [], "source": [ "reader = SynergyHT(device_id=None, read_timeout=180)" ] }, { "cell_type": "markdown", "id": "c465e6a3", "metadata": {}, "source": [ "Initialize the connection and check the model and required protocol capabilities." ] }, { "cell_type": "code", "execution_count": null, "id": "8b6489d1", "metadata": {}, "outputs": [], "source": [ "await reader.setup()" ] }, { "cell_type": "markdown", "id": "84f66ec9", "metadata": {}, "source": [ "Inspect the reported identity and allowed incubation setpoints." ] }, { "cell_type": "code", "execution_count": null, "id": "0f913344", "metadata": {}, "outputs": [], "source": [ "(reader.serial_number, reader.version, reader.temperature_range)" ] }, { "cell_type": "markdown", "id": "43f97bad", "metadata": {}, "source": [ "## Load a plate\n", "\n", "Open the tray. Ensure its travel path is clear.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "c5893180", "metadata": {}, "outputs": [], "source": [ "await reader.open()" ] }, { "cell_type": "markdown", "id": "35aad092", "metadata": {}, "source": [ "Place a compatible, unlidded 96-well plate on the tray, with A1 aligned to the tray marking. Then close the tray." ] }, { "cell_type": "code", "execution_count": null, "id": "82f003c0", "metadata": {}, "outputs": [], "source": [ "await reader.close()" ] }, { "cell_type": "markdown", "id": "994d7c9d", "metadata": {}, "source": [ "## Read absorbance\n", "\n", "Read the full plate at 600 nm. Pass the plate type as a string: `\"96-well\"` or `\"24-well\"`,\n", "matching the built-in preset for the loaded plate. The instrument validates its wavelength range.\n", "\n", "Like the other BioTek readers, this returns a list of `AbsorbanceResult` objects. An HT endpoint\n", "read produces one result. Its `.data` matrix is indexed `[row][column]`: A1 is `[0][0]`, B1 is `[1][0]`.\n", "Values are raw OD, without blank subtraction or pathlength correction. Unselected wells are `None`,\n", "and instrument overflow is `NaN`. Include suitable blanks and standards for your assay." ] }, { "cell_type": "code", "execution_count": null, "id": "4419205d", "metadata": {}, "outputs": [], "source": [ "results = await reader.read_absorbance(wavelength=600, plate_type=\"96-well\")" ] }, { "cell_type": "markdown", "id": "0792e0fa", "metadata": {}, "source": [ "Inspect the first row of the endpoint result." ] }, { "cell_type": "code", "execution_count": null, "id": "dc3ed0af", "metadata": {}, "outputs": [], "source": [ "results[0].data[0]" ] }, { "cell_type": "markdown", "id": "aa100e5b", "metadata": {}, "source": [ "Inspect the measurement metadata. The wavelength is in nm, and the reported incubator temperature\n", "is in °C (`None` if unavailable). The timestamp is the host's local time when the read completed." ] }, { "cell_type": "code", "execution_count": null, "id": "b58987dc", "metadata": {}, "outputs": [], "source": [ "(results[0].wavelength, results[0].temperature, results[0].timestamp)" ] }, { "cell_type": "markdown", "id": "shake-before-read", "metadata": {}, "source": [ "## Shake before reading\n", "\n", "Shake the plate for 10 seconds before measuring absorbance. `shake_duration` is a whole number of\n", "seconds from 0 to 65535; zero (the default) disables shaking. `shake_intensity` selects one of the\n", "instrument's four levels: `\"slow\"` (the default), `\"medium\"`, `\"fast\"`, or `\"variable\"`.\n", "These levels are not frequencies in Hz or RPM.\n", "\n", "The tray must be closed. The call waits for both shaking and the measurement to finish, allowing\n", "`shake_duration` extra seconds beyond `read_timeout`. Shaking settings apply only to this call;\n", "the next read uses its own settings. Standalone shaking is not supported." ] }, { "cell_type": "code", "execution_count": null, "id": "shake-before-read-example", "metadata": {}, "outputs": [], "source": [ "shaken = await reader.read_absorbance(\n", " wavelength=600,\n", " plate_type=\"96-well\",\n", " shake_duration=10,\n", " shake_intensity=\"fast\",\n", ")" ] }, { "cell_type": "markdown", "id": "5ba58d05", "metadata": {}, "source": [ "## Select wells\n", "\n", "For a partial read, provide well names. The instrument measures their bounding rectangle;\n", "`selected[0].data` contains the full-plate matrix, with `None` for all wells you did not request." ] }, { "cell_type": "code", "execution_count": null, "id": "f05b2486", "metadata": {}, "outputs": [], "source": [ "selected = await reader.read_absorbance(600, \"96-well\", wells=[\"A1\", \"B2\"])" ] }, { "cell_type": "markdown", "id": "09f8f4e4", "metadata": {}, "source": [ "## Optional incubation\n", "\n", "Enable incubation at 37 °C. This returns when the setpoint is accepted, before the plate has\n", "necessarily reached that temperature. Check `reader.temperature_range` for this instrument's limits.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "b609632c", "metadata": {}, "outputs": [], "source": [ "await reader.set_temperature(37)" ] }, { "cell_type": "markdown", "id": "83c6d911", "metadata": {}, "source": [ "Read the current incubator temperature in °C. This is not a measurement of the liquid temperature." ] }, { "cell_type": "code", "execution_count": null, "id": "8139fb10", "metadata": {}, "outputs": [], "source": [ "temperature = await reader.get_temperature()" ] }, { "cell_type": "markdown", "id": "564d4234", "metadata": {}, "source": [ "Disable incubation when it is no longer needed." ] }, { "cell_type": "code", "execution_count": null, "id": "3076cfc2", "metadata": {}, "outputs": [], "source": [ "await reader.stop_heating()" ] }, { "cell_type": "markdown", "id": "622c4922", "metadata": {}, "source": [ "## Unload and disconnect\n", "\n", "Open the tray and remove the plate.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "5b4fdd75", "metadata": {}, "outputs": [], "source": [ "await reader.open()" ] }, { "cell_type": "markdown", "id": "81c03b8e", "metadata": {}, "source": [ "After removing the plate, close the empty tray." ] }, { "cell_type": "code", "execution_count": null, "id": "bf953007", "metadata": {}, "outputs": [], "source": [ "await reader.close()" ] }, { "cell_type": "markdown", "id": "da4f9bf4", "metadata": {}, "source": [ "Disconnect. `stop()` does not disable incubation or abort a measurement. A failed or cancelled\n", "exchange closes the connection. Ensure the reader is idle before calling `setup()` to reconnect." ] }, { "cell_type": "code", "execution_count": null, "id": "e9cd0896", "metadata": {}, "outputs": [], "source": [ "await reader.stop()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.10" } }, "nbformat": 4, "nbformat_minor": 5 }