From 7ddd3bf64d4088d7a74deb88cfcd82dba5c96c7e Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Thu, 12 Jun 2025 12:46:36 -0700 Subject: [PATCH 1/2] Add Cytomat incubator tutorial --- .../_material-handling.rst | 1 + .../incubators/cytomat.ipynb | 175 ++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 docs/user_guide/01_material-handling/incubators/cytomat.ipynb diff --git a/docs/user_guide/01_material-handling/_material-handling.rst b/docs/user_guide/01_material-handling/_material-handling.rst index 2967b17c284..622a673954e 100644 --- a/docs/user_guide/01_material-handling/_material-handling.rst +++ b/docs/user_guide/01_material-handling/_material-handling.rst @@ -18,5 +18,6 @@ This includes machines for temperature and motion control (as neither machines p fans/fans temperature tilting + incubators/cytomat diff --git a/docs/user_guide/01_material-handling/incubators/cytomat.ipynb b/docs/user_guide/01_material-handling/incubators/cytomat.ipynb new file mode 100644 index 00000000000..f27bf742a8a --- /dev/null +++ b/docs/user_guide/01_material-handling/incubators/cytomat.ipynb @@ -0,0 +1,175 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "abb22091", + "metadata": {}, + "source": [ + "# Hello World, \"Cytomat Incubator\"!\n", + "\n", + "The Cytomat series of incubators is used for storing microplates under\n", + "controlled environmental conditions. PyLabRobot implements the\n", + "{class}`~pylabrobot.incubators.cytomat.cytomat.CytomatBackend` which\n", + "supports several models such as `C6000`, `C6002`, `C2C_50`, `C2C_425`,\n", + "`C2C_450_SHAKE` and `C5C`.\n", + "\n", + "In this tutorial we show how to:\n", + "- connect to the incubator\n", + "- configure racks\n", + "- move plates in and out\n", + "- monitor temperature and humidity\n", + "\n", + "```{note}\n", + "This notebook uses `await` statements which must be run inside an\n", + "asynchronous environment such as `asyncio`.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6b9218a", + "metadata": {}, + "outputs": [], + "source": [ + "from pylabrobot.incubators import CytomatBackend, CytomatType\n", + "from pylabrobot.incubators.cytomat.racks import cytomat_rack_9mm_51\n", + "from pylabrobot.incubators.incubator import Incubator\n", + "from pylabrobot.resources.corning.plates import Cor_96_wellplate_360ul_Fb\n", + "from pylabrobot.resources import Coordinate\n", + "\n", + "# Connect to the incubator via a serial port\n", + "backend = CytomatBackend(model=CytomatType.C6000, port=\"/dev/ttyUSB0\")\n", + "\n", + "# Create a rack and assemble an `Incubator` resource\n", + "rack = cytomat_rack_9mm_51(\"rack_A\")\n", + "incubator = Incubator(\n", + " backend=backend,\n", + " name=\"cyto\",\n", + " size_x=860,\n", + " size_y=550,\n", + " size_z=900,\n", + " racks=[rack],\n", + " loading_tray_location=Coordinate(0, 0, 0),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "de3fe5c6", + "metadata": {}, + "source": [ + "## Setup\n", + "\n", + "Setting up the incubator opens the serial connection and initializes the\n", + "device." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cee39594", + "metadata": {}, + "outputs": [], + "source": [ + "await incubator.setup()" + ] + }, + { + "cell_type": "markdown", + "id": "8f379ea7", + "metadata": {}, + "source": [ + "## Storing a plate\n", + "\n", + "To store a plate we first place it on the loading tray and then call\n", + "{meth}`~pylabrobot.incubators.incubator.Incubator.take_in_plate`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25169f81", + "metadata": {}, + "outputs": [], + "source": [ + "plate = Cor_96_wellplate_360ul_Fb(\"my_plate\")\n", + "incubator.loading_tray.assign_child_resource(plate)\n", + "await incubator.take_in_plate(\"smallest\") # choose the smallest free site" + ] + }, + { + "cell_type": "markdown", + "id": "31f1c241", + "metadata": {}, + "source": [ + "## Retrieving a plate\n", + "\n", + "Use {meth}`~pylabrobot.incubators.incubator.Incubator.fetch_plate_to_loading_tray`\n", + "to move a plate from storage to the loading tray." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "632ec3f7", + "metadata": {}, + "outputs": [], + "source": [ + "await incubator.fetch_plate_to_loading_tray(\"my_plate\")\n", + "retrieved = incubator.loading_tray.resource" + ] + }, + { + "cell_type": "markdown", + "id": "7dc4dfb9", + "metadata": {}, + "source": [ + "## Monitoring conditions\n", + "\n", + "The Cytomat provides queries for temperature and humidity." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0d768495", + "metadata": {}, + "outputs": [], + "source": [ + "current_temp = await incubator.get_temperature()\n", + "current_humidity = await incubator.backend.get_humidity()\n", + "print(current_temp, current_humidity)" + ] + }, + { + "cell_type": "markdown", + "id": "7c27b01e", + "metadata": {}, + "source": [ + "## Shutdown\n", + "\n", + "Always close the connection when finished." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28b68d42", + "metadata": {}, + "outputs": [], + "source": [ + "await incubator.stop()" + ] + } + ], + "metadata": { + "jupytext": { + "cell_metadata_filter": "-all", + "main_language": "python", + "notebook_metadata_filter": "-all" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 4cfb4374cc24efb40b9b1bf8acbc2fd767eec5bb Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Thu, 12 Jun 2025 12:56:26 -0700 Subject: [PATCH 2/2] Document all take_in_plate options --- .../incubators/cytomat.ipynb | 176 +----------------- 1 file changed, 1 insertion(+), 175 deletions(-) diff --git a/docs/user_guide/01_material-handling/incubators/cytomat.ipynb b/docs/user_guide/01_material-handling/incubators/cytomat.ipynb index f27bf742a8a..f3e0072a327 100644 --- a/docs/user_guide/01_material-handling/incubators/cytomat.ipynb +++ b/docs/user_guide/01_material-handling/incubators/cytomat.ipynb @@ -1,175 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "abb22091", - "metadata": {}, - "source": [ - "# Hello World, \"Cytomat Incubator\"!\n", - "\n", - "The Cytomat series of incubators is used for storing microplates under\n", - "controlled environmental conditions. PyLabRobot implements the\n", - "{class}`~pylabrobot.incubators.cytomat.cytomat.CytomatBackend` which\n", - "supports several models such as `C6000`, `C6002`, `C2C_50`, `C2C_425`,\n", - "`C2C_450_SHAKE` and `C5C`.\n", - "\n", - "In this tutorial we show how to:\n", - "- connect to the incubator\n", - "- configure racks\n", - "- move plates in and out\n", - "- monitor temperature and humidity\n", - "\n", - "```{note}\n", - "This notebook uses `await` statements which must be run inside an\n", - "asynchronous environment such as `asyncio`.\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b6b9218a", - "metadata": {}, - "outputs": [], - "source": [ - "from pylabrobot.incubators import CytomatBackend, CytomatType\n", - "from pylabrobot.incubators.cytomat.racks import cytomat_rack_9mm_51\n", - "from pylabrobot.incubators.incubator import Incubator\n", - "from pylabrobot.resources.corning.plates import Cor_96_wellplate_360ul_Fb\n", - "from pylabrobot.resources import Coordinate\n", - "\n", - "# Connect to the incubator via a serial port\n", - "backend = CytomatBackend(model=CytomatType.C6000, port=\"/dev/ttyUSB0\")\n", - "\n", - "# Create a rack and assemble an `Incubator` resource\n", - "rack = cytomat_rack_9mm_51(\"rack_A\")\n", - "incubator = Incubator(\n", - " backend=backend,\n", - " name=\"cyto\",\n", - " size_x=860,\n", - " size_y=550,\n", - " size_z=900,\n", - " racks=[rack],\n", - " loading_tray_location=Coordinate(0, 0, 0),\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "de3fe5c6", - "metadata": {}, - "source": [ - "## Setup\n", - "\n", - "Setting up the incubator opens the serial connection and initializes the\n", - "device." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cee39594", - "metadata": {}, - "outputs": [], - "source": [ - "await incubator.setup()" - ] - }, - { - "cell_type": "markdown", - "id": "8f379ea7", - "metadata": {}, - "source": [ - "## Storing a plate\n", - "\n", - "To store a plate we first place it on the loading tray and then call\n", - "{meth}`~pylabrobot.incubators.incubator.Incubator.take_in_plate`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "25169f81", - "metadata": {}, - "outputs": [], - "source": [ - "plate = Cor_96_wellplate_360ul_Fb(\"my_plate\")\n", - "incubator.loading_tray.assign_child_resource(plate)\n", - "await incubator.take_in_plate(\"smallest\") # choose the smallest free site" - ] - }, - { - "cell_type": "markdown", - "id": "31f1c241", - "metadata": {}, - "source": [ - "## Retrieving a plate\n", - "\n", - "Use {meth}`~pylabrobot.incubators.incubator.Incubator.fetch_plate_to_loading_tray`\n", - "to move a plate from storage to the loading tray." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "632ec3f7", - "metadata": {}, - "outputs": [], - "source": [ - "await incubator.fetch_plate_to_loading_tray(\"my_plate\")\n", - "retrieved = incubator.loading_tray.resource" - ] - }, - { - "cell_type": "markdown", - "id": "7dc4dfb9", - "metadata": {}, - "source": [ - "## Monitoring conditions\n", - "\n", - "The Cytomat provides queries for temperature and humidity." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0d768495", - "metadata": {}, - "outputs": [], - "source": [ - "current_temp = await incubator.get_temperature()\n", - "current_humidity = await incubator.backend.get_humidity()\n", - "print(current_temp, current_humidity)" - ] - }, - { - "cell_type": "markdown", - "id": "7c27b01e", - "metadata": {}, - "source": [ - "## Shutdown\n", - "\n", - "Always close the connection when finished." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "28b68d42", - "metadata": {}, - "outputs": [], - "source": [ - "await incubator.stop()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{"cells": [{"cell_type": "markdown", "id": "abb22091", "metadata": {}, "source": ["# Hello World, \"Cytomat Incubator\"!\n", "\n", "The Cytomat series of incubators is used for storing microplates under\n", "controlled environmental conditions. PyLabRobot implements the\n", "{class}`~pylabrobot.incubators.cytomat.cytomat.CytomatBackend` which\n", "supports several models such as `C6000`, `C6002`, `C2C_50`, `C2C_425`,\n", "`C2C_450_SHAKE` and `C5C`.\n", "\n", "In this tutorial we show how to:\n", "- connect to the incubator\n", "- configure racks\n", "- move plates in and out\n", "- monitor temperature and humidity\n", "\n", "```{note}\n", "This notebook uses `await` statements which must be run inside an\n", "asynchronous environment such as `asyncio`.\n", "```"]}, {"cell_type": "code", "execution_count": null, "id": "b6b9218a", "metadata": {}, "outputs": [], "source": ["from pylabrobot.incubators import CytomatBackend, CytomatType\n", "from pylabrobot.incubators.cytomat.racks import cytomat_rack_9mm_51\n", "from pylabrobot.incubators.incubator import Incubator\n", "from pylabrobot.resources.corning.plates import Cor_96_wellplate_360ul_Fb\n", "from pylabrobot.resources import Coordinate\n", "\n", "# Connect to the incubator via a serial port\n", "backend = CytomatBackend(model=CytomatType.C6000, port=\"/dev/ttyUSB0\")\n", "\n", "# Create a rack and assemble an `Incubator` resource\n", "rack = cytomat_rack_9mm_51(\"rack_A\")\n", "incubator = Incubator(\n", " backend=backend,\n", " name=\"cyto\",\n", " size_x=860,\n", " size_y=550,\n", " size_z=900,\n", " racks=[rack],\n", " loading_tray_location=Coordinate(0, 0, 0),\n", ")"]}, {"cell_type": "markdown", "id": "de3fe5c6", "metadata": {}, "source": ["## Setup\n", "\n", "Setting up the incubator opens the serial connection and initializes the\n", "device."]}, {"cell_type": "code", "execution_count": null, "id": "cee39594", "metadata": {}, "outputs": [], "source": ["await incubator.setup()"]}, {"cell_type": "markdown", "id": "8f379ea7", "metadata": {}, "source": ["## Storing a plate\n", "\n", "To store a plate we first place it on the loading tray and then call\n", "{meth}`~pylabrobot.incubators.incubator.Incubator.take_in_plate`.\n", "You can choose a site automatically or specify one explicitly.\n"]}, {"cell_type": "code", "execution_count": null, "id": "25169f81", "metadata": {}, "outputs": [], "source": ["plate = Cor_96_wellplate_360ul_Fb(\"my_plate\")\n", "incubator.loading_tray.assign_child_resource(plate)\n", "await incubator.take_in_plate(\"smallest\") # choose the smallest free site\n", "\n", "# other options:\n", "# await incubator.take_in_plate(\"random\") # random free site\n", "# await incubator.take_in_plate(rack[3]) # store at rack position 3\n"]}, {"cell_type": "markdown", "id": "31f1c241", "metadata": {}, "source": ["## Retrieving a plate\n", "\n", "Use {meth}`~pylabrobot.incubators.incubator.Incubator.fetch_plate_to_loading_tray`\n", "to move a plate from storage to the loading tray."]}, {"cell_type": "code", "execution_count": null, "id": "632ec3f7", "metadata": {}, "outputs": [], "source": ["await incubator.fetch_plate_to_loading_tray(\"my_plate\")\n", "retrieved = incubator.loading_tray.resource"]}, {"cell_type": "markdown", "id": "7dc4dfb9", "metadata": {}, "source": ["## Monitoring conditions\n", "\n", "The Cytomat provides queries for temperature and humidity."]}, {"cell_type": "code", "execution_count": null, "id": "0d768495", "metadata": {}, "outputs": [], "source": ["current_temp = await incubator.get_temperature()\n", "current_humidity = await incubator.backend.get_humidity()\n", "print(current_temp, current_humidity)"]}, {"cell_type": "markdown", "id": "7c27b01e", "metadata": {}, "source": ["## Shutdown\n", "\n", "Always close the connection when finished."]}, {"cell_type": "code", "execution_count": null, "id": "28b68d42", "metadata": {}, "outputs": [], "source": ["await incubator.stop()"]}], "metadata": {"jupytext": {"cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all"}}, "nbformat": 4, "nbformat_minor": 5}