Skip to content

Commit 1c67288

Browse files
committed
tests for rpl ot2 gamma
1 parent 47e6f76 commit 1c67288

3 files changed

Lines changed: 298 additions & 0 deletions

File tree

tests/basic_config_alpha.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""basic config module"""
2+
from opentrons import protocol_api
3+
4+
metadata = {
5+
"protocolName": "Example Name",
6+
"author": "Kyle khippe@anl.gov",
7+
"description": "basic_config.yml",
8+
"apiLevel": "2.12",
9+
}
10+
11+
12+
def run(protocol: protocol_api.ProtocolContext):
13+
"""run basic config"""
14+
deck = {}
15+
pipettes = {}
16+
17+
################
18+
# load labware #
19+
################
20+
deck["2"] = protocol.load_labware("corning_96_wellplate_360ul_flat", "2")
21+
deck["3"] = protocol.load_labware("corning_96_wellplate_360ul_flat", "3")
22+
deck["8"] = protocol.load_labware("opentrons_96_tiprack_20ul", "8")
23+
pipettes["right"] = protocol.load_instrument(
24+
"p20_single_gen2", "left", tip_racks=[deck["8"]]
25+
)
26+
27+
####################
28+
# execute commands #
29+
####################
30+
31+
# example command
32+
pipettes["right"].pick_up_tip(deck["8"].wells()[0])
33+
pipettes["right"].aspirate(10, deck["2"]["A1"])
34+
pipettes["right"].dispense(10, deck["3"]["A1"])
35+
pipettes["right"].drop_tip()
36+
37+
# other command
38+
# pipettes["right"].pick_up_tip(deck["8"].wells()[1])
39+
# pipettes["right"].aspirate(10, deck["2"]["A2"])
40+
# pipettes["right"].dispense(10, deck["3"]["A2"])
41+
# pipettes["right"].drop_tip()

tests/run_ot2_wf.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Run OT-2 Protocol WF
2+
3+
metadata:
4+
author: Abe Stroka
5+
info: Workflow for running one OT-2 protocol from payload
6+
version: '0.1'
7+
8+
parameters:
9+
file_inputs:
10+
- key: ot2_protocol
11+
12+
steps:
13+
# Run OT-2 protocol
14+
- name: Run OT-2 patrick
15+
node: ot2_gamma
16+
action: run_protocol
17+
files:
18+
protocol: ot2_protocol

tests/test_resource_exp.py

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
#!/usr/bin/env python3
2+
"""Experiment application for the Protein Design experiment"""
3+
4+
import time
5+
from datetime import datetime
6+
from pathlib import Path
7+
8+
from madsci.common.types.experiment_types import ExperimentDesign
9+
from madsci.client import ExperimentClient, WorkcellClient, LocationClient, ResourceClient
10+
from madsci.common.types.node_types import NodeDefinition
11+
from madsci.common.types.resource_types import Resource
12+
from madsci.experiment_application import (
13+
ExperimentApplication,
14+
ExperimentApplicationConfig,
15+
)
16+
from pydantic import AnyUrl
17+
18+
# import helper_functions
19+
20+
21+
22+
23+
24+
class PDApp(ExperimentApplication):
25+
"""PD Experiment Application
26+
27+
# TODO:
28+
29+
"""
30+
31+
experiment_design = ExperimentDesign(
32+
experiment_name="PD_App",
33+
)
34+
config = ExperimentApplicationConfig(node_url=AnyUrl("http://localhost:6000"))
35+
experiment_client = ExperimentClient()
36+
workcell_client = WorkcellClient()
37+
location_client = LocationClient()
38+
resource_client = ResourceClient()
39+
experiment_id = None
40+
experiment_label = None
41+
42+
43+
def __init__(self) -> None:
44+
"""Initializes the PD Experiment App"""
45+
46+
super().__init__()
47+
self.init_assay_plate_resource_template()
48+
49+
def init_assay_plate_resource_template(self):
50+
"""Initializes assay plate resource template"""
51+
52+
self.resource_client.create_template(
53+
resource=Resource(
54+
resource_description="NEST PCR plate 200ul",
55+
),
56+
template_name="opentrons_96_wellplate_200ul_pcr_full_skirt",
57+
description="Template for 200ul PCR plate",
58+
tags=["Plate", "ANSI/SLAS", "96 Well", "PCR", "Labware"],
59+
)
60+
61+
self.resource_client.create_template(
62+
resource=Resource(
63+
resource_description="ot2 20ul tiprack",
64+
),
65+
template_name="opentrons_96_filtertiprack_20ul",
66+
description="Template for ot2 20ul tiprack",
67+
tags=["Tiprack", "ANSI/SLAS", "96 Well", "Labware"],
68+
)
69+
70+
self.resource_client.create_template(
71+
resource=Resource(
72+
resource_description="otflex 50ul tiprack",
73+
),
74+
template_name="opentrons_flex_96_filtertiprack_50ul",
75+
description="Template for OT-Flex 50ul tiprack",
76+
tags=["Tiprack", "ANSI/SLAS", "96 Well", "Labware"],
77+
)
78+
79+
self.resource_client.create_template(
80+
resource=Resource(
81+
resource_description="otflex 200ul tiprack",
82+
),
83+
template_name="opentrons_flex_96_filtertiprack_200ul",
84+
description="Template for 200ul OT-Flex tiprack",
85+
tags=["Tiprack", "ANSI/SLAS", "96 Well", "Labware"],
86+
)
87+
88+
89+
def push_new_assay_plate_resource(
90+
self,
91+
plate_num: int,
92+
location_name: str,
93+
experiment_id: int,
94+
name: str,
95+
) -> None | Resource:
96+
"""
97+
Pushes a new assay plate resource into the specified location, popping an existing plate in that location if necessary.
98+
"""
99+
# get the resource id of the resource associated with the given location
100+
associated_resource_id = self.location_client.get_location_by_name(location_name).resource_id
101+
print("Location name: ", location_name)
102+
print("ASSC Resource id: ", associated_resource_id)
103+
# get the resource object from the resource id
104+
resource_object = self.resource_client.get_resource(associated_resource_id)
105+
106+
# check if the resource object currently has child resources (a plate already at that location)
107+
old_plate = None
108+
if resource_object.child:
109+
# there is already a plate at this location
110+
self.logger.log_info(f"A plate with ID {resource_object.child.resource_id} already exists at location: {location_name}")
111+
112+
# pop the old plate
113+
popped_plate, updated_parent = self.resource_client.pop(resource=associated_resource_id)
114+
self.logger.log_info(f"Popped plate with ID {resource_object.child.resource_id} from location: {location_name}")
115+
old_plate = popped_plate
116+
117+
118+
# create a new assay plate resource and push it into the resource object associated with the given location
119+
# if name == "opentrons_96_wellplate_200ul_pcr_full_skirt":
120+
121+
new_plate = self.resource_client.create_resource_from_template(
122+
template_name = name,
123+
resource_name = f"res_{experiment_id}_plate{plate_num}",
124+
)
125+
126+
self.logger.log_info(f"Created new plate resource {new_plate.resource_name}, {new_plate.resource_id}")
127+
128+
self.resource_client.push(
129+
resource = associated_resource_id,
130+
child = new_plate.resource_id,
131+
)
132+
self.logger.log_info(f"Pushed new plate resource into location {location_name}")
133+
return new_plate, old_plate
134+
135+
def run_experiment(self) -> None:
136+
"""main experiment function"""
137+
138+
#TODO: plate starting on ot2 patrick deck 6 on temp block
139+
# new_plate, old_plate = self.push_new_assay_plate_resource(
140+
# location_name="ot2_patrick_nest6_temp_block_wide",
141+
# )
142+
143+
# DEFINE PATHS AND VARIABLES ========
144+
run_robots = False # if False, no robots will run
145+
run_resources = True
146+
test_prints = True # if True, will print out extra info for testing purposes
147+
148+
# Experiment ID and name
149+
experiment_id = self.experiment.experiment_id
150+
experiment_label = "1"
151+
152+
# Directory paths
153+
app_directory = Path(__file__).parent.parent # experiment app
154+
wf_directory = app_directory / "workflows" # workflows
155+
run_directory = wf_directory / "run_instrument"
156+
transfers_directory = wf_directory / "transfers"
157+
protocol_directory = app_directory / "protocols" # protocols
158+
159+
# Workflow paths
160+
run_ot2_wf = "run_ot2_wf.yaml"
161+
run_thermo_wf = run_directory / "run_thermo.yaml"
162+
163+
ot2_to_thermocycler = (
164+
transfers_directory / "ot2_to_thermocycler.yaml"
165+
)
166+
167+
168+
# Protocol paths (for OT-2)
169+
golden_gate_protocol = protocol_directory / "pd_golden_gate_ot2_v2.py"
170+
171+
seal_and_thermocycle = (
172+
transfers_directory / "seal_and_thermocycle_pcr.yaml"
173+
)
174+
175+
payload = {}
176+
177+
temp_ot2_file_str = "basic_config_alpha.py"
178+
179+
# combination_data = self.rest_handler.collect_combinations(oracle_id=1008)
180+
# print("combination_data", combination_data)
181+
# print(combination_data["combinations"])
182+
# print(combination_data["use_combinations"])
183+
# print(combination_data["non_combinatorial_sources"])
184+
185+
# payload["combinations"] = combination_data["combinations"]
186+
# payload["use_combinations"] = combination_data["use_combinations"]
187+
# payload["non_combinatorial_sources"] = combination_data["non_combinatorial_sources"]
188+
189+
190+
191+
# EXPERIMENT ACTIONS -------------------------------------------------------
192+
193+
# run ot2 protocol step 1
194+
# ot2_replacement_variables = helper_functions.collect_ot2_replacement_variables(payload)
195+
# temp_ot2_file_str = helper_functions.generate_ot2_protocol(golden_gate_protocol, ot2_replacement_variables)
196+
payload["current_ot2_protocol"] = temp_ot2_file_str
197+
workflow = self.workcell_client.submit_workflow(
198+
run_ot2_wf.resolve(),
199+
file_inputs={
200+
"ot2_protocol": payload["current_ot2_protocol"],
201+
},
202+
)
203+
204+
###### depending on combinatorial length, will need additional tips
205+
#swap tip boxes
206+
207+
#run ot2 protocol step 2
208+
209+
#swap tip boxes
210+
211+
#run ot2 protocol step 3 with master mix multi dispense
212+
213+
#########################
214+
215+
# transfer destination plate to thermocycler and run
216+
# workflow = self.workcell_client.submit_workflow(
217+
# seal_and_thermocycle.resolve(),
218+
# )
219+
220+
# #run thermocycler
221+
# workflow = self.workcell_client.submit_workflow(
222+
# run_thermo_wf.resolve(),
223+
# )
224+
225+
226+
227+
228+
229+
if __name__ == "__main__":
230+
exp_app = PDApp()
231+
232+
current_time = datetime.now()
233+
234+
# Start experiment run
235+
with exp_app.manage_experiment(
236+
run_name = f"PD_Experiment{current_time.strftime('%Y%m%d_%H%M%S')}",
237+
run_description = "PD experiment",
238+
):
239+
exp_app.start_app()

0 commit comments

Comments
 (0)