Skip to content

Commit

Permalink
feat(api): Mark calibrations as bad when determined they exceed thres…
Browse files Browse the repository at this point in the history
…hold

closes #6730
  • Loading branch information
Laura-Danielle committed Nov 5, 2020
1 parent 77f5182 commit f2b746a
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 45 deletions.
4 changes: 2 additions & 2 deletions api/src/opentrons/calibration_storage/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@


def _format_calibration_type(
data: 'CalibrationDict') -> local_types.CalibrationTypes:
data: 'CalibrationDict') -> local_types.LabwareCalibrationTypes:
offset = local_types.OffsetData(
value=data['default']['offset'],
last_modified=data['default']['lastModified']
Expand All @@ -27,7 +27,7 @@ def _format_calibration_type(
# the labware calibraiton file. We should
# have a follow-up PR to grab tip lengths
# based on the loaded pips + labware
return local_types.CalibrationTypes(
return local_types.LabwareCalibrationTypes(
offset=offset,
tip_length=local_types.TipLengthData())

Expand Down
88 changes: 68 additions & 20 deletions api/src/opentrons/calibration_storage/modify.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from pathlib import Path

from opentrons import config
from opentrons.types import Mount
from opentrons.types import Mount, Point

from opentrons.util.helpers import utc_now

from . import (
Expand All @@ -22,7 +23,7 @@
TipLengthCalibration, PipTipLengthCalibration,
DeckCalibrationData, PipetteCalibrationData, CalibrationStatusDict)
from opentrons_shared_data.labware.dev_types import LabwareDefinition
from opentrons.types import Point
from opentrons.protocol_api.labware import Labware


def _add_to_index_offset_file(parent: str, slot: str, uri: str, lw_hash: str):
Expand Down Expand Up @@ -76,7 +77,7 @@ def add_existing_labware_to_index_file(
def save_labware_calibration(
labware_path: local_types.StrPath,
definition: 'LabwareDefinition',
delta: 'Point',
delta: Point,
slot: str = '',
parent: str = ''):
"""
Expand Down Expand Up @@ -106,7 +107,9 @@ def save_labware_calibration(
def create_tip_length_data(
definition: 'LabwareDefinition',
parent: str,
length: float) -> 'PipTipLengthCalibration':
length: float,
cal_status: typing.Optional[local_types.CalibrationStatus] = None
) -> 'PipTipLengthCalibration':
"""
Function to correctly format tip length data.
Expand All @@ -121,22 +124,25 @@ def create_tip_length_data(
# assert labware._is_tiprack, \
# 'cannot save tip length for non-tiprack labware'
labware_hash = helpers.hash_labware_def(definition)
status: 'CalibrationStatusDict' =\
helpers.convert_to_dict( # type: ignore
local_types.CalibrationStatus())
if cal_status:
status = cal_status
else:
status = local_types.CalibrationStatus()
status_dict: 'CalibrationStatusDict' =\
helpers.convert_to_dict(status) # type: ignore

tip_length_data: 'TipLengthCalibration' = {
'tipLength': length,
'lastModified': utc_now(),
'source': local_types.SourceType.user,
'status': status
'status': status_dict
}

data = {labware_hash + parent: tip_length_data}
return data


def _helper_offset_data_format(filepath: str, delta: 'Point') -> dict:
def _helper_offset_data_format(filepath: str, delta: Point) -> dict:
if not Path(filepath).is_file():
calibration_data = {
"default": {
Expand Down Expand Up @@ -197,20 +203,25 @@ def save_robot_deck_attitude(
transform: local_types.AttitudeMatrix,
pip_id: typing.Optional[str],
lw_hash: typing.Optional[str],
source: local_types.SourceType = None):
source: local_types.SourceType = None,
cal_status: typing.Optional[local_types.CalibrationStatus] = None):
robot_dir = config.get_opentrons_path('robot_calibration_dir')
robot_dir.mkdir(parents=True, exist_ok=True)
gantry_path = robot_dir/'deck_calibration.json'
status: 'CalibrationStatusDict' = \
helpers.convert_to_dict( # type: ignore
local_types.CalibrationStatus())
if cal_status:
status = cal_status
else:
status = local_types.CalibrationStatus()
status_dict: 'CalibrationStatusDict' =\
helpers.convert_to_dict(status) # type: ignore

gantry_dict: 'DeckCalibrationData' = {
'attitude': transform,
'pipette_calibrated_with': pip_id,
'last_modified': utc_now(),
'tiprack': lw_hash,
'source': source or local_types.SourceType.user,
'status': status
'status': status_dict
}
io.save_to_file(gantry_path, gantry_dict)

Expand All @@ -233,23 +244,60 @@ def _add_to_pipette_offset_index_file(pip_id: str, mount: Mount):


def save_pipette_calibration(
offset: 'Point',
offset: Point,
pip_id: str, mount: Mount,
tiprack_hash: str, tiprack_uri: str):
tiprack_hash: str, tiprack_uri: str,
cal_status: typing.Optional[local_types.CalibrationStatus] = None):
pip_dir = config.get_opentrons_path(
'pipette_calibration_dir') / mount.name.lower()
pip_dir.mkdir(parents=True, exist_ok=True)
status: 'CalibrationStatusDict' =\
helpers.convert_to_dict( # type: ignore
local_types.CalibrationStatus())
if cal_status:
status = cal_status
else:
status = local_types.CalibrationStatus()
status_dict: 'CalibrationStatusDict' =\
helpers.convert_to_dict(status) # type: ignore
offset_path = pip_dir/f'{pip_id}.json'
offset_dict: 'PipetteCalibrationData' = {
'offset': [offset.x, offset.y, offset.z],
'tiprack': tiprack_hash,
'uri': tiprack_uri,
'last_modified': utc_now(),
'source': local_types.SourceType.user,
'status': status
'status': status_dict
}
io.save_to_file(offset_path, offset_dict)
_add_to_pipette_offset_index_file(pip_id, mount)


def mark_bad(
calibration: typing.Union[
local_types.DeckCalibration,
local_types.PipetteOffsetCalibration,
typing.Tuple[float, str, 'Labware']],
source_marked_bad: local_types.SourceType):
status = local_types.CalibrationStatus(
markedBad=True, source=source_marked_bad, markedAt=utc_now())
if isinstance(calibration, local_types.DeckCalibration):
save_robot_deck_attitude(
transform=calibration.attitude,
pip_id=calibration.pipette_calibrated_with,
lw_hash=calibration.tiprack,
source=calibration.source,
cal_status=status)
elif isinstance(calibration, local_types.PipetteOffsetCalibration):
save_pipette_calibration(
offset=Point(*calibration.offset),
pip_id=calibration.pipette,
mount=Mount.string_to_mount(calibration.mount),
tiprack_hash=calibration.tiprack,
tiprack_uri=calibration.uri,
cal_status=status)
else:
tip_length, pipette_id, tiprack = calibration
tip_length_dict = create_tip_length_data(
definition=tiprack._implementation.get_definition(),
parent=tiprack.parent,
length=tip_length,
cal_status=status)
save_tip_length_calibration(pipette_id, tip_length_dict)
6 changes: 3 additions & 3 deletions api/src/opentrons/calibration_storage/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ParentOptions:


@dataclass
class CalibrationTypes:
class LabwareCalibrationTypes:
"""
Class to categorize what calibration
data might be stored for a labware.
Expand All @@ -90,7 +90,7 @@ class CalibrationInformation:
Class to store important calibration
info for labware.
"""
calibration: CalibrationTypes
calibration: LabwareCalibrationTypes
parent: ParentOptions
labware_id: str
uri: str
Expand Down Expand Up @@ -119,7 +119,7 @@ class DeckCalibration:
@dataclass
class PipetteOffsetByPipetteMount:
"""
Class to store pipette offset without pipette and monut info
Class to store pipette offset without pipette and mount info
"""
offset: PipetteOffset
source: SourceType
Expand Down
7 changes: 7 additions & 0 deletions api/src/opentrons/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ class Mount(enum.Enum):
def __str__(self):
return self.name

@classmethod
def string_to_mount(cls, mount: str) -> 'Mount':
if mount == 'right':
return cls.RIGHT
else:
return cls.LEFT


class TransferTipPolicy(enum.Enum):
ONCE = enum.auto()
Expand Down
Loading

0 comments on commit f2b746a

Please sign in to comment.