From d3b912fecdd4e00ac21551424f6686bc27db2662 Mon Sep 17 00:00:00 2001 From: Jethary Date: Fri, 29 Sep 2023 13:21:46 -0400 Subject: [PATCH] add some logic for pipetting into 384 well plate with 50uL tip --- .../src/steplist/formLevel/errors.ts | 18 ++++++++++-- .../handleFormChange/test/mix.test.ts | 6 ++++ .../formLevel/handleFormChange/utils.ts | 5 +++- .../js/helpers/__tests__/wellSets.test.ts | 28 +++++++++++++++++-- shared-data/js/helpers/wellSets.ts | 28 ++++++++++++++++--- 5 files changed, 74 insertions(+), 11 deletions(-) diff --git a/protocol-designer/src/steplist/formLevel/errors.ts b/protocol-designer/src/steplist/formLevel/errors.ts index 1a017910a048..ef04b76ad1d4 100644 --- a/protocol-designer/src/steplist/formLevel/errors.ts +++ b/protocol-designer/src/steplist/formLevel/errors.ts @@ -141,7 +141,11 @@ export const incompatibleLabware = ( ): FormError | null => { const { labware, pipette } = fields if (!labware || !pipette) return null - return !canPipetteUseLabware(pipette.spec, labware.def) + return !canPipetteUseLabware( + pipette.spec, + labware.def, + pipette.tiprackLabwareDef + ) ? INCOMPATIBLE_LABWARE : null } @@ -150,7 +154,11 @@ export const incompatibleDispenseLabware = ( ): FormError | null => { const { dispense_labware, pipette } = fields if (!dispense_labware || !pipette) return null - return !canPipetteUseLabware(pipette.spec, dispense_labware.def) + return !canPipetteUseLabware( + pipette.spec, + dispense_labware.def, + pipette.tiprackLabwareDef + ) ? INCOMPATIBLE_DISPENSE_LABWARE : null } @@ -159,7 +167,11 @@ export const incompatibleAspirateLabware = ( ): FormError | null => { const { aspirate_labware, pipette } = fields if (!aspirate_labware || !pipette) return null - return !canPipetteUseLabware(pipette.spec, aspirate_labware.def) + return !canPipetteUseLabware( + pipette.spec, + aspirate_labware.def, + pipette.tiprackLabwareDef + ) ? INCOMPATIBLE_ASPIRATE_LABWARE : null } diff --git a/protocol-designer/src/steplist/formLevel/handleFormChange/test/mix.test.ts b/protocol-designer/src/steplist/formLevel/handleFormChange/test/mix.test.ts index 0f3d5f268a03..c2c0f9b2d540 100644 --- a/protocol-designer/src/steplist/formLevel/handleFormChange/test/mix.test.ts +++ b/protocol-designer/src/steplist/formLevel/handleFormChange/test/mix.test.ts @@ -1,6 +1,8 @@ import { LabwareDefinition2 } from '@opentrons/shared-data' import _fixture_96_plate from '@opentrons/shared-data/labware/fixtures/2/fixture_96_plate.json' import _fixture_trash from '@opentrons/shared-data/labware/fixtures/2/fixture_trash.json' +import fixture_tiprack_10_ul from '@opentrons/shared-data/labware/fixtures/2/fixture_tiprack_10_ul.json' +import fixture_tiprack_300_ul from '@opentrons/shared-data/labware/fixtures/2/fixture_tiprack_300_ul.json' import { LabwareEntities, PipetteEntities } from '@opentrons/step-generation' import { DEFAULT_MM_FROM_BOTTOM_DISPENSE } from '../../../../constants' import { FormData } from '../../../../form-types' @@ -8,6 +10,8 @@ import { dependentFieldsUpdateMix } from '../dependentFieldsUpdateMix' const fixture96Plate = _fixture_96_plate as LabwareDefinition2 const fixtureTrash = _fixture_trash as LabwareDefinition2 +const fixtureTipRack10ul = fixture_tiprack_10_ul as LabwareDefinition2 +const fixtureTipRack300ul = fixture_tiprack_300_ul as LabwareDefinition2 let pipetteEntities: PipetteEntities let labwareEntities: LabwareEntities @@ -20,6 +24,7 @@ beforeEach(() => { spec: { channels: 1, }, + tiprackLabwareDef: fixtureTipRack300ul, }, pipetteMultiId: { name: 'p10_multi', @@ -27,6 +32,7 @@ beforeEach(() => { spec: { channels: 8, }, + tiprackLabwareDef: fixtureTipRack10ul, }, } as any labwareEntities = { diff --git a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.ts b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.ts index be4c393775a5..f531ad136b01 100644 --- a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.ts +++ b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.ts @@ -7,6 +7,7 @@ import { LabwareDefinition2, PipetteChannels } from '@opentrons/shared-data' import { LabwareEntities, PipetteEntities } from '@opentrons/step-generation' import { FormPatch } from '../../actions/types' import { FormData, PathOption, StepFieldName } from '../../../form-types' + export function chainPatchUpdaters( initialPatch: FormPatch, fns: Array<(arg0: FormPatch) => FormPatch> @@ -145,9 +146,11 @@ export function getDefaultWells(args: GetDefaultWellsArgs): string[] { ) return [] const labwareDef = labwareEntities[labwareId].def + const pipetteCanUseLabware = canPipetteUseLabware( pipetteEntities[pipetteId].spec, - labwareDef + labwareDef, + pipetteEntities[pipetteId].tiprackLabwareDef ) if (!pipetteCanUseLabware) return [] const isSingleWellLabware = diff --git a/shared-data/js/helpers/__tests__/wellSets.test.ts b/shared-data/js/helpers/__tests__/wellSets.test.ts index a0be4f4edded..475d6bf545f1 100644 --- a/shared-data/js/helpers/__tests__/wellSets.test.ts +++ b/shared-data/js/helpers/__tests__/wellSets.test.ts @@ -2,6 +2,8 @@ import pipetteNameSpecsFixtures from '../../../pipette/fixtures/name/pipetteName import fixture_12_trough from '../../../labware/fixtures/2/fixture_12_trough.json' import fixture_96_plate from '../../../labware/fixtures/2/fixture_96_plate.json' import fixture_384_plate from '../../../labware/fixtures/2/fixture_384_plate.json' +import fixture_tiprack_10_ul from '../../../labware/fixtures/2/fixture_tiprack_10_ul.json' +import fixture_tiprack_300_ul from '../../../labware/fixtures/2/fixture_tiprack_300_ul.json' import fixture_overlappy_wellplate from '../../../labware/fixtures/2/fixture_overlappy_wellplate.json' import { makeWellSetHelpers } from '../wellSets' import { findWellAt } from '../getWellNamePerMultiTip' @@ -17,6 +19,8 @@ const fixture12Trough = fixture_12_trough as LabwareDefinition2 const fixture96Plate = fixture_96_plate as LabwareDefinition2 const fixture384Plate = fixture_384_plate as LabwareDefinition2 const fixtureOverlappyWellplate = fixture_overlappy_wellplate as LabwareDefinition2 +const fixtureTipRack10ul = fixture_tiprack_10_ul as LabwareDefinition2 +const fixtureTipRack300ul = fixture_tiprack_300_ul as LabwareDefinition2 const EIGHT_CHANNEL = 8 const NINETY_SIX_CHANNEL = 96 const wellsForReservoir = [ @@ -201,15 +205,33 @@ describe('canPipetteUseLabware', () => { const pipette = fixtureP10Multi const pipette96 = fixtureP100096 - expect(canPipetteUseLabware(pipette, labwareDef)).toBe(false) - expect(canPipetteUseLabware(pipette96, labwareDef)).toBe(false) + expect(canPipetteUseLabware(pipette, labwareDef, fixtureTipRack10ul)).toBe( + false + ) + expect( + canPipetteUseLabware(pipette96, labwareDef, fixtureTipRack10ul) + ).toBe(false) }) it('returns true when pipette is single channel', () => { const labwareDef = fixtureOverlappyWellplate const pipette = fixtureP10Single - expect(canPipetteUseLabware(pipette, labwareDef)).toBe(true) + expect(canPipetteUseLabware(pipette, labwareDef, fixtureTipRack10ul)).toBe( + true + ) + }) + it('returns false when the tip volume is too high with the 384 well plate', () => { + const labwareDef = fixture384Plate + const pipette = fixtureP10Multi + const pipette96 = fixtureP100096 + + expect(canPipetteUseLabware(pipette, labwareDef, fixtureTipRack300ul)).toBe( + false + ) + expect( + canPipetteUseLabware(pipette96, labwareDef, fixtureTipRack300ul) + ).toBe(false) }) }) diff --git a/shared-data/js/helpers/wellSets.ts b/shared-data/js/helpers/wellSets.ts index f01b104ebc47..0af496b75ed2 100644 --- a/shared-data/js/helpers/wellSets.ts +++ b/shared-data/js/helpers/wellSets.ts @@ -14,7 +14,12 @@ import uniq from 'lodash/uniq' import { getWellNamePerMultiTip } from './getWellNamePerMultiTip' -import { get96Channel384WellPlateWells, getLabwareDefURI, orderWells } from '.' +import { + get96Channel384WellPlateWells, + getLabwareDefURI, + getTiprackVolume, + orderWells, +} from '.' import type { LabwareDefinition2, PipetteNameSpecs } from '../types' type WellSetByPrimaryWell = string[][] @@ -56,7 +61,8 @@ export interface WellSetHelpers { canPipetteUseLabware: ( pipetteSpec: PipetteNameSpecs, - labwareDef: LabwareDefinition2 + labwareDef: LabwareDefinition2, + tiprackDef: LabwareDefinition2 ) => boolean } @@ -131,10 +137,24 @@ export const makeWellSetHelpers = (): WellSetHelpers => { const canPipetteUseLabware = ( pipetteSpec: PipetteNameSpecs, - labwareDef: LabwareDefinition2 + labwareDef: LabwareDefinition2, + tiprackDef: LabwareDefinition2 ): boolean => { + // 384 well plates are only compatible with p50s or p20/p10s + const tiprackVolume = getTiprackVolume(tiprackDef) + const is384WellPlate = Object.keys(labwareDef.wells).length === 384 + if ( + (tiprackVolume === 200 || + tiprackVolume === 300 || + tiprackVolume === 1000) && + is384WellPlate + ) { + return false + } + if (pipetteSpec.channels === 1) { - // assume all labware can be used by single-channel + // assume all labware except for the 384 well plate with certain volumes + // can be used by single-channel return true }