Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into loadlc
Browse files Browse the repository at this point in the history
  • Loading branch information
ddcc4 committed Nov 15, 2024
2 parents d0c98c8 + 0110e17 commit b86fc64
Show file tree
Hide file tree
Showing 129 changed files with 4,444 additions and 2,562 deletions.
30 changes: 23 additions & 7 deletions .github/workflows/analyses-snapshot-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ jobs:
timeout-minutes: 15
runs-on: ubuntu-latest
env:
BASE_IMAGE_NAME: opentrons-python-base:3.10
ANALYSIS_REF: ${{ github.event.inputs.ANALYSIS_REF || github.head_ref || 'edge' }}
SNAPSHOT_REF: ${{ github.event.inputs.SNAPSHOT_REF || github.head_ref || 'edge' }}
# If we're running because of workflow_dispatch, use the user input to decide
# whether to open a PR on failure. Otherwise, there is no user input,
# so we only open a PR if the PR has the label 'gen-analyses-snapshot-pr'
OPEN_PR_ON_FAILURE: ${{ (github.event_name == 'workflow_dispatch' && github.events.inputs.OPEN_PR_ON_FAILURE) || ((github.event_name != 'workflow_dispatch') && (contains(github.event.pull_request.labels.*.name, 'gen-analyses-snapshot-pr'))) }}
OPEN_PR_ON_FAILURE: ${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.OPEN_PR_ON_FAILURE) || ((github.event_name != 'workflow_dispatch') && (contains(github.event.pull_request.labels.*.name, 'gen-analyses-snapshot-pr'))) }}
PR_TARGET_BRANCH: ${{ github.event.pull_request.base.ref || 'not a pr'}}
steps:
- name: Checkout Repository
Expand All @@ -71,9 +72,24 @@ jobs:
echo "Analyses snapshots match ${{ env.PR_TARGET_BRANCH }} snapshots."
fi
- name: Docker Build
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build base image
id: build_base_image
uses: docker/build-push-action@v6
with:
context: analyses-snapshot-testing/citools
file: analyses-snapshot-testing/citools/Dockerfile.base
push: false
load: true
tags: ${{ env.BASE_IMAGE_NAME }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Build analysis image
working-directory: analyses-snapshot-testing
run: make build-opentrons-analysis
run: make build-opentrons-analysis BASE_IMAGE_NAME=${{ env.BASE_IMAGE_NAME }} ANALYSIS_REF=${{ env.ANALYSIS_REF }} CACHEBUST=${{ github.run_number }}

- name: Set up Python 3.13
uses: actions/setup-python@v5
Expand Down Expand Up @@ -112,8 +128,8 @@ jobs:
commit-message: 'fix(analyses-snapshot-testing): heal analyses snapshots'
title: 'fix(analyses-snapshot-testing): heal ${{ env.ANALYSIS_REF }} snapshots'
body: 'This PR was requested on the PR https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
branch: 'analyses-snapshot-testing/${{ env.ANALYSIS_REF }}-from-${{ env.SNAPSHOT_REF}}'
base: ${{ env.SNAPSHOT_REF}}
branch: 'analyses-snapshot-testing/${{ env.ANALYSIS_REF }}-from-${{ env.SNAPSHOT_REF }}'
base: ${{ env.SNAPSHOT_REF }}

- name: Comment on feature PR
if: always() && steps.create_pull_request.outcome == 'success' && github.event_name == 'pull_request'
Expand All @@ -135,5 +151,5 @@ jobs:
commit-message: 'fix(analyses-snapshot-testing): heal ${{ env.ANALYSIS_REF }} snapshots'
title: 'fix(analyses-snapshot-testing): heal ${{ env.ANALYSIS_REF }} snapshots'
body: 'The ${{ env.ANALYSIS_REF }} overnight analyses snapshot test is failing. This PR was opened to alert us to the failure.'
branch: 'analyses-snapshot-testing/${{ env.ANALYSIS_REF }}-from-${{ env.SNAPSHOT_REF}}'
base: ${{ env.SNAPSHOT_REF}}
branch: 'analyses-snapshot-testing/${{ env.ANALYSIS_REF }}-from-${{ env.SNAPSHOT_REF }}'
base: ${{ env.SNAPSHOT_REF }}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ def run(ctx: protocol_api.ProtocolContext) -> None:
bind_time_1 = bind_time_2 = wash_time = 0.25
drybeads = 0.5
lysis_rep_1 = lysis_rep_2 = bead_reps_2 = 1
PK_vol = 20.0
bead_vol = 25.0
starting_vol = lysis_vol + sample_vol
binding_buffer_vol = bind_vol + bead_vol
Expand Down Expand Up @@ -137,7 +136,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None:
"""
lysis_ = res1.wells()[0]
binding_buffer = res1.wells()[1:4]
bind2_res = res1.wells()[4:6]
bind2_res = res1.wells()[4:8]
wash1 = res1.wells()[6:8]
elution_solution = res1.wells()[-1]
wash2 = res2.wells()[:6]
Expand All @@ -149,16 +148,12 @@ def run(ctx: protocol_api.ProtocolContext) -> None:
samps = sample_plate.wells()[: (8 * num_cols)]

liquid_vols_and_wells: Dict[str, List[Dict[str, Well | List[Well] | float]]] = {
"Lysis": [{"well": lysis_, "volume": lysis_vol}],
"PK": [{"well": lysis_, "volume": PK_vol}],
"Beads": [{"well": binding_buffer, "volume": bead_vol}],
"Binding": [{"well": binding_buffer, "volume": bind_vol}],
"Binding 2": [{"well": bind2_res, "volume": bind2_vol}],
"Wash 1": [{"well": wash1_vol, "volume": wash1}],
"Wash 2": [{"well": wash2_vol, "volume": wash2}],
"Wash 3": [{"well": wash3_vol, "volume": wash3}],
"Final Elution": [{"well": elution_solution, "volume": elution_vol}],
"Samples": [{"well": samps, "volume": 0}],
"Lysis and PK": [{"well": lysis_, "volume": 12320.0}],
"Beads and Binding": [{"well": binding_buffer, "volume": 11875.0}],
"Binding 2": [{"well": bind2_res, "volume": 13500.0}],
"Final Elution": [{"well": elution_solution, "volume": 52000}],
"Samples": [{"well": samps, "volume": 0.0}],
"Reagents": [{"well": res2.wells(), "volume": 9000.0}],
}
flattened_list_of_wells = helpers.find_liquid_height_of_loaded_liquids(
ctx, liquid_vols_and_wells, m1000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,6 @@ def run(protocol: ProtocolContext) -> None:
style=SINGLE, start="H1", tip_racks=[tiprack_x_1, tiprack_x_2, tiprack_x_3]
)
helpers.find_liquid_height_of_all_wells(protocol, p1000, wells)
tiprack_x_1.reset()

sample_quant_csv = """
sample_plate_1, Sample_well,DYE,DILUENT
sample_plate_1,A1,0,100
Expand Down
26 changes: 25 additions & 1 deletion abr-testing/abr_testing/protocols/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
ThermocyclerContext,
TemperatureModuleContext,
)

from typing import List, Union, Dict
from opentrons.hardware_control.modules.types import ThermocyclerStep
from opentrons_shared_data.errors.exceptions import PipetteLiquidNotFoundError
Expand Down Expand Up @@ -225,6 +224,31 @@ def create_hs_speed_parameter(parameters: ParameterContext) -> None:
)


def create_tc_compatible_labware_parameter(parameters: ParameterContext) -> None:
"""Create parameter for labware type compatible with thermocycler."""
parameters.add_str(
variable_name="labware_tc_compatible",
display_name="Labware Type for Thermocycler",
description="labware compatible with thermocycler.",
default="biorad_96_wellplate_200ul_pcr",
choices=[
{
"display_name": "Armadillo_200ul",
"value": "armadillo_96_wellplate_200ul_pcr_full_skirt",
},
{"display_name": "Bio-Rad_200ul", "value": "biorad_96_wellplate_200ul_pcr"},
{
"display_name": "NEST_100ul",
"value": "nest_96_wellplate_100ul_pcr_full_skirt",
},
{
"display_name": "Opentrons_200ul",
"value": "opentrons_96_wellplate_200ul_pcr_full_skirt",
},
],
)


# FUNCTIONS FOR COMMON MODULE SEQUENCES


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,35 @@ def run(protocol: protocol_api.ProtocolContext) -> None:
res1 = protocol.load_labware("nest_12_reservoir_15ml", "C3", "R1")
res2 = protocol.load_labware("nest_12_reservoir_15ml", "B3", "R2")

lysis_and_pk = (3200 + 320) / 8
beads_and_binding = (275 + 6600) / 8
binding2 = 5500 / 8
wash1 = 5500 / 8
final_elution = 2100 / 8
lysis_and_pk = 12320 / 8
beads_and_binding = 11875 / 8
binding2 = 13500 / 8
wash2 = 9000 / 8
wash3 = 9000 / 8
wash2_list = [wash2] * 12
# Fill up Plates
# Res1
p1000.transfer(
volume=[lysis_and_pk, beads_and_binding, binding2, wash1, final_elution],
volume=[
lysis_and_pk,
beads_and_binding,
beads_and_binding,
beads_and_binding,
binding2,
binding2,
binding2,
binding2,
binding2,
],
source=source_reservoir["A1"].bottom(z=0.2),
dest=[
res1["A1"].top(),
res1["A2"].top(),
res1["A3"].top(),
res1["A4"].top(),
res1["A5"].top(),
res1["A6"].top(),
res1["A7"].top(),
res1["A8"].top(),
res1["A12"].top(),
],
blow_out=True,
Expand All @@ -54,9 +66,9 @@ def run(protocol: protocol_api.ProtocolContext) -> None:
)
# Res2
p1000.transfer(
volume=[wash2, wash3],
volume=wash2_list,
source=source_reservoir["A1"],
dest=[res2["A1"].top(), res2["A7"].top()],
dest=res2.wells(),
blow_out=True,
blowout_location="source well",
trash=False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,23 @@ def run(protocol: protocol_api.ProtocolContext) -> None:
res1 = protocol.load_labware("nest_12_reservoir_15ml", "D2", "reagent reservoir 1")
# Label Reservoirs
well1 = res1["A1"].top()
well2 = res1["A2"].top()
well3 = res1["A3"].top()
well4 = res1["A4"].top()
well5 = res1["A5"].top()
well6 = res1["A6"].top()
well7 = res1["A7"].top()
well8 = res1["A8"].top()
well9 = res1["A9"].top()
well10 = res1["A10"].top()

well11 = res1["A11"].top()
well12 = res1["A12"].top()
# Volumes
wash = 600
al_and_pk = 468
beads_and_binding = 552
binding = 320
beads = 230
pk = 230
lysis = 230

# Sample Plate
p1000.transfer(
Expand All @@ -65,9 +73,41 @@ def run(protocol: protocol_api.ProtocolContext) -> None:
)
# Res 1
p1000.transfer(
volume=[beads_and_binding, al_and_pk, wash, wash, wash],
volume=[
binding,
beads,
binding,
beads,
lysis,
pk,
wash,
wash,
wash,
wash,
wash,
wash,
wash,
wash,
wash,
],
source=source_reservoir["A1"].bottom(z=0.5),
dest=[well1, well3, well4, well7, well10],
dest=[
well1,
well1,
well2,
well2,
well3,
well3,
well4,
well5,
well6,
well7,
well8,
well9,
well10,
well11,
well12,
],
blowout=True,
blowout_location="source well",
trash=False,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"""Test TC Disposable Lid with BioRad Plate."""

from opentrons.protocol_api import (
ProtocolContext,
ParameterContext,
Well,
Labware,
InstrumentContext,
)
from typing import List
from abr_testing.protocols import helpers
from opentrons.protocol_api.module_contexts import ThermocyclerContext
from opentrons.hardware_control.modules.types import ThermocyclerStep

metadata = {"protocolName": "Tough Auto Seal Lid Evaporation Test"}
requirements = {"robotType": "Flex", "apiLevel": "2.21"}


def add_parameters(parameters: ParameterContext) -> None:
"""Add Parameters."""
helpers.create_single_pipette_mount_parameter(parameters)
helpers.create_tc_lid_deck_riser_parameter(parameters)
helpers.create_tc_compatible_labware_parameter(parameters)


def _pcr_cycle(thermocycler: ThermocyclerContext) -> None:
"""30x cycles of: 70° for 30s 72° for 30s 95° for 10s."""
profile_TAG2: List[ThermocyclerStep] = [
{"temperature": 70, "hold_time_seconds": 30},
{"temperature": 72, "hold_time_seconds": 30},
{"temperature": 95, "hold_time_seconds": 10},
]
thermocycler.execute_profile(
steps=profile_TAG2, repetitions=30, block_max_volume=50
)


def _fill_with_liquid_and_measure(
protocol: ProtocolContext,
pipette: InstrumentContext,
reservoir: Labware,
plate_in_cycler: Labware,
) -> None:
"""Fill plate with 10 ul per well."""
locations: List[Well] = [
plate_in_cycler["A1"],
plate_in_cycler["A2"],
plate_in_cycler["A3"],
plate_in_cycler["A4"],
plate_in_cycler["A5"],
plate_in_cycler["A6"],
plate_in_cycler["A7"],
plate_in_cycler["A8"],
plate_in_cycler["A9"],
plate_in_cycler["A10"],
plate_in_cycler["A11"],
plate_in_cycler["A12"],
]
volumes = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
protocol.pause("Weight Armadillo Plate, place on thermocycler")
# pipette 10uL into Armadillo wells
source_well: Well = reservoir["A1"]
pipette.distribute(
volume=volumes,
source=source_well,
dest=locations,
return_tips=True,
blow_out=False,
)
protocol.pause("Weight Armadillo Plate, place on thermocycler, put on lid")


def run(ctx: ProtocolContext) -> None:
"""Evaporation Test."""
pipette_mount = ctx.params.pipette_mount # type: ignore[attr-defined]
deck_riser = ctx.params.deck_riser # type: ignore[attr-defined]
labware_tc_compatible = ctx.params.labware_tc_compatible # type: ignore[attr-defined]
tiprack_50 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", "B2")
ctx.load_trash_bin("A3")
tc_mod: ThermocyclerContext = ctx.load_module(
helpers.tc_str
) # type: ignore[assignment]
plate_in_cycler = tc_mod.load_labware(labware_tc_compatible)
p50 = ctx.load_instrument("flex_8channel_50", pipette_mount, tip_racks=[tiprack_50])
unused_lids = helpers.load_disposable_lids(ctx, 5, ["D2"], deck_riser)
top_lid = unused_lids[0]
reservoir = ctx.load_labware("nest_12_reservoir_15ml", "A2")
tc_mod.open_lid()
tc_mod.set_block_temperature(4)
tc_mod.set_lid_temperature(105)

# hold at 95° for 3 minutes
profile_TAG: List[ThermocyclerStep] = [{"temperature": 95, "hold_time_minutes": 3}]
# hold at 72° for 5min
profile_TAG3: List[ThermocyclerStep] = [{"temperature": 72, "hold_time_minutes": 5}]
tc_mod.open_lid()
_fill_with_liquid_and_measure(ctx, p50, reservoir, plate_in_cycler)
ctx.move_labware(top_lid, plate_in_cycler, use_gripper=True)
tc_mod.close_lid()
tc_mod.execute_profile(steps=profile_TAG, repetitions=1, block_max_volume=50)
_pcr_cycle(tc_mod)
tc_mod.execute_profile(steps=profile_TAG3, repetitions=1, block_max_volume=50)
# # # Cool to 4°
tc_mod.set_block_temperature(4)
tc_mod.set_lid_temperature(105)
# Open lid
tc_mod.open_lid()
ctx.move_labware(top_lid, "C2", use_gripper=True)
ctx.move_labware(top_lid, unused_lids[1], use_gripper=True)
Loading

0 comments on commit b86fc64

Please sign in to comment.