Skip to content
Open
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
213 changes: 168 additions & 45 deletions docs/user_guide/agilent/biotek/cytation/hello-world.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -3,135 +3,258 @@
{
"cell_type": "markdown",
"id": "wez9bxdabm",
"source": "# Agilent BioTek Cytation\n\nThe Cytation is an Agilent BioTek multi-mode plate reader with optional microscopy imaging. Depending on the model it supports:\n\n- [Absorbance](../../../capabilities/absorbance)\n- [Fluorescence](../../../capabilities/fluorescence)\n- [Luminescence](../../../capabilities/luminescence)\n- [Microscopy](../../../capabilities/microscopy)\n- [Temperature control](../../../capabilities/temperature-control)\n\n| Model | PLR Name | Plate Reading | Microscopy | Temperature |\n|---|---|---|---|---|\n| Cytation 5 | `Cytation5` | Absorbance, Fluorescence, Luminescence | yes | yes |\n| Cytation 1 | `Cytation1` | -- | yes | yes |\n\nBoth models share the `CytationBackend` driver, which communicates over FTDI USB. The Cytation 5 adds plate-reading capabilities on top of the shared microscopy and temperature-control features.",
"metadata": {}
"metadata": {},
"source": [
"# Agilent BioTek Cytation\n",
"\n",
"The Cytation is an Agilent BioTek multi-mode plate reader with optional microscopy imaging. Depending on the model it supports:\n",
"\n",
"- [Absorbance](../../../capabilities/absorbance)\n",
"- [Fluorescence](../../../capabilities/fluorescence)\n",
"- [Luminescence](../../../capabilities/luminescence)\n",
"- [Microscopy](../../../capabilities/microscopy)\n",
"- [Temperature control](../../../capabilities/temperature-control)\n",
"\n",
"| Model | PLR Name | Plate Reading | Microscopy | Temperature |\n",
"|---|---|---|---|---|\n",
"| Cytation 5 | `Cytation5` | Absorbance, Fluorescence, Luminescence | yes | yes |\n",
"| Cytation 1 | `Cytation1` | -- | yes | yes |\n",
"\n",
"Both models share the `CytationBackend` driver, which communicates over FTDI USB. The Cytation 5 adds plate-reading capabilities on top of the shared microscopy and temperature-control features."
]
},
{
"cell_type": "markdown",
"id": "0rn94ubvq8dj",
"source": "## Setup\n\nThe examples below use a Cytation 5. For a Cytation 1, replace `Cytation5` with `Cytation1` (the Cytation 1 does not have `.absorbance`, `.fluorescence`, or `.luminescence` attributes).",
"metadata": {}
"metadata": {},
"source": [
"## Setup\n",
"\n",
"The examples below use a Cytation 5. For a Cytation 1, replace `Cytation5` with `Cytation1` (the Cytation 1 does not have `.absorbance`, `.fluorescence`, or `.luminescence` attributes)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ia4t5ga2ldg",
"source": "from pylabrobot.agilent.biotek.cytation import Cytation5\n\nc5 = Cytation5(name=\"cytation5\")\nawait c5.setup()",
"metadata": {},
"execution_count": null,
"outputs": []
"outputs": [],
"source": [
"from pylabrobot.agilent.biotek.cytation import Cytation5\n",
"\n",
"c5 = Cytation5(name=\"cytation5\")\n",
"await c5.setup()"
]
},
{
"cell_type": "markdown",
"id": "35rmpdivj44",
"source": "Open and close the tray door. Pass `slow=True` for slower motor travel if needed.",
"metadata": {}
"metadata": {},
"source": [
"Open and close the tray door. Pass `slow=True` for slower motor travel if needed."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "l85qt1z6hdf",
"source": "await c5.open()\n\nfrom pylabrobot.resources import Cor_96_wellplate_360ul_Fb\nplate = Cor_96_wellplate_360ul_Fb(name=\"plate\")\nc5.plate_holder.assign_child_resource(plate)\n\nawait c5.close()",
"metadata": {},
"execution_count": null,
"outputs": []
"outputs": [],
"source": [
"await c5.open()\n",
"\n",
"from pylabrobot.resources import Cor_96_wellplate_360ul_Fb\n",
"plate = Cor_96_wellplate_360ul_Fb(name=\"plate\")\n",
"c5.plate_holder.assign_child_resource(plate)\n",
"\n",
"await c5.close()"
]
},
{
"cell_type": "markdown",
"id": "hxkf2luxk9n",
"source": "## Plate reading (Cytation 5 only)\n\nThe Cytation 5 exposes `.absorbance`, `.fluorescence`, and `.luminescence` capability objects. For the full API, see [Absorbance](../../../capabilities/absorbance), [Fluorescence](../../../capabilities/fluorescence), and [Luminescence](../../../capabilities/luminescence).",
"metadata": {}
"metadata": {},
"source": [
"## Plate reading (Cytation 5 only)\n",
"\n",
"The Cytation 5 exposes `.absorbance`, `.fluorescence`, and `.luminescence` capability objects. For the full API, see [Absorbance](../../../capabilities/absorbance), [Fluorescence](../../../capabilities/fluorescence), and [Luminescence](../../../capabilities/luminescence)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "hwipa2rwkzl",
"source": "# Absorbance\ndata = await c5.absorbance.read_absorbance(wavelength=450)",
"metadata": {},
"execution_count": null,
"outputs": []
"outputs": [],
"source": [
"# Absorbance\n",
"data = await c5.absorbance.read_absorbance(wavelength=450)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "jmvn8du2t5",
"source": "# Fluorescence\ndata = await c5.fluorescence.read_fluorescence(\n excitation_wavelength=485, emission_wavelength=528, focal_height=7.5\n)",
"metadata": {},
"execution_count": null,
"outputs": []
"outputs": [],
"source": [
"# Fluorescence\n",
"data = await c5.fluorescence.read_fluorescence(\n",
" excitation_wavelength=485, emission_wavelength=528, focal_height=7.5\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "oxn123gjoh",
"source": "# Luminescence\ndata = await c5.luminescence.read_luminescence(focal_height=4.5)",
"metadata": {},
"execution_count": null,
"outputs": []
"outputs": [],
"source": [
"# Luminescence\n",
"data = await c5.luminescence.read_luminescence(focal_height=4.5)"
]
},
{
"cell_type": "markdown",
"id": "1qn3t2pqvw",
"source": "## Microscopy\n\nBoth the Cytation 5 and Cytation 1 expose a `.microscopy` capability. For imaging, pass `use_cam=True` during setup so the Spinnaker camera is initialized. For the full API, see [Microscopy](../../../capabilities/microscopy).\n\nUse {class}`~pylabrobot.agilent.biotek.cytation.CytationBackend.CaptureParams` to control LED intensity, coverage tiling, and pixel format.",
"metadata": {}
"metadata": {},
"source": [
"## Microscopy\n",
"\n",
"Both the Cytation 5 and Cytation 1 expose a `.microscopy` capability. For imaging, pass `use_cam=True` during setup so the Spinnaker camera is initialized. For the full API, see [Microscopy](../../../capabilities/microscopy).\n",
"\n",
"Use {class}`~pylabrobot.agilent.biotek.cytation.CytationBackend.CaptureParams` to control LED intensity, coverage tiling, and pixel format."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "qr1jm6691a",
"source": "from pylabrobot.agilent.biotek.cytation import CytationBackend, CytationImagingConfig\nfrom pylabrobot.capabilities.microscopy.standard import ImagingMode, Objective\n\nres = await c5.microscopy.capture(\n row=1,\n column=2,\n mode=ImagingMode.BRIGHTFIELD,\n objective=Objective.O_4X_PL_FL_Phase,\n focal_height=0.833,\n exposure_time=5,\n gain=16,\n plate=plate,\n backend_params=CytationBackend.CaptureParams(led_intensity=10),\n)",
"metadata": {},
"outputs": [],
"source": [
"from pylabrobot.agilent.biotek.cytation import CytationBackend, CytationImagingConfig\n",
"from pylabrobot.capabilities.microscopy.standard import ImagingMode, Objective\n",
"\n",
"res = await c5.microscopy.capture(\n",
" well=(1, 2),\n",
" mode=ImagingMode.BRIGHTFIELD,\n",
" objective=Objective.O_4X_PL_FL_Phase,\n",
" focal_height=0.833,\n",
" exposure_time=5,\n",
" gain=16,\n",
" plate=plate,\n",
" backend_params=CytationBackend.CaptureParams(led_intensity=10),\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"outputs": []
"id": "b7125e49",
"metadata": {},
"outputs": [],
"source": [
"from PIL import Image\n",
"img = Image.fromarray(res.images[0])\n",
"img"
]
},
{
"cell_type": "markdown",
"id": "km95iou30f",
"source": "Tile multiple fields of view with the `coverage` parameter:",
"metadata": {}
"metadata": {},
"source": [
"Tile multiple fields of view with the `coverage` parameter:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fi1o94l1uni",
"source": "res = await c5.microscopy.capture(\n row=1,\n column=2,\n mode=ImagingMode.BRIGHTFIELD,\n objective=Objective.O_4X_PL_FL_Phase,\n focal_height=0.833,\n exposure_time=5,\n gain=16,\n plate=plate,\n backend_params=CytationBackend.CaptureParams(\n led_intensity=10,\n coverage=(4, 4),\n ),\n)\nprint(f\"{len(res.images)} images captured\")",
"metadata": {},
"execution_count": null,
"outputs": []
"outputs": [],
"source": [
"res = await c5.microscopy.capture(\n",
" well=(1, 2),\n",
" mode=ImagingMode.BRIGHTFIELD,\n",
" objective=Objective.O_4X_PL_FL_Phase,\n",
" focal_height=0.833,\n",
" exposure_time=5,\n",
" gain=16,\n",
" plate=plate,\n",
" backend_params=CytationBackend.CaptureParams(\n",
" led_intensity=10,\n",
" coverage=(4, 4),\n",
" ),\n",
")\n",
"print(f\"{len(res.images)} images captured\")"
]
},
{
"cell_type": "markdown",
"id": "sa9pdeeo51",
"source": "## Temperature control\n\nBoth models expose a `.temperature` controller. For the full API, see [Temperature Control](../../../capabilities/temperature-control).",
"metadata": {}
"metadata": {},
"source": [
"## Temperature control\n",
"\n",
"Both models expose a `.temperature` controller. For the full API, see [Temperature Control](../../../capabilities/temperature-control)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "qhsjnerhl3",
"source": "await c5.temperature.set_temperature(37.0)\n\ncurrent = await c5.temperature.request_temperature()\nprint(f\"{current:.1f} \\u00b0C\")\n\nawait c5.temperature.deactivate()",
"metadata": {},
"execution_count": null,
"outputs": []
"outputs": [],
"source": [
"await c5.temperature.set_temperature(37.0)\n",
"\n",
"current = await c5.temperature.request_temperature()\n",
"print(f\"{current:.1f} \\u00b0C\")\n",
"\n",
"await c5.temperature.deactivate()"
]
},
{
"cell_type": "markdown",
"id": "f667qnt4occ",
"source": "## Teardown",
"metadata": {}
"metadata": {},
"source": [
"## Teardown"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "xcqz2zwu04g",
"source": "await c5.stop()",
"metadata": {},
"execution_count": null,
"outputs": []
"outputs": [],
"source": [
"await c5.stop()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "env",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"version": "3.11.0"
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
}
2 changes: 2 additions & 0 deletions pylabrobot/agilent/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from .biotek import (
EL406,
AravisImagingConfig,
BioTekBackend,
Cytation1,
Cytation5,
CytationAravisDriver,
CytationBackend,
CytationImagingConfig,
EL406Driver,
Expand Down
10 changes: 4 additions & 6 deletions pylabrobot/agilent/biotek/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from .biotek import BioTekBackend
from .cytation import (
Cytation1,
Cytation5,
CytationBackend,
CytationImagingConfig,
)
from .cytation import CytationBackend, CytationImagingConfig
from .cytation1 import Cytation1
from .cytation5 import Cytation5
from .cytation_aravis_driver import AravisImagingConfig, CytationAravisDriver
from .el406 import EL406, EL406Driver, EL406PlateWashingBackend, EL406ShakingBackend
from .synergy_h1 import SynergyH1, SynergyH1Backend
Loading
Loading