Skip to content

Commit

Permalink
Merge branch 'edge' into E2E_Transfer_and_Command_update
Browse files Browse the repository at this point in the history
  • Loading branch information
alexjoel42 authored Jan 6, 2025
2 parents e60771b + b27238e commit 79531ef
Show file tree
Hide file tree
Showing 32 changed files with 14,677 additions and 22 deletions.
17 changes: 17 additions & 0 deletions analyses-snapshot-testing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,20 @@ You have the option to specify one or many protocols to run the analyses on. Thi
### Updating the snapshots locally

- `make snapshot-test-update-local` - this target builds the base image, builds the local code into the base image, then runs the analyses battery against the image you just created, updating the snapshots by passing the `--update-snapshots` flag to the test

### Add some protocols to the analyses battery

> The below instructions avoid needing docker and executing snapshot tests locally.

1. create new protocol file(s) in the [files/protocols](./files/protocols) directory following the naming convention in [files/README.md](./files/README.md)
1. add the protocol(s) to the [protocols.py](./automation/data/protocols.py)
1. `make format` (make sure you have followed setup instructions)
1. commit and push your branch
1. open a PR and add the label `gen-analyses-snapshot-pr`
1. when the snapshot fails because your new protocols don't have snapshots a PR will be created that heals.
1. merge the healing PR if the snapshots are as expected
1. get a review and merge! 🎉 now your protocols are a part of the test
### Add a protocol with overrides to the analyses battery
> TODO when we have a more straight forward example
42 changes: 42 additions & 0 deletions analyses-snapshot-testing/automation/data/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,48 @@ class Protocols:
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_X_v2_21_plate_reader_no_trash.py
Flex_X_v2_21_plate_reader_no_trash: Protocol = Protocol(
file_stem="Flex_X_v2_21_plate_reader_no_trash",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_X_v2_21_plate_reader_wrong_plate.py
Flex_X_v2_21_plate_reader_wrong_plate: Protocol = Protocol(
file_stem="Flex_X_v2_21_plate_reader_wrong_plate",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_X_v2_21_plate_reader_wrong_plate2.py
Flex_X_v2_21_plate_reader_wrong_plate2: Protocol = Protocol(
file_stem="Flex_X_v2_21_plate_reader_wrong_plate2",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_X_v2_21_plate_reader_bad_slot.py
Flex_X_v2_21_plate_reader_bad_slot: Protocol = Protocol(
file_stem="Flex_X_v2_21_plate_reader_bad_slot",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_X_v2_21_plate_reader_no_close_lid.py
Flex_X_v2_21_plate_reader_no_close_lid: Protocol = Protocol(
file_stem="Flex_X_v2_21_plate_reader_no_close_lid",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_21_tc_lids_happy_path.py
Flex_S_v2_21_tc_lids_happy_path: Protocol = Protocol(
file_stem="Flex_S_v2_21_tc_lids_happy_path",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_X_v2_21_tc_lids_wrong_target.py
Flex_X_v2_21_tc_lids_wrong_target: Protocol = Protocol(
file_stem="Flex_X_v2_21_tc_lids_wrong_target",
file_extension="py",
robot="Flex",
)

OT2_X_v2_18_None_None_duplicateRTPVariableName: Protocol = Protocol(
file_stem="OT2_X_v2_18_None_None_duplicateRTPVariableName",
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from typing import List, Dict, Any, Optional
from opentrons.protocol_api import ProtocolContext, Labware

metadata = {"protocolName": "Opentrons Flex Deck Riser with TC Lids Test"}
requirements = {"robotType": "Flex", "apiLevel": "2.21"}


"""
Setup:
- 1-5x lids are stacked in deck D2
- Thermocycler installed
Run:
- For each lid in the stack (1-5x)
- Move lid in D2 to Thermocycler
- Remove top-most lid
- PAUSE, wait for tester to press continue
- Move lid from Thermocycler to new slot C2
- Stacked onto any previously placed lids
"""

LID_STARTING_SLOT = "B2"
LID_ENDING_SLOT = "C2"
LID_COUNT = 3
LID_DEFINITION = "opentrons_tough_pcr_auto_sealing_lid"
LID_BOTTOM_DEFINITION = "opentrons_tough_pcr_auto_sealing_lid"
DECK_RISER_NAME = "opentrons_flex_deck_riser"
USING_THERMOCYCLER = True

OFFSET_DECK = {
"pick-up": {"x": 0, "y": 0, "z": 0},
"drop": {"x": 0, "y": 0, "z": 0},
}
OFFSET_THERMOCYCLER = {
"pick-up": {"x": 0, "y": 0, "z": 0},
"drop": {"x": 0, "y": 0, "z": 0},
}


def _move_labware_with_offset_and_pause(
protocol: ProtocolContext,
labware: Labware,
destination: Any,
pick_up_offset: Optional[Dict[str, float]] = None,
drop_offset: Optional[Dict[str, float]] = None,
) -> None:
protocol.move_labware(
labware,
destination,
use_gripper=True,
pick_up_offset=pick_up_offset,
drop_offset=drop_offset,
)


def run(protocol: ProtocolContext):
# SETUP
deck_riser_adapter = protocol.load_adapter(DECK_RISER_NAME, "B2")

lids: List[Labware] = [deck_riser_adapter.load_labware(LID_BOTTOM_DEFINITION)]
for i in range(LID_COUNT - 1):
lids.append(lids[-1].load_labware(LID_DEFINITION))
lids.reverse() # NOTE: reversing to more easily loop through lids from top-to-bottom
if USING_THERMOCYCLER:
# TODO: confirm if we need to load 96-well adapter onto Thermocycler
thermocycler = protocol.load_module("thermocyclerModuleV2")
thermocycler.open_lid()
plate_in_cycler = thermocycler.load_labware("armadillo_96_wellplate_200ul_pcr_full_skirt")
else:
plate_in_cycler = None

# RUN
prev_moved_lid: Optional[Labware] = None
for lid in lids:

if USING_THERMOCYCLER:
_move_labware_with_offset_and_pause(
protocol,
lid,
plate_in_cycler,
pick_up_offset=OFFSET_DECK["pick-up"],
drop_offset=OFFSET_THERMOCYCLER["drop"],
)
_move_labware_with_offset_and_pause(
protocol,
lid,
prev_moved_lid if prev_moved_lid else LID_ENDING_SLOT,
pick_up_offset=OFFSET_THERMOCYCLER["pick-up"],
drop_offset=OFFSET_DECK["drop"],
)
else:
_move_labware_with_offset_and_pause(
protocol,
lid,
prev_moved_lid if prev_moved_lid else LID_ENDING_SLOT,
pick_up_offset=OFFSET_DECK["pick-up"],
drop_offset=OFFSET_DECK["drop"],
)
prev_moved_lid = lid
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import cast
from opentrons import protocol_api
from opentrons.protocol_api.module_contexts import AbsorbanceReaderContext

from opentrons import protocol_api
from opentrons.protocol_api import SINGLE, ALL

requirements = {"robotType": "Flex", "apiLevel": "2.21"}
metadata = {"protocolName": "plate_reader bad slot"}


def run(protocol: protocol_api.ProtocolContext):
partial_rack = protocol.load_labware(load_name="opentrons_flex_96_tiprack_1000ul", location="D3")
trash = protocol.load_trash_bin("A3")
instrument = protocol.load_instrument(instrument_name="flex_8channel_1000", mount="right")
instrument.configure_nozzle_layout(style=SINGLE, start="H1", tip_racks=[partial_rack])

plate_1 = protocol.load_labware("nest_96_wellplate_200ul_flat", "D1")
mod = protocol.load_module("absorbanceReaderV1", "C1")
mod.open_lid()
protocol.move_labware(plate_1, mod, use_gripper=True)
mod.close_lid()
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from typing import cast
from opentrons import protocol_api
from opentrons.protocol_api.module_contexts import AbsorbanceReaderContext

# metadata
metadata = {
"protocolName": "Absorbance Reader no close lid",
"author": "Platform Expansion",
}

requirements = {
"robotType": "Flex",
"apiLevel": "2.21",
}


# protocol run function
def run(protocol: protocol_api.ProtocolContext):
mod = cast(AbsorbanceReaderContext, protocol.load_module("absorbanceReaderV1", "D3"))
plate = protocol.load_labware("nest_96_wellplate_200ul_flat", "C2")
tiprack_1000 = protocol.load_labware(load_name="opentrons_flex_96_tiprack_50ul", location="B2")
trash_labware = protocol.load_trash_bin("B3")
instrument = protocol.load_instrument("flex_8channel_50", "right", tip_racks=[tiprack_1000])

# pick up tip and perform action
instrument.pick_up_tip(tiprack_1000.wells_by_name()["A1"])
instrument.aspirate(30, plate.wells_by_name()["A1"])
instrument.dispense(30, plate.wells_by_name()["B1"])
instrument.return_tip()

# Initialize to a single wavelength with reference wavelength
# Issue: Make sure there is no labware here or youll get an error
# mod.close_lid()
mod.initialize("single", [600], 450)

# NOTE: CANNOT INITIALIZE WITH THE LID OPEN

# Remove the Plate Reader lid using the Gripper.
mod.open_lid()
protocol.move_labware(plate, mod, use_gripper=True)
mod.close_lid()

# Take a reading and show the resulting absorbance values.
# Issue: cant read before you initialize or you an get an error
result = mod.read()
msg = f"single: {result}"
protocol.comment(msg=msg)
protocol.pause(msg=msg)

# Initialize to multiple wavelengths
protocol.pause(msg="Perform Multi Read")
mod.open_lid()
protocol.move_labware(plate, "C2", use_gripper=True)

mod.close_lid()

# mod.initialize('multi', [450, 570, 600])
mod.initialize("multi", [450, 600])
# Open the lid and move the labware into the reader
mod.open_lid()
protocol.move_labware(plate, mod, use_gripper=True)

# pick up tip and perform action on labware inside plate reader
instrument.pick_up_tip(tiprack_1000.wells_by_name()["A1"])
instrument.aspirate(30, plate.wells_by_name()["A1"])
instrument.dispense(30, plate.wells_by_name()["B1"])
instrument.return_tip()

mod.close_lid()

# Take reading
result = mod.read()
msg = f"multi: {result}"
protocol.comment(msg=msg)
protocol.pause(msg=msg)

# Take a reading and save to csv
protocol.pause(msg="Perform Read and Save to CSV")
result = mod.read(export_filename="plate_reader_csv.csv")
msg = f"csv: {result}"
protocol.pause(msg=msg)

# Place the Plate Reader lid back on using the Gripper.
mod.open_lid()
protocol.move_labware(plate, "C2", use_gripper=True)
mod.close_lid()

mod.read(export_filename="csv_name.csv")
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import cast
from opentrons import protocol_api
from opentrons.protocol_api.module_contexts import AbsorbanceReaderContext

from opentrons import protocol_api
from opentrons.protocol_api import SINGLE, ALL

requirements = {"robotType": "Flex", "apiLevel": "2.21"}
metadata = {"protocolName": "plate_reader no trash"}


def run(protocol: protocol_api.ProtocolContext):
partial_rack = protocol.load_labware(load_name="opentrons_flex_96_tiprack_1000ul", location="D2")
trash = protocol.load_trash_bin("A3")
instrument = protocol.load_instrument(instrument_name="flex_8channel_1000", mount="right")
instrument.configure_nozzle_layout(style=SINGLE, start="H1", tip_racks=[partial_rack])

plate_1 = protocol.load_labware("nest_96_wellplate_200ul_flat", "C1")

mod = protocol.load_module("absorbanceReaderV1", "B3")

mod.open_lid()
protocol.move_labware(plate_1, mod, use_gripper=True)
protocol.move_labware(plate_1, trash, use_gripper=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import cast
from opentrons import protocol_api
from opentrons.protocol_api.module_contexts import AbsorbanceReaderContext

from opentrons import protocol_api
from opentrons.protocol_api import SINGLE, ALL

requirements = {"robotType": "Flex", "apiLevel": "2.21"}
metadata = {"protocolName": "plate_reader wrong plate"}


def run(protocol: protocol_api.ProtocolContext):
partial_rack = protocol.load_labware(load_name="opentrons_flex_96_tiprack_1000ul", location="D2")
trash = protocol.load_trash_bin("A3")
instrument = protocol.load_instrument(instrument_name="flex_8channel_1000", mount="right")
instrument.configure_nozzle_layout(style=SINGLE, start="H1", tip_racks=[partial_rack])

plate_1 = protocol.load_labware("corning_12_wellplate_6.9ml_flat", "C2")

mod = protocol.load_module("absorbanceReaderV1", "B3")

mod.open_lid()
protocol.move_labware(plate_1, mod, use_gripper=True)
protocol.move_labware(plate_1, trash, use_gripper=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import cast
from opentrons import protocol_api
from opentrons.protocol_api.module_contexts import AbsorbanceReaderContext

from opentrons import protocol_api
from opentrons.protocol_api import SINGLE, ALL

requirements = {"robotType": "Flex", "apiLevel": "2.21"}
metadata = {"protocolName": "plate_reader wrong plate"}


def run(protocol: protocol_api.ProtocolContext):
partial_rack = protocol.load_labware(load_name="opentrons_flex_96_tiprack_1000ul", location="D2")
trash = protocol.load_trash_bin("A3")
instrument = protocol.load_instrument(instrument_name="flex_8channel_1000", mount="right")
instrument.configure_nozzle_layout(style=SINGLE, start="H1", tip_racks=[partial_rack])

plate_1 = protocol.load_labware("thermoscientificnunc_96_wellplate_2000ul", "C2")

mod = protocol.load_module("absorbanceReaderV1", "B3")

mod.open_lid()
protocol.move_labware(plate_1, mod, use_gripper=True)
protocol.move_labware(plate_1, trash, use_gripper=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import List, Dict, Any, Optional
from opentrons.protocol_api import ProtocolContext, Labware

metadata = {"Stacking a deep well plate on its adapter "}
requirements = {"robotType": "Flex", "apiLevel": "2.21"}


def run(protocol: ProtocolContext):
temp_mod = protocol.load_module(module_name="temperature module gen2", location="D1")
LID_COUNT = 5
LID_DEFINITION = "opentrons_tough_pcr_auto_sealing_lid"
LID_BOTTOM_DEFINITION = "opentrons_tough_pcr_auto_sealing_lid"
adapter = temp_mod.load_adapter("opentrons_96_deep_well_temp_mod_adapter")
stack = protocol.load_labware("nest_96_wellplate_2ml_deep", "A1")
deck_riser_adapter = protocol.load_adapter("opentrons_flex_deck_riser", "B2")
protocol.move_labware(stack, adapter)
lids = [deck_riser_adapter.load_labware(LID_BOTTOM_DEFINITION, "D2")]
for i in range(LID_COUNT - 1):
lids.append(lids[-1].load_labware(LID_DEFINITION))
lids.reverse() # NOTE: reversing to more easily loop through lids from top-to-bottom

protocol.move_labware(
lids[0],
stack,
use_gripper=True,
)
Loading

0 comments on commit 79531ef

Please sign in to comment.