Skip to content

Commit

Permalink
updated from edge. Hope it does not break anything.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexjoel42 committed Jan 15, 2025
2 parents 2227a2a + 9ab7ba9 commit 6aadcde
Show file tree
Hide file tree
Showing 356 changed files with 31,235 additions and 4,094 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/pd-test-build-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ jobs:
run: |
make -C protocol-designer NODE_ENV=development
- name: 'upload github artifact'
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: 'pd-artifact'
path: protocol-designer/dist
Expand Down Expand Up @@ -197,7 +197,7 @@ jobs:
const { buildComplexEnvVars } = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/utils.js`)
buildComplexEnvVars(core, context)
- name: 'download PD build'
uses: 'actions/download-artifact@v3'
uses: 'actions/download-artifact@v4'
with:
name: pd-artifact
path: ./dist
Expand Down
1 change: 1 addition & 0 deletions abr-testing/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pandas = "*"
pandas-stubs = "*"
paramiko = "*"
prettier = "*"
pydantic = "==2.9.0"

[dev-packages]
atomicwrites = "==1.4.1"
Expand Down
1,261 changes: 569 additions & 692 deletions abr-testing/Pipfile.lock

Large diffs are not rendered by default.

35 changes: 16 additions & 19 deletions abr-testing/abr_testing/data_collection/abr_robot_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ def retrieve_protocol_file(
) -> Path | str:
"""Find and copy protocol file on robot with error."""
protocol_dir = f"/var/lib/opentrons-robot-server/7.1/protocols/{protocol_id}"

print(f"FILE TO FIND: {protocol_dir}/{protocol_id}")
# Copy protocol file found in robot oto host computer
save_dir = Path(f"{storage}/protocol_errors")
# Copy protocol file found in robot onto host computer
save_dir = Path(f"{storage}")
command = ["scp", "-r", f"root@{robot_ip}:{protocol_dir}", save_dir]
try:
# If file found and copied return path to file
Expand Down Expand Up @@ -62,7 +60,6 @@ def compare_current_trh_to_average(
# Find average conditions of errored time period
df_all_trh = pd.DataFrame(all_trh_data)
# Convert timestamps to datetime objects
print(f'TIMESTAMP: {df_all_trh["Timestamp"]}')
try:
df_all_trh["Timestamp"] = pd.to_datetime(
df_all_trh["Timestamp"], format="mixed", utc=True
Expand Down Expand Up @@ -196,7 +193,6 @@ def read_each_log(folder_path: str, issue_url: str) -> None:
for file_name in os.listdir(folder_path):
file_path = os.path.join(folder_path, file_name)
not_found_words = []
print(file_path)
if file_path.endswith(".log"):
with open(file_path) as file:
lines = file.readlines()
Expand Down Expand Up @@ -341,11 +337,8 @@ def get_robot_state(
if "8.2" in affects_version:
labels.append("8_2_0")
parent = affects_version + " Bugs"
print(components)
end_time = datetime.now()
print(end_time)
start_time = end_time - timedelta(hours=2)
print(start_time)
# Get current temp/rh compared to historical data
temp_rh_string = compare_current_trh_to_average(
parent, start_time, end_time, "", storage_directory
Expand Down Expand Up @@ -554,11 +547,17 @@ def get_run_error_info_from_robot(
sys.exit()
if len(run_or_other) < 1:
# Retrieve the most recently run protocol file
protocol_files_path = retrieve_protocol_file(
protocol_folder = retrieve_protocol_file(
protocol_ids[-1], ip, storage_directory
)
protocol_folder_path = os.path.join(protocol_folder, protocol_ids[-1])
# Path to protocol folder
list_of_files = os.listdir(protocol_folder_path)
for file in list_of_files:
if str(file).endswith(".py"):
protocol_file_path = os.path.join(protocol_folder_path, file)
# Set protocol_found to true if python protocol was successfully copied over
if protocol_files_path:
if protocol_file_path:
protocol_found = True

one_run = error_runs[-1] # Most recent run with error.
Expand Down Expand Up @@ -612,15 +611,13 @@ def get_run_error_info_from_robot(
# OPEN TICKET
issue_url = ticket.open_issue(issue_key)
# MOVE FILES TO ERROR FOLDER.
print(protocol_files_path)
error_files = [saved_file_path_calibration, run_log_file_path] + file_paths

# Move protocol file(s) to error folder
if protocol_files_path:
for file in os.listdir(protocol_files_path):
error_files.append(os.path.join(protocol_files_path, file))
error_files = [
saved_file_path_calibration,
run_log_file_path,
protocol_file_path,
] + file_paths

error_folder_path = os.path.join(storage_directory, "issue_key")
error_folder_path = os.path.join(storage_directory, issue_key)
os.makedirs(error_folder_path, exist_ok=True)
for source_file in error_files:
try:
Expand Down
16 changes: 16 additions & 0 deletions abr-testing/abr_testing/data_collection/read_robot_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,11 @@ def get_error_info(file_results: Dict[str, Any]) -> Dict[str, Any]:
recoverable_errors.get(error_type, 0) + 1
)
# Get run-ending error info
module_dict = {
"heatershaker": "heaterShakerModuleV1",
"thermocycler": "thermocyclerModuleV2",
"temperature module": "temperatureModuleV2",
}
try:
run_command_error = commands_of_run[-1]["error"]
error_type = run_command_error.get("errorType", "")
Expand All @@ -647,6 +652,17 @@ def get_error_info(file_results: Dict[str, Any]) -> Dict[str, Any]:
error_instrument = run_command_error.get("errorInfo", {}).get(
"node", run_command_error.get("errorInfo", {}).get("port", "")
)
if "gripper" in error_instrument:
# get gripper serial number
error_instrument = file_results["extension"]
else:
# get module serial number
for module in module_dict.keys():
if module in error_instrument:
for module_list in file_results["modules"]:
model = module_list["model"]
if model == module_dict[module]:
error_instrument = module_list["serialNumber"]
except (IndexError, KeyError):
try:
error_details = file_results.get("errors", [{}])[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def add_parameters(parameters: ParameterContext) -> None:
parameters.add_int(
variable_name="number_of_runs",
display_name="Number of Runs",
default=2,
default=4,
minimum=1,
maximum=4,
)
Expand All @@ -53,7 +53,7 @@ def run(protocol: ProtocolContext) -> None:
bind_vol = 300.0
sample_vol = 180.0
elution_vol = 100.0
helpers.comment_protocol_version(protocol, "01")
helpers.comment_protocol_version(protocol, "02")
# Same for all HDQ Extractions
deepwell_type = "nest_96_wellplate_2ml_deep"
if not dry_run:
Expand Down Expand Up @@ -87,7 +87,7 @@ def run(protocol: ProtocolContext) -> None:
magblock: MagneticBlockContext = protocol.load_module(
"magneticBlockV1", "C1"
) # type: ignore[assignment]
liquid_waste = protocol.load_labware("nest_1_reservoir_195ml", "B3", "Liquid Waste")
liquid_waste = protocol.load_labware("nest_1_reservoir_290ml", "B3", "Liquid Waste")
waste = liquid_waste.wells()[0].top()

lysis_reservoir = protocol.load_labware(deepwell_type, "D2", "Lysis reservoir")
Expand Down Expand Up @@ -417,7 +417,6 @@ def clean() -> None:
elutionplate,
wash2_reservoir,
wash1_reservoir,
liquid_waste,
]
helpers.clean_up_plates(pip, plates_to_clean, liquid_waste["A1"], 1000)

Expand Down
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()
Loading

0 comments on commit 6aadcde

Please sign in to comment.