{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Inheco ODTC (On Deck Thermal Cycler)\n", "\n", "The Inheco ODTC is an on-deck thermal cycler designed for automated PCR workflows. It features:\n", "\n", "- Precise temperature control for PCR cycling\n", "- Heated lid to prevent condensation\n", "- Motorized door for automated plate handling\n", "- SiLA 2 communication interface\n", "\n", "**Specifications:**\n", "- Temperature range: 4°C to 99°C\n", "- Heating/cooling rate: up to 4.4°C/s\n", "- 96-well plate format\n", "\n", "See the [Inheco ODTC product page](https://www.inheco.com/odtc.html) for more information." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Setup\n", "\n", "The ODTC communicates over Ethernet using the SiLA 2 protocol. You'll need:\n", "1. The IP address of the ODTC\n", "2. Network connectivity between your computer and the ODTC" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pylabrobot.resources.coordinate import Coordinate\n", "from pylabrobot.thermocycling.inheco import ExperimentalODTCBackend\n", "from pylabrobot.thermocycling.thermocycler import Thermocycler\n", "\n", "odtc = Thermocycler(\n", " name=\"odtc\",\n", " size_x=159.0,\n", " size_y=245.0,\n", " size_z=228.0,\n", " backend=ExperimentalODTCBackend(ip=\"169.254.151.99\"), # Replace with your ODTC's IP address\n", " child_location=Coordinate(0, 0, 0) # TODO: resource modeling...\n", ")\n", "await odtc.setup()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Door Control\n", "\n", "Open and close the door for plate access:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "await odtc.open_lid()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "await odtc.close_lid()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Temperature Control\n", "\n", "### Reading Sensor Data\n", "\n", "Get current temperatures from all sensors:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sensor_data = await odtc.backend.get_sensor_data()\n", "print(sensor_data)\n", "# Example output:\n", "# {'Mount': 25.0, 'Mount_Monitor': 25.1, 'Lid': 30.0, 'Lid_Monitor': 30.1,\n", "# 'Ambient': 22.0, 'PCB': 28.0, 'Heatsink': 26.0, 'Heatsink_TEC': 25.5}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setting Block Temperature\n", "\n", "Set a constant block temperature. Note that the ODTC uses a \"pre-method\" approach which takes several minutes to stabilize:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "await odtc.set_block_temperature([37.0]) # Set to 37°C" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Check current block temperature\n", "temp = await odtc.get_block_current_temperature()\n", "print(f\"Block temperature: {temp[0]}°C\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Deactivating Temperature Control" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "await odtc.deactivate_block()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Running PCR Protocols\n", "\n", "The ODTC can run complex PCR protocols defined using `Protocol`, `Stage`, and `Step` objects.\n", "\n", "### Defining a Protocol\n", "\n", "A protocol consists of stages, each containing steps with temperature and hold time. Stages can repeat multiple times for cycling." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pylabrobot.thermocycling.standard import Protocol, Stage, Step\n", "\n", "# Example: Standard 3-step PCR protocol\n", "pcr_protocol = Protocol(\n", " stages=[\n", " # Initial denaturation\n", " Stage(\n", " steps=[Step(temperature=[95.0], hold_seconds=300)], # 95°C for 5 min\n", " repeats=1\n", " ),\n", " # PCR cycling (30 cycles)\n", " Stage(\n", " steps=[\n", " Step(temperature=[95.0], hold_seconds=30), # Denature: 95°C for 30s\n", " Step(temperature=[55.0], hold_seconds=30), # Anneal: 55°C for 30s\n", " Step(temperature=[72.0], hold_seconds=60), # Extend: 72°C for 60s\n", " ],\n", " repeats=30\n", " ),\n", " # Final extension\n", " Stage(\n", " steps=[Step(temperature=[72.0], hold_seconds=600)], # 72°C for 10 min\n", " repeats=1\n", " ),\n", " # Hold\n", " Stage(\n", " steps=[Step(temperature=[4.0], hold_seconds=0)], # 4°C hold\n", " repeats=1\n", " ),\n", " ]\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Running the Protocol" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "await odtc.run_protocol(\n", " protocol=pcr_protocol,\n", " block_max_volume=20.0, # Maximum sample volume in µL\n", " start_block_temperature=25.0, # Starting block temperature\n", " start_lid_temperature=105.0, # Lid temperature (typically 105°C to prevent condensation)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Custom Ramp Rates\n", "\n", "You can specify custom temperature ramp rates for each step:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Protocol with custom ramp rates\n", "custom_protocol = Protocol(\n", " stages=[\n", " Stage(\n", " steps=[\n", " Step(temperature=[95.0], hold_seconds=60, rate=4.4), # Fast ramp (4.4°C/s)\n", " Step(temperature=[60.0], hold_seconds=30, rate=2.0), # Slower ramp (2.0°C/s)\n", " ],\n", " repeats=1\n", " ),\n", " ]\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "await odtc.run_protocol(\n", " protocol=custom_protocol,\n", " block_max_volume=25.0,\n", " start_block_temperature=25.0,\n", " start_lid_temperature=105.0,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Closing the Connection" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "await odtc.stop()" ] } ], "metadata": { "kernelspec": { "display_name": "env", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.24" } }, "nbformat": 4, "nbformat_minor": 4 }