diff --git a/docs/resources/library/diy/grindbio.md b/docs/resources/library/diy/grindbio.md index 2ab0a5bea0e..0194dffe70b 100644 --- a/docs/resources/library/diy/grindbio.md +++ b/docs/resources/library/diy/grindbio.md @@ -6,3 +6,8 @@ GrindBio created a 3D printed part for one of the Hamilton modules (cat.-no. 188 | Description | Image | PLR definition | | - | - | - | | 'Hamilton_MFX_plateholder_DWP_metal_tapped_10mm_3dprint'
3D printed supports accept Hamilton MFX DWP Module (cat.-no. 188042 / 188042-00)
[OnShape link to part](https://cad.onshape.com/documents/87b79aea22945656e1849b61/w/1d28384d184c23a6551facf8/e/3313021cc0b2fe3c5e005547)
Read more about assembly [here](https://labautomation.io/t/adapters-for-hamilton-carrier-188039/6561)| ![](../img/grindbio/3d-supports-for-Hamilton-module.jpeg) | `Hamilton_MFX_plateholder_DWP_metal_tapped_10mm_3dprint` | + +## Pioreactor Plate Adapter +This ANSI-compatible adapter allows the Pioreactor to be placed on the deck. +https://cad.onshape.com/documents/cae54894e48b6624a361b53a/w/b1eaa767347c60ba70d74e31/e/cd40414a831dd21eb4ae1235 + diff --git a/docs/resources/library/img/pioreactor/pioreactor_20mL.png b/docs/resources/library/img/pioreactor/pioreactor_20mL.png new file mode 100644 index 00000000000..5692ab0e897 Binary files /dev/null and b/docs/resources/library/img/pioreactor/pioreactor_20mL.png differ diff --git a/docs/resources/library/pioreactor.md b/docs/resources/library/pioreactor.md new file mode 100644 index 00000000000..518a4717ddb --- /dev/null +++ b/docs/resources/library/pioreactor.md @@ -0,0 +1,9 @@ +# Pioreactor + +Pioreactor is a modular, open-source benchtop bioreactor system designed for running many small, parallel microbial cultivations with tight control of key parameters (e.g., stirring, aeration, temperature, and dosing) and easy integration into automation workflows. In PyLabRobot, Pioreactor labware definitions let you reference Pioreactor vessels in deck layouts and liquid-handling protocols. + +## Bioreactors + +| Description | Image | PLR definition | +|-|-|-| +| `pioreactor_20ml` | ![](img/pioreactor/pioreactor_20mL.png) | `pioreactor_20ml` | diff --git a/pylabrobot/resources/pioreactor/__init__.py b/pylabrobot/resources/pioreactor/__init__.py new file mode 100644 index 00000000000..15ff2bd6e67 --- /dev/null +++ b/pylabrobot/resources/pioreactor/__init__.py @@ -0,0 +1 @@ +from .plates import * diff --git a/pylabrobot/resources/pioreactor/plates.py b/pylabrobot/resources/pioreactor/plates.py new file mode 100644 index 00000000000..d5b7998dd6c --- /dev/null +++ b/pylabrobot/resources/pioreactor/plates.py @@ -0,0 +1,70 @@ +from typing import Optional + +from pylabrobot.resources import Lid, Plate +from pylabrobot.resources.utils import create_ordered_items_2d +from pylabrobot.resources.well import CrossSectionType, Well, WellBottomType + + +def pioreactor_20ml(name: str, lid: Optional[Lid] = None) -> Plate: + """ + Pioreactor 20mL Vessel: https://pioreactor.com/products/pioreactor-20ml + Modeled as a 1x1 skirted plate + + Geometry (mm): + - Outer footprint (on holder): 127.74 x 85.40 + - Total height (plate Z): 126.5 + - Central vial (A1): inner Ø 23.5, depth 57.0 + """ + + # --- Outer dimensions (measured) --- + OUTER_X = 127.74 + OUTER_Y = 85.40 + OUTER_Z = 126.5 # overall height used for collision checks + + # --- Well (vial) geometry (spec/measured) --- + WELL_DIAMETER = 23.5 + WELL_DEPTH = 57.0 + MATERIAL_Z_THICKNESS = 1.0 # plastic between top surface and cavity start + + # Center the single circular well + dx = (OUTER_X - WELL_DIAMETER) / 2.0 + dy = (OUTER_Y - WELL_DIAMETER) / 2.0 + + # Distance from plate top to top of cavity + # dz = OUTER_Z - WELL_DEPTH - MATERIAL_Z_THICKNESS + # dz = 126.5-57 -1 =68.5 # tip crashes into bottom + dz = 76 # measured + + # Cylinder area for volume/height conversions + cross_section_area = 3.14 * (WELL_DIAMETER / 2.0) ** 2 + + well_kwargs = { + "size_x": WELL_DIAMETER, # for CIRCLE, size_x == size_y == diameter + "size_y": WELL_DIAMETER, + "size_z": WELL_DEPTH, + "bottom_type": WellBottomType.FLAT, + "cross_section_type": CrossSectionType.CIRCLE, + "compute_height_from_volume": lambda v: v / cross_section_area, + "compute_volume_from_height": lambda h: h * cross_section_area, + "material_z_thickness": MATERIAL_Z_THICKNESS, + } + + return Plate( + name=name, + size_x=OUTER_X, + size_y=OUTER_Y, + size_z=OUTER_Z, + lid=lid, + model="PioreactorPlate", + ordered_items=create_ordered_items_2d( + Well, + num_items_x=1, + num_items_y=1, + dx=dx, + dy=dy, + dz=dz, + item_dx=WELL_DIAMETER, + item_dy=WELL_DIAMETER, + **well_kwargs, + ), + )