Skip to content

Commit

Permalink
Add AVG historical temp and RH conditions to error ticket (#15655)
Browse files Browse the repository at this point in the history
<!--
Thanks for taking the time to open a pull request! Please make sure
you've read the "Opening Pull Requests" section of our Contributing
Guide:


https://github.com/Opentrons/opentrons/blob/edge/CONTRIBUTING.md#opening-pull-requests

To ensure your code is reviewed quickly and thoroughly, please fill out
the sections below to the best of your ability!
-->

# Overview

Add AVG historical temp and RH conditions to error ticket 

# Test Plan

- Connects to ABR sheet
- Connects to ABR Ambient conditions sheet
- Filters out data between time stamps and robot and same protocol
- Adds a string that compares found averages to the ticket description.

# Changelog

<!--
List out the changes to the code in this PR. Please try your best to
categorize your changes and describe what has changed and why.

Example changelog:
- Fixed app crash when trying to calibrate an illegal pipette
- Added state to API to track pipette usage
- Updated API docs to mention only two pipettes are supported

IMPORTANT: MAKE SURE ANY BREAKING CHANGES ARE PROPERLY COMMUNICATED
-->

# Review requests

<!--
Describe any requests for your reviewers here.
-->

# Risk assessment

<!--
Carefully go over your pull request and look at the other parts of the
codebase it may affect. Look for the possibility, even if you think it's
small, that your change may affect some other part of the system - for
instance, changing return tip behavior in protocol may also change the
behavior of labware calibration.

Identify the other parts of the system your codebase may affect, so that
in addition to your own review and testing, other people who may not
have the system internalized as much as you can focus their attention
and testing there.
-->
  • Loading branch information
rclarke0 authored Jul 15, 2024
1 parent 4f90e28 commit 187e079
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 5 deletions.
4 changes: 2 additions & 2 deletions abr-testing/abr_testing/data_collection/abr_google_drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ def create_data_dictionary(
start_time = datetime.strptime(
file_results.get("startedAt", ""), "%Y-%m-%dT%H:%M:%S.%f%z"
)
adjusted_start_time = start_time - timedelta(hours=5)
adjusted_start_time = start_time - timedelta(hours=4)
start_date = str(adjusted_start_time.date())
start_time_str = str(adjusted_start_time).split("+")[0]
complete_time = datetime.strptime(
file_results.get("completedAt", ""), "%Y-%m-%dT%H:%M:%S.%f%z"
)
adjusted_complete_time = complete_time - timedelta(hours=5)
adjusted_complete_time = complete_time - timedelta(hours=4)
complete_time_str = str(adjusted_complete_time).split("+")[0]
run_time = complete_time - start_time
run_time_min = run_time.total_seconds() / 60
Expand Down
118 changes: 115 additions & 3 deletions abr-testing/abr_testing/data_collection/abr_robot_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,97 @@
import shutil
import os
import subprocess
from datetime import datetime, timedelta
import sys
import json
import re
import pandas as pd
from statistics import mean, StatisticsError


def compare_current_trh_to_average(
robot: str,
start_time: Any,
end_time: Any,
protocol_name: str,
storage_directory: str,
) -> str:
"""Get average temp/rh for errored run and compare to average."""
# Connect to ABR ambient conditions sheet
credentials_path = os.path.join(storage_directory, "credentials.json")
temprh_data_sheet = google_sheets_tool.google_sheet(
credentials_path, "ABR Ambient Conditions", 0
)
headers = temprh_data_sheet.get_row(1)
all_trh_data = temprh_data_sheet.get_all_data(expected_headers=headers)
# Connect to ABR-run-data sheet
abr_data = google_sheets_tool.google_sheet(credentials_path, "ABR-run-data", 0)
headers = abr_data.get_row(1)
all_run_data = abr_data.get_all_data(expected_headers=headers)
# Find average conditions of errored time period
df_all_trh = pd.DataFrame(all_trh_data)
# Convert timestamps to datetime objects
df_all_trh["Timestamp"] = pd.to_datetime(
df_all_trh["Timestamp"], format="mixed"
).dt.tz_localize(None)
# Ensure start_time is timezone-naive
start_time = start_time.replace(tzinfo=None)
end_time = end_time.replace(tzinfo=None)
relevant_temp_rhs = df_all_trh[
(df_all_trh["Robot"] == robot)
& (df_all_trh["Timestamp"] >= start_time)
& (df_all_trh["Timestamp"] <= end_time)
]
try:
avg_temp = round(mean(relevant_temp_rhs["Temp (oC)"]), 2)
avg_rh = round(mean(relevant_temp_rhs["Relative Humidity (%)"]), 2)
except StatisticsError:
avg_temp = None
avg_rh = None
# Get AVG t/rh of runs w/ same robot & protocol newer than 3 wks old with no errors
weeks_ago_3 = start_time - timedelta(weeks=3)
df_all_run_data = pd.DataFrame(all_run_data)
df_all_run_data["Start_Time"] = pd.to_datetime(
df_all_run_data["Start_Time"], format="mixed"
).dt.tz_localize(None)
df_all_run_data["Errors"] = pd.to_numeric(df_all_run_data["Errors"])
df_all_run_data["Average Temp (oC)"] = pd.to_numeric(
df_all_run_data["Average Temp (oC)"]
)
common_filters = (
(df_all_run_data["Robot"] == robot)
& (df_all_run_data["Start_Time"] >= weeks_ago_3)
& (df_all_run_data["Start_Time"] <= start_time)
& (df_all_run_data["Errors"] < 1)
& (df_all_run_data["Average Temp (oC)"] > 1)
)

if protocol_name == "":
relevant_run_data = df_all_run_data[common_filters]
else:
relevant_run_data = df_all_run_data[
common_filters & (df_all_run_data["Protocol_Name"] == protocol_name)
]
# Calculate means of historical data
try:
historical_avg_temp = round(
mean(relevant_run_data["Average Temp (oC)"].astype(float)), 2
)
historical_avg_rh = round(
mean(relevant_run_data["Average RH(%)"].astype(float)), 2
)
except StatisticsError:
historical_avg_temp = None
historical_avg_rh = None
# Formats TEMP/RH message for ticket.
temp_rh_message = (
f"{len(relevant_run_data)} runs with temp/rh data for {robot} running {protocol_name}."
f" AVG TEMP (deg C): {historical_avg_temp}. AVG RH (%): {historical_avg_rh}."
f" AVG TEMP of ERROR: {avg_temp}. AVG RH of ERROR: {avg_rh}."
)
# Print out comparison string.
print(temp_rh_message)
return temp_rh_message


def compare_lpc_to_historical_data(
Expand Down Expand Up @@ -42,9 +129,9 @@ def compare_lpc_to_historical_data(
current_x = round(labware_dict["X"], 2)
current_y = round(labware_dict["Y"], 2)
current_z = round(labware_dict["Z"], 2)
avg_x = round(sum(x_float) / len(x_float), 2)
avg_y = round(sum(y_float) / len(y_float), 2)
avg_z = round(sum(z_float) / len(z_float), 2)
avg_x = round(mean(x_float), 2)
avg_y = round(mean(y_float), 2)
avg_z = round(mean(z_float), 2)

# Formats LPC message for ticket.
lpc_message = (
Expand Down Expand Up @@ -195,6 +282,13 @@ def get_robot_state(
components = ["Flex-RABR"]
components = match_error_to_component("RABR", reported_string, components)
print(components)
end_time = datetime.now()
start_time = end_time - timedelta(hours=2)
# Get current temp/rh compared to historical data
temp_rh_string = compare_current_trh_to_average(
parent, start_time, end_time, "", storage_directory
)
description["Robot Temp and RH Comparison"] = temp_rh_string
whole_description_str = (
"{"
+ "\n".join("{!r}: {!r},".format(k, v) for k, v in description.items())
Expand Down Expand Up @@ -242,6 +336,23 @@ def get_run_error_info_from_robot(
description["protocol_name"] = results["protocol"]["metadata"].get(
"protocolName", ""
)
# Get start and end time of run
start_time = datetime.strptime(
results.get("startedAt", ""), "%Y-%m-%dT%H:%M:%S.%f%z"
)
adjusted_start_time = start_time - timedelta(hours=4)
complete_time = datetime.strptime(
results.get("completedAt", ""), "%Y-%m-%dT%H:%M:%S.%f%z"
)
adjusted_complete_time = complete_time - timedelta(hours=4)
# Get average temp and rh of robot and protocol the error occurred on.
temp_rh_comparison = compare_current_trh_to_average(
parent,
adjusted_start_time,
adjusted_complete_time,
description["protocol_name"],
storage_directory,
)
# Get LPC coordinates of labware of failure
lpc_dict = results["labwareOffsets"]
labware_dict = results["labware"]
Expand Down Expand Up @@ -280,6 +391,7 @@ def get_run_error_info_from_robot(
if len(lpc_message) < 1:
lpc_message = "No LPC coordinates found in relation to error."
description["LPC Comparison"] = lpc_message
description["Robot Temp and RH Comparison"] = temp_rh_comparison
all_modules = abr_google_drive.get_modules(results)
whole_description = {**description, **all_modules}
whole_description_str = (
Expand Down

0 comments on commit 187e079

Please sign in to comment.