@opentrons/shared-data 0.0.1-alpha.20 → 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Makefile +1 -1
- package/lib/opentrons-shared-data.js +1 -1
- package/lib/opentrons-shared-data.js.map +1 -1
- package/package.json +1 -1
- package/js/__tests__/__snapshots__/pipettes.test.ts.snap +0 -5969
- package/js/__tests__/deckSchemas.test.ts +0 -87
- package/js/__tests__/errors.test.js +0 -21
- package/js/__tests__/getAreSlotsAdjacent.test.ts +0 -128
- package/js/__tests__/getWellNamePerMultiTip.test.ts +0 -162
- package/js/__tests__/labwareDefQuirks.test.ts +0 -37
- package/js/__tests__/labwareDefSchemaV1.test.ts +0 -82
- package/js/__tests__/labwareDefSchemaV2.test.ts +0 -298
- package/js/__tests__/moduleAccessors.test.ts +0 -50
- package/js/__tests__/moduleSpecsSchema.test.ts +0 -77
- package/js/__tests__/pipetteSchemaV2.test.ts +0 -107
- package/js/__tests__/pipetteSpecSchemas.test.ts +0 -48
- package/js/__tests__/pipettes.test.ts +0 -58
- package/js/__tests__/protocolSchemaV4.test.ts +0 -137
- package/js/__tests__/protocolSchemaV5.test.ts +0 -137
- package/js/__tests__/protocolSchemaV6.test.ts +0 -132
- package/js/__tests__/protocolSchemaV7.test.ts +0 -64
- package/js/__tests__/protocolValidation.test.ts +0 -83
- package/js/__tests__/sortWells.test.ts +0 -40
- package/js/__tests__/splitWellsOnColumn.test.ts +0 -21
- package/js/__tests__/validateErrors.test.js +0 -34
- package/js/constants.ts +0 -338
- package/js/cypressUtils.ts +0 -35
- package/js/errors.ts +0 -33
- package/js/fixtures.ts +0 -161
- package/js/getLabware.ts +0 -154
- package/js/gripper.ts +0 -29
- package/js/helpers/__tests__/getAdapterName.test.ts +0 -31
- package/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.ts +0 -12
- package/js/helpers/__tests__/getVectorDifference.test.ts +0 -25
- package/js/helpers/__tests__/getVectorSum.test.ts +0 -21
- package/js/helpers/__tests__/labwareInference.test.ts +0 -84
- package/js/helpers/__tests__/orderWells.test.ts +0 -87
- package/js/helpers/__tests__/parseProtocolData.test.ts +0 -165
- package/js/helpers/__tests__/volume.test.ts +0 -108
- package/js/helpers/__tests__/wellSets.test.ts +0 -352
- package/js/helpers/get96Channel384WellPlateWells.ts +0 -44
- package/js/helpers/getAddressableAreasInProtocol.ts +0 -59
- package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +0 -30
- package/js/helpers/getModuleVizDims.ts +0 -118
- package/js/helpers/getOccludedSlotCountForModule.ts +0 -13
- package/js/helpers/getVectorDifference.ts +0 -12
- package/js/helpers/getVectorSum.ts +0 -12
- package/js/helpers/getWellNamePerMultiTip.ts +0 -86
- package/js/helpers/getWellTotalVolume.ts +0 -16
- package/js/helpers/index.ts +0 -347
- package/js/helpers/labwareInference.ts +0 -92
- package/js/helpers/orderWells.ts +0 -69
- package/js/helpers/parseProtocolData.ts +0 -141
- package/js/helpers/volume.ts +0 -35
- package/js/helpers/wellIsRect.ts +0 -6
- package/js/helpers/wellSets.ts +0 -155
- package/js/index.ts +0 -14
- package/js/labwareTools/__tests__/__snapshots__/createIrregularLabware.test.ts.snap +0 -3
- package/js/labwareTools/__tests__/__snapshots__/createLabware.test.ts.snap +0 -3
- package/js/labwareTools/__tests__/createDefaultDisplayName.test.ts +0 -111
- package/js/labwareTools/__tests__/createIrregularLabware.test.ts +0 -226
- package/js/labwareTools/__tests__/createLabware.test.ts +0 -147
- package/js/labwareTools/index.ts +0 -452
- package/js/modules.ts +0 -97
- package/js/pipettes.ts +0 -89
- package/js/protocols.ts +0 -290
- package/js/schema.ts +0 -80
- package/js/scripts/generateDeckLayersFromSVG.js +0 -46
- package/js/titleCase.ts +0 -30
- package/js/types.ts +0 -600
- package/python/.coveragerc +0 -4
- package/python/.flake8 +0 -32
- package/python/Config.in +0 -10
- package/python/Makefile +0 -134
- package/python/Pipfile +0 -28
- package/python/Pipfile.lock +0 -645
- package/python/buildroot.mk +0 -30
- package/python/mypy.ini +0 -41
- package/python/opentrons_shared_data/__init__.py +0 -17
- package/python/opentrons_shared_data/_version.py +0 -20
- package/python/opentrons_shared_data/command/__init__.py +0 -52
- package/python/opentrons_shared_data/deck/__init__.py +0 -96
- package/python/opentrons_shared_data/deck/dev_types.py +0 -180
- package/python/opentrons_shared_data/errors/__init__.py +0 -30
- package/python/opentrons_shared_data/errors/categories.py +0 -60
- package/python/opentrons_shared_data/errors/codes.py +0 -108
- package/python/opentrons_shared_data/errors/exceptions.py +0 -915
- package/python/opentrons_shared_data/gripper/__init__.py +0 -63
- package/python/opentrons_shared_data/gripper/constants.py +0 -6
- package/python/opentrons_shared_data/gripper/gripper_definition.py +0 -101
- package/python/opentrons_shared_data/labware/__init__.py +0 -22
- package/python/opentrons_shared_data/labware/constants.py +0 -7
- package/python/opentrons_shared_data/labware/dev_types.py +0 -140
- package/python/opentrons_shared_data/labware/labware_definition.py +0 -328
- package/python/opentrons_shared_data/load.py +0 -57
- package/python/opentrons_shared_data/module/__init__.py +0 -74
- package/python/opentrons_shared_data/module/dev_types.py +0 -141
- package/python/opentrons_shared_data/pipette/__init__.py +0 -107
- package/python/opentrons_shared_data/pipette/dev_types.py +0 -177
- package/python/opentrons_shared_data/pipette/file_operation_helpers.py +0 -37
- package/python/opentrons_shared_data/pipette/load_data.py +0 -261
- package/python/opentrons_shared_data/pipette/model_constants.py +0 -123
- package/python/opentrons_shared_data/pipette/mutable_configurations.py +0 -431
- package/python/opentrons_shared_data/pipette/pipette_definition.py +0 -503
- package/python/opentrons_shared_data/pipette/pipette_load_name_conversions.py +0 -240
- package/python/opentrons_shared_data/pipette/scripts/__init__.py +0 -0
- package/python/opentrons_shared_data/pipette/scripts/build_json_script.py +0 -469
- package/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py +0 -450
- package/python/opentrons_shared_data/pipette/types.py +0 -193
- package/python/opentrons_shared_data/protocol/__init__.py +0 -13
- package/python/opentrons_shared_data/protocol/constants.py +0 -98
- package/python/opentrons_shared_data/protocol/dev_types.py +0 -436
- package/python/opentrons_shared_data/protocol/models/__init__.py +0 -48
- package/python/opentrons_shared_data/protocol/models/protocol_schema_v6.py +0 -145
- package/python/opentrons_shared_data/protocol/models/protocol_schema_v7.py +0 -95
- package/python/opentrons_shared_data/protocol/models/protocol_schema_v8.py +0 -110
- package/python/opentrons_shared_data/protocol/models/shared_models.py +0 -111
- package/python/opentrons_shared_data/py.typed +0 -0
- package/python/opentrons_shared_data/robot/__init__.py +0 -33
- package/python/opentrons_shared_data/robot/dev_types.py +0 -37
- package/python/pytest.ini +0 -2
- package/python/setup.cfg +0 -5
- package/python/setup.py +0 -179
- package/python/tests/__init__.py +0 -1
- package/python/tests/conftest.py +0 -0
- package/python/tests/deck/__init__.py +0 -0
- package/python/tests/deck/test_list_names.py +0 -12
- package/python/tests/deck/test_position.py +0 -113
- package/python/tests/deck/test_typechecks.py +0 -28
- package/python/tests/errors/__init__.py +0 -1
- package/python/tests/errors/test_error_completeness.py +0 -19
- package/python/tests/errors/test_exceptions.py +0 -74
- package/python/tests/gripper/__init__.py +0 -0
- package/python/tests/gripper/test_definition.py +0 -30
- package/python/tests/gripper/test_load.py +0 -16
- package/python/tests/labware/__init__.py +0 -13
- package/python/tests/labware/test_typechecks.py +0 -21
- package/python/tests/module/__init__.py +0 -20
- package/python/tests/module/test_load.py +0 -49
- package/python/tests/module/test_typechecks.py +0 -34
- package/python/tests/pipette/__init__.py +0 -0
- package/python/tests/pipette/test_load_data.py +0 -103
- package/python/tests/pipette/test_mutable_configurations.py +0 -266
- package/python/tests/pipette/test_pipette_definition.py +0 -183
- package/python/tests/pipette/test_pipette_load_name_conversions.py +0 -222
- package/python/tests/pipette/test_typechecks.py +0 -50
- package/python/tests/pipette/test_validate_schema.py +0 -37
- package/python/tests/protocol/__init__.py +0 -15
- package/python/tests/protocol/test_protocol_schema_v6.py +0 -107
- package/python/tests/protocol/test_protocol_schema_v7.py +0 -34
- package/python/tests/protocol/test_protocol_schema_v8.py +0 -20
- package/python/tests/protocol/test_typechecks.py +0 -36
- package/python/tests/robot/__init__.py +0 -0
- package/python/tests/robot/test_typechecks.py +0 -20
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
// volume helpers tests
|
|
2
|
-
import * as helpers from '..'
|
|
3
|
-
|
|
4
|
-
interface BaseSpec<T extends (...args: any) => any> {
|
|
5
|
-
name: string
|
|
6
|
-
func: T
|
|
7
|
-
input: Parameters<T>
|
|
8
|
-
expected: ReturnType<T>
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type GetDisplayVolumeSpec = BaseSpec<typeof helpers.getDisplayVolume>
|
|
12
|
-
|
|
13
|
-
type GetAsciiVolumeUnitsSpec = BaseSpec<typeof helpers.getAsciiVolumeUnits>
|
|
14
|
-
|
|
15
|
-
type EnsureVolumeUnitsSpec = BaseSpec<typeof helpers.ensureVolumeUnits>
|
|
16
|
-
|
|
17
|
-
type TestSpec =
|
|
18
|
-
| GetDisplayVolumeSpec
|
|
19
|
-
| GetAsciiVolumeUnitsSpec
|
|
20
|
-
| EnsureVolumeUnitsSpec
|
|
21
|
-
|
|
22
|
-
describe('volume helpers', () => {
|
|
23
|
-
const SPECS: TestSpec[] = [
|
|
24
|
-
{
|
|
25
|
-
name: 'getDisplayVolume outputs µL string by default',
|
|
26
|
-
func: helpers.getDisplayVolume,
|
|
27
|
-
input: [380],
|
|
28
|
-
expected: '380',
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: 'getDisplayVolume converts to mL',
|
|
32
|
-
func: helpers.getDisplayVolume,
|
|
33
|
-
input: [4200, 'mL'],
|
|
34
|
-
expected: '4.2',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: 'getDisplayVolume converts to L',
|
|
38
|
-
func: helpers.getDisplayVolume,
|
|
39
|
-
input: [800000, 'L'],
|
|
40
|
-
expected: '0.8',
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
name: 'getDisplayVolume can round to fixed digits',
|
|
44
|
-
func: helpers.getDisplayVolume,
|
|
45
|
-
input: [123456789, 'L', 3],
|
|
46
|
-
expected: '123.457',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
name: 'getAsciiVolumeUnits converts µL to uL',
|
|
50
|
-
func: helpers.getAsciiVolumeUnits,
|
|
51
|
-
input: ['µL'],
|
|
52
|
-
expected: 'uL',
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: 'getAsciiVolumeUnits leaves mL alone',
|
|
56
|
-
func: helpers.getAsciiVolumeUnits,
|
|
57
|
-
input: ['mL'],
|
|
58
|
-
expected: 'mL',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: 'getAsciiVolumeUnits leaves L alone',
|
|
62
|
-
func: helpers.getAsciiVolumeUnits,
|
|
63
|
-
input: ['L'],
|
|
64
|
-
expected: 'L',
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
name: 'ensureVolumeUnits converts undefined to µL',
|
|
68
|
-
func: helpers.ensureVolumeUnits,
|
|
69
|
-
input: [undefined],
|
|
70
|
-
expected: 'µL',
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
name: 'ensureVolumeUnits converts uL to µL',
|
|
74
|
-
func: helpers.ensureVolumeUnits,
|
|
75
|
-
input: ['uL'],
|
|
76
|
-
expected: 'µL',
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
name: 'ensureVolumeUnits leaves mL alone',
|
|
80
|
-
func: helpers.ensureVolumeUnits,
|
|
81
|
-
input: ['mL'],
|
|
82
|
-
expected: 'mL',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: 'ensureVolumeUnits leaves L alone',
|
|
86
|
-
func: helpers.ensureVolumeUnits,
|
|
87
|
-
input: ['L'],
|
|
88
|
-
expected: 'L',
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
name: 'ensureVolumeUnits converts ml to mL',
|
|
92
|
-
func: helpers.ensureVolumeUnits,
|
|
93
|
-
input: ['ml'],
|
|
94
|
-
expected: 'mL',
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
name: 'ensureVolumeUnits leaves l to L',
|
|
98
|
-
func: helpers.ensureVolumeUnits,
|
|
99
|
-
input: ['l'],
|
|
100
|
-
expected: 'L',
|
|
101
|
-
},
|
|
102
|
-
]
|
|
103
|
-
|
|
104
|
-
SPECS.forEach(s => {
|
|
105
|
-
// @ts-expect-error(mc, 2021-04-27): rewrite as regular tests
|
|
106
|
-
it(`should ${s.name}`, () => expect(s.func(...s.input)).toEqual(s.expected))
|
|
107
|
-
})
|
|
108
|
-
})
|
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
import pipetteNameSpecsFixtures from '../../../pipette/fixtures/name/pipetteNameSpecFixtures.json'
|
|
2
|
-
import fixture_12_trough from '../../../labware/fixtures/2/fixture_12_trough.json'
|
|
3
|
-
import fixture_96_plate from '../../../labware/fixtures/2/fixture_96_plate.json'
|
|
4
|
-
import fixture_384_plate from '../../../labware/fixtures/2/fixture_384_plate.json'
|
|
5
|
-
import fixture_overlappy_wellplate from '../../../labware/fixtures/2/fixture_overlappy_wellplate.json'
|
|
6
|
-
import { makeWellSetHelpers } from '../wellSets'
|
|
7
|
-
import { findWellAt } from '../getWellNamePerMultiTip'
|
|
8
|
-
import { get96Channel384WellPlateWells, orderWells } from '..'
|
|
9
|
-
|
|
10
|
-
import type { LabwareDefinition2, PipetteNameSpecs } from '../../types'
|
|
11
|
-
import type { WellSetHelpers } from '../wellSets'
|
|
12
|
-
|
|
13
|
-
const fixtureP10Single = pipetteNameSpecsFixtures.p10_single as PipetteNameSpecs
|
|
14
|
-
const fixtureP10Multi = pipetteNameSpecsFixtures.p10_multi as PipetteNameSpecs
|
|
15
|
-
const fixtureP100096 = (pipetteNameSpecsFixtures.p1000_96 as any) as PipetteNameSpecs
|
|
16
|
-
const fixture12Trough = fixture_12_trough as LabwareDefinition2
|
|
17
|
-
const fixture96Plate = fixture_96_plate as LabwareDefinition2
|
|
18
|
-
const fixture384Plate = fixture_384_plate as LabwareDefinition2
|
|
19
|
-
const fixtureOverlappyWellplate = fixture_overlappy_wellplate as LabwareDefinition2
|
|
20
|
-
const EIGHT_CHANNEL = 8
|
|
21
|
-
const NINETY_SIX_CHANNEL = 96
|
|
22
|
-
const wellsForReservoir = [
|
|
23
|
-
'A1',
|
|
24
|
-
'A2',
|
|
25
|
-
'A3',
|
|
26
|
-
'A4',
|
|
27
|
-
'A5',
|
|
28
|
-
'A6',
|
|
29
|
-
'A7',
|
|
30
|
-
'A8',
|
|
31
|
-
'A9',
|
|
32
|
-
'A10',
|
|
33
|
-
'A11',
|
|
34
|
-
'A12',
|
|
35
|
-
]
|
|
36
|
-
|
|
37
|
-
const wellsFor96WellPlate = [
|
|
38
|
-
'A1',
|
|
39
|
-
'B1',
|
|
40
|
-
'C1',
|
|
41
|
-
'D1',
|
|
42
|
-
'E1',
|
|
43
|
-
'F1',
|
|
44
|
-
'G1',
|
|
45
|
-
'H1',
|
|
46
|
-
'A2',
|
|
47
|
-
'B2',
|
|
48
|
-
'C2',
|
|
49
|
-
'D2',
|
|
50
|
-
'E2',
|
|
51
|
-
'F2',
|
|
52
|
-
'G2',
|
|
53
|
-
'H2',
|
|
54
|
-
'A3',
|
|
55
|
-
'B3',
|
|
56
|
-
'C3',
|
|
57
|
-
'D3',
|
|
58
|
-
'E3',
|
|
59
|
-
'F3',
|
|
60
|
-
'G3',
|
|
61
|
-
'H3',
|
|
62
|
-
'A4',
|
|
63
|
-
'B4',
|
|
64
|
-
'C4',
|
|
65
|
-
'D4',
|
|
66
|
-
'E4',
|
|
67
|
-
'F4',
|
|
68
|
-
'G4',
|
|
69
|
-
'H4',
|
|
70
|
-
'A5',
|
|
71
|
-
'B5',
|
|
72
|
-
'C5',
|
|
73
|
-
'D5',
|
|
74
|
-
'E5',
|
|
75
|
-
'F5',
|
|
76
|
-
'G5',
|
|
77
|
-
'H5',
|
|
78
|
-
'A6',
|
|
79
|
-
'B6',
|
|
80
|
-
'C6',
|
|
81
|
-
'D6',
|
|
82
|
-
'E6',
|
|
83
|
-
'F6',
|
|
84
|
-
'G6',
|
|
85
|
-
'H6',
|
|
86
|
-
'A7',
|
|
87
|
-
'B7',
|
|
88
|
-
'C7',
|
|
89
|
-
'D7',
|
|
90
|
-
'E7',
|
|
91
|
-
'F7',
|
|
92
|
-
'G7',
|
|
93
|
-
'H7',
|
|
94
|
-
'A8',
|
|
95
|
-
'B8',
|
|
96
|
-
'C8',
|
|
97
|
-
'D8',
|
|
98
|
-
'E8',
|
|
99
|
-
'F8',
|
|
100
|
-
'G8',
|
|
101
|
-
'H8',
|
|
102
|
-
'A9',
|
|
103
|
-
'B9',
|
|
104
|
-
'C9',
|
|
105
|
-
'D9',
|
|
106
|
-
'E9',
|
|
107
|
-
'F9',
|
|
108
|
-
'G9',
|
|
109
|
-
'H9',
|
|
110
|
-
'A10',
|
|
111
|
-
'B10',
|
|
112
|
-
'C10',
|
|
113
|
-
'D10',
|
|
114
|
-
'E10',
|
|
115
|
-
'F10',
|
|
116
|
-
'G10',
|
|
117
|
-
'H10',
|
|
118
|
-
'A11',
|
|
119
|
-
'B11',
|
|
120
|
-
'C11',
|
|
121
|
-
'D11',
|
|
122
|
-
'E11',
|
|
123
|
-
'F11',
|
|
124
|
-
'G11',
|
|
125
|
-
'H11',
|
|
126
|
-
'A12',
|
|
127
|
-
'B12',
|
|
128
|
-
'C12',
|
|
129
|
-
'D12',
|
|
130
|
-
'E12',
|
|
131
|
-
'F12',
|
|
132
|
-
'G12',
|
|
133
|
-
'H12',
|
|
134
|
-
]
|
|
135
|
-
|
|
136
|
-
describe('findWellAt', () => {
|
|
137
|
-
it('should determine if given (x, y) is within a rectangular well', () => {
|
|
138
|
-
const def: any = {
|
|
139
|
-
wells: {
|
|
140
|
-
A1: {
|
|
141
|
-
shape: 'rectangular',
|
|
142
|
-
x: 200,
|
|
143
|
-
y: 200,
|
|
144
|
-
xDimension: 10,
|
|
145
|
-
yDimension: 10,
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
}
|
|
149
|
-
const middle = findWellAt(def, 200, 200)
|
|
150
|
-
expect(middle).toBe('A1')
|
|
151
|
-
|
|
152
|
-
const insideCornerNE = findWellAt(def, 200 - 4, 200 + 4)
|
|
153
|
-
expect(insideCornerNE).toEqual('A1')
|
|
154
|
-
|
|
155
|
-
// exactly at an edge doesn't count
|
|
156
|
-
const exactlyOnCornerNE = findWellAt(def, 200 - 5, 200 + 5)
|
|
157
|
-
expect(exactlyOnCornerNE).toBeUndefined()
|
|
158
|
-
|
|
159
|
-
const exactlyOnWEdge = findWellAt(def, 200, 200 - 5)
|
|
160
|
-
expect(exactlyOnWEdge).toBeUndefined()
|
|
161
|
-
|
|
162
|
-
const justOutsideToEast = findWellAt(def, 200 + 5.1, 200)
|
|
163
|
-
expect(justOutsideToEast).toBeUndefined()
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
it('should determine if given (x, y) is within a circular well', () => {
|
|
167
|
-
const def: any = {
|
|
168
|
-
wells: {
|
|
169
|
-
A1: {
|
|
170
|
-
shape: 'circular',
|
|
171
|
-
x: 200,
|
|
172
|
-
y: 200,
|
|
173
|
-
diameter: 10,
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
}
|
|
177
|
-
const middle = findWellAt(def, 200, 200)
|
|
178
|
-
expect(middle).toBe('A1')
|
|
179
|
-
|
|
180
|
-
const inside = findWellAt(def, 200 - 1, 200 + 1)
|
|
181
|
-
expect(inside).toEqual('A1')
|
|
182
|
-
|
|
183
|
-
// exactly at an edge doesn't count
|
|
184
|
-
const exactlyOnWEdge = findWellAt(def, 200, 200 - 5)
|
|
185
|
-
expect(exactlyOnWEdge).toBeUndefined()
|
|
186
|
-
|
|
187
|
-
const justOutsideToEast = findWellAt(def, 200 + 5.1, 200)
|
|
188
|
-
expect(justOutsideToEast).toBeUndefined()
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
describe('canPipetteUseLabware', () => {
|
|
192
|
-
let canPipetteUseLabware: WellSetHelpers['canPipetteUseLabware']
|
|
193
|
-
|
|
194
|
-
beforeEach(() => {
|
|
195
|
-
const helpers = makeWellSetHelpers()
|
|
196
|
-
canPipetteUseLabware = helpers.canPipetteUseLabware
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
it('returns false when wells are too close together for multi channel pipettes', () => {
|
|
200
|
-
const labwareDef = fixtureOverlappyWellplate
|
|
201
|
-
const pipette = fixtureP10Multi
|
|
202
|
-
const pipette96 = fixtureP100096
|
|
203
|
-
|
|
204
|
-
expect(canPipetteUseLabware(pipette, labwareDef)).toBe(false)
|
|
205
|
-
expect(canPipetteUseLabware(pipette96, labwareDef)).toBe(false)
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
it('returns true when pipette is single channel', () => {
|
|
209
|
-
const labwareDef = fixtureOverlappyWellplate
|
|
210
|
-
const pipette = fixtureP10Single
|
|
211
|
-
|
|
212
|
-
expect(canPipetteUseLabware(pipette, labwareDef)).toBe(true)
|
|
213
|
-
})
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
describe('getWellSetForMultichannel (integration test)', () => {
|
|
217
|
-
let getWellSetForMultichannel: WellSetHelpers['getWellSetForMultichannel']
|
|
218
|
-
|
|
219
|
-
beforeEach(() => {
|
|
220
|
-
const helpers = makeWellSetHelpers()
|
|
221
|
-
getWellSetForMultichannel = helpers.getWellSetForMultichannel
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
it('96-flat', () => {
|
|
225
|
-
const labwareDef = fixture96Plate
|
|
226
|
-
|
|
227
|
-
expect(getWellSetForMultichannel(labwareDef, 'A1', EIGHT_CHANNEL)).toEqual([
|
|
228
|
-
'A1',
|
|
229
|
-
'B1',
|
|
230
|
-
'C1',
|
|
231
|
-
'D1',
|
|
232
|
-
'E1',
|
|
233
|
-
'F1',
|
|
234
|
-
'G1',
|
|
235
|
-
'H1',
|
|
236
|
-
])
|
|
237
|
-
|
|
238
|
-
expect(getWellSetForMultichannel(labwareDef, 'B1', EIGHT_CHANNEL)).toEqual([
|
|
239
|
-
'A1',
|
|
240
|
-
'B1',
|
|
241
|
-
'C1',
|
|
242
|
-
'D1',
|
|
243
|
-
'E1',
|
|
244
|
-
'F1',
|
|
245
|
-
'G1',
|
|
246
|
-
'H1',
|
|
247
|
-
])
|
|
248
|
-
|
|
249
|
-
expect(getWellSetForMultichannel(labwareDef, 'H1', EIGHT_CHANNEL)).toEqual([
|
|
250
|
-
'A1',
|
|
251
|
-
'B1',
|
|
252
|
-
'C1',
|
|
253
|
-
'D1',
|
|
254
|
-
'E1',
|
|
255
|
-
'F1',
|
|
256
|
-
'G1',
|
|
257
|
-
'H1',
|
|
258
|
-
])
|
|
259
|
-
|
|
260
|
-
expect(getWellSetForMultichannel(labwareDef, 'A2', EIGHT_CHANNEL)).toEqual([
|
|
261
|
-
'A2',
|
|
262
|
-
'B2',
|
|
263
|
-
'C2',
|
|
264
|
-
'D2',
|
|
265
|
-
'E2',
|
|
266
|
-
'F2',
|
|
267
|
-
'G2',
|
|
268
|
-
'H2',
|
|
269
|
-
])
|
|
270
|
-
|
|
271
|
-
// 96-channel
|
|
272
|
-
expect(
|
|
273
|
-
getWellSetForMultichannel(labwareDef, 'A1', NINETY_SIX_CHANNEL)
|
|
274
|
-
).toEqual(wellsFor96WellPlate)
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
it('invalid well', () => {
|
|
278
|
-
const labwareDef = fixture96Plate
|
|
279
|
-
|
|
280
|
-
expect(
|
|
281
|
-
getWellSetForMultichannel(labwareDef, 'A13', EIGHT_CHANNEL)
|
|
282
|
-
).toBeFalsy()
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
it('trough-12row', () => {
|
|
286
|
-
const labwareDef = fixture12Trough
|
|
287
|
-
|
|
288
|
-
expect(getWellSetForMultichannel(labwareDef, 'A1', EIGHT_CHANNEL)).toEqual([
|
|
289
|
-
'A1',
|
|
290
|
-
'A1',
|
|
291
|
-
'A1',
|
|
292
|
-
'A1',
|
|
293
|
-
'A1',
|
|
294
|
-
'A1',
|
|
295
|
-
'A1',
|
|
296
|
-
'A1',
|
|
297
|
-
])
|
|
298
|
-
|
|
299
|
-
expect(getWellSetForMultichannel(labwareDef, 'A2', EIGHT_CHANNEL)).toEqual([
|
|
300
|
-
'A2',
|
|
301
|
-
'A2',
|
|
302
|
-
'A2',
|
|
303
|
-
'A2',
|
|
304
|
-
'A2',
|
|
305
|
-
'A2',
|
|
306
|
-
'A2',
|
|
307
|
-
'A2',
|
|
308
|
-
])
|
|
309
|
-
|
|
310
|
-
// 96-channel
|
|
311
|
-
expect(
|
|
312
|
-
getWellSetForMultichannel(labwareDef, 'A1', NINETY_SIX_CHANNEL)
|
|
313
|
-
).toEqual(wellsForReservoir)
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
it('384-plate', () => {
|
|
317
|
-
const labwareDef = fixture384Plate
|
|
318
|
-
const well96Channel = 'A1'
|
|
319
|
-
const all384Wells = orderWells(labwareDef.ordering, 't2b', 'l2r')
|
|
320
|
-
const ninetySixChannelWells = get96Channel384WellPlateWells(
|
|
321
|
-
all384Wells,
|
|
322
|
-
well96Channel
|
|
323
|
-
)
|
|
324
|
-
|
|
325
|
-
expect(getWellSetForMultichannel(labwareDef, 'C1', EIGHT_CHANNEL)).toEqual([
|
|
326
|
-
'A1',
|
|
327
|
-
'C1',
|
|
328
|
-
'E1',
|
|
329
|
-
'G1',
|
|
330
|
-
'I1',
|
|
331
|
-
'K1',
|
|
332
|
-
'M1',
|
|
333
|
-
'O1',
|
|
334
|
-
])
|
|
335
|
-
|
|
336
|
-
expect(getWellSetForMultichannel(labwareDef, 'F2', EIGHT_CHANNEL)).toEqual([
|
|
337
|
-
'B2',
|
|
338
|
-
'D2',
|
|
339
|
-
'F2',
|
|
340
|
-
'H2',
|
|
341
|
-
'J2',
|
|
342
|
-
'L2',
|
|
343
|
-
'N2',
|
|
344
|
-
'P2',
|
|
345
|
-
])
|
|
346
|
-
|
|
347
|
-
// 96-channel
|
|
348
|
-
expect(
|
|
349
|
-
getWellSetForMultichannel(labwareDef, well96Channel, NINETY_SIX_CHANNEL)
|
|
350
|
-
).toEqual(ninetySixChannelWells)
|
|
351
|
-
})
|
|
352
|
-
})
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// TODO(jr, 10/19/23): should extend getWellNamePerMultiTip to use similar math for 96-channel and 384 well plates
|
|
2
|
-
// instead of special casing using this util
|
|
3
|
-
export function get96Channel384WellPlateWells(
|
|
4
|
-
all384Wells: string[],
|
|
5
|
-
well: string
|
|
6
|
-
): string[] {
|
|
7
|
-
const totalWells = 96 * 2 // multiplying 2 because we will remove either odd or even numbers
|
|
8
|
-
|
|
9
|
-
const filterWellsFor96Channel = (start: number, isOdd: boolean): string[] => {
|
|
10
|
-
const filteredWells: string[] = []
|
|
11
|
-
let count = start
|
|
12
|
-
for (let i = 0; i < totalWells; i++) {
|
|
13
|
-
if (count < all384Wells.length) {
|
|
14
|
-
const well = all384Wells[count]
|
|
15
|
-
const numberFromWell = well.match(/\d+/)
|
|
16
|
-
if (numberFromWell) {
|
|
17
|
-
const number = parseInt(numberFromWell[0])
|
|
18
|
-
if ((number % 2 === 1 && isOdd) || (number % 2 === 0 && !isOdd)) {
|
|
19
|
-
filteredWells.push(well)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
count += 2
|
|
23
|
-
} else {
|
|
24
|
-
break
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return filteredWells
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const allSetsOfWells = [
|
|
31
|
-
filterWellsFor96Channel(0, true),
|
|
32
|
-
filterWellsFor96Channel(1, true),
|
|
33
|
-
filterWellsFor96Channel(0, false),
|
|
34
|
-
filterWellsFor96Channel(1, false),
|
|
35
|
-
]
|
|
36
|
-
|
|
37
|
-
for (const wells of allSetsOfWells) {
|
|
38
|
-
if (wells.includes(well)) {
|
|
39
|
-
return wells
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return []
|
|
44
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { AddressableAreaName } from '../../deck'
|
|
2
|
-
import type { RunTimeCommand } from '../../protocol'
|
|
3
|
-
|
|
4
|
-
export function getAddressableAreasInProtocol(
|
|
5
|
-
commands: RunTimeCommand[]
|
|
6
|
-
): AddressableAreaName[] {
|
|
7
|
-
return commands.reduce<AddressableAreaName[]>((acc, command) => {
|
|
8
|
-
if (
|
|
9
|
-
command.commandType === 'moveLabware' &&
|
|
10
|
-
command.params.newLocation !== 'offDeck' &&
|
|
11
|
-
'slotName' in command.params.newLocation &&
|
|
12
|
-
!acc.includes(command.params.newLocation.slotName as AddressableAreaName)
|
|
13
|
-
) {
|
|
14
|
-
return [
|
|
15
|
-
...acc,
|
|
16
|
-
command.params.newLocation.slotName as AddressableAreaName,
|
|
17
|
-
]
|
|
18
|
-
} else if (
|
|
19
|
-
command.commandType === 'moveLabware' &&
|
|
20
|
-
command.params.newLocation !== 'offDeck' &&
|
|
21
|
-
'addressableAreaName' in command.params.newLocation &&
|
|
22
|
-
!acc.includes(
|
|
23
|
-
command.params.newLocation.addressableAreaName as AddressableAreaName
|
|
24
|
-
)
|
|
25
|
-
) {
|
|
26
|
-
return [
|
|
27
|
-
...acc,
|
|
28
|
-
command.params.newLocation.addressableAreaName as AddressableAreaName,
|
|
29
|
-
]
|
|
30
|
-
} else if (
|
|
31
|
-
(command.commandType === 'loadLabware' ||
|
|
32
|
-
command.commandType === 'loadModule') &&
|
|
33
|
-
command.params.location !== 'offDeck' &&
|
|
34
|
-
'slotName' in command.params.location &&
|
|
35
|
-
!acc.includes(command.params.location.slotName as AddressableAreaName)
|
|
36
|
-
) {
|
|
37
|
-
return [...acc, command.params.location.slotName as AddressableAreaName]
|
|
38
|
-
} else if (
|
|
39
|
-
command.commandType === 'loadLabware' &&
|
|
40
|
-
command.params.location !== 'offDeck' &&
|
|
41
|
-
'addressableAreaName' in command.params.location &&
|
|
42
|
-
!acc.includes(
|
|
43
|
-
command.params.location.addressableAreaName as AddressableAreaName
|
|
44
|
-
)
|
|
45
|
-
) {
|
|
46
|
-
return [
|
|
47
|
-
...acc,
|
|
48
|
-
command.params.location.addressableAreaName as AddressableAreaName,
|
|
49
|
-
]
|
|
50
|
-
} else if (
|
|
51
|
-
command.commandType === 'moveToAddressableArea' &&
|
|
52
|
-
!acc.includes(command.params.addressableAreaName as AddressableAreaName)
|
|
53
|
-
) {
|
|
54
|
-
return [...acc, command.params.addressableAreaName as AddressableAreaName]
|
|
55
|
-
} else {
|
|
56
|
-
return acc
|
|
57
|
-
}
|
|
58
|
-
}, [])
|
|
59
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { getLabwareDefURI } from '.'
|
|
2
|
-
import type { RunTimeCommand, LabwareDefinition2 } from '..'
|
|
3
|
-
|
|
4
|
-
export interface LabwareDefinitionsByUri {
|
|
5
|
-
[defURI: string]: LabwareDefinition2
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function getLoadedLabwareDefinitionsByUri(
|
|
9
|
-
commands: RunTimeCommand[]
|
|
10
|
-
): LabwareDefinitionsByUri {
|
|
11
|
-
return commands.reduce((acc, command) => {
|
|
12
|
-
if (command.commandType === 'loadLabware') {
|
|
13
|
-
const labwareDef: LabwareDefinition2 | undefined =
|
|
14
|
-
command.result?.definition
|
|
15
|
-
if (labwareDef == null) {
|
|
16
|
-
console.warn(
|
|
17
|
-
`could not find a labware definition in the results of load labware command: ${JSON.stringify(
|
|
18
|
-
command
|
|
19
|
-
)}`
|
|
20
|
-
)
|
|
21
|
-
return acc
|
|
22
|
-
} else {
|
|
23
|
-
const definitionUri = getLabwareDefURI(labwareDef)
|
|
24
|
-
return { ...acc, [definitionUri]: labwareDef }
|
|
25
|
-
}
|
|
26
|
-
} else {
|
|
27
|
-
return acc
|
|
28
|
-
}
|
|
29
|
-
}, {})
|
|
30
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
// NOTE: Ian 2019-10-24 these are by-eye numbers that intentionally
|
|
2
|
-
// ignore the real-life data to emphasize overhangs etc
|
|
3
|
-
import {
|
|
4
|
-
MAGNETIC_MODULE_TYPE,
|
|
5
|
-
TEMPERATURE_MODULE_TYPE,
|
|
6
|
-
THERMOCYCLER_MODULE_TYPE,
|
|
7
|
-
HEATERSHAKER_MODULE_TYPE,
|
|
8
|
-
STD_SLOT_X_DIM as SLOT_X,
|
|
9
|
-
STD_SLOT_Y_DIM as SLOT_Y,
|
|
10
|
-
STD_SLOT_DIVIDER_WIDTH as DIVIDER,
|
|
11
|
-
SPAN7_8_10_11_SLOT,
|
|
12
|
-
MAGNETIC_BLOCK_TYPE,
|
|
13
|
-
} from '../constants'
|
|
14
|
-
import { ModuleType, ModuleOrientation } from '../types'
|
|
15
|
-
// NOTE: all dims are in 'left' orientation. Rotate & transform to obtain 'right' orientation.
|
|
16
|
-
|
|
17
|
-
export interface ModuleVizDims {
|
|
18
|
-
xOffset: number
|
|
19
|
-
yOffset: number
|
|
20
|
-
xDimension: number
|
|
21
|
-
yDimension: number
|
|
22
|
-
childXOffset: number
|
|
23
|
-
childYOffset: number
|
|
24
|
-
childXDimension: number
|
|
25
|
-
childYDimension: number
|
|
26
|
-
}
|
|
27
|
-
const MODULE_VIZ_DIMS: Record<ModuleType, ModuleVizDims> = {
|
|
28
|
-
[MAGNETIC_MODULE_TYPE]: {
|
|
29
|
-
xOffset: -1 * (SLOT_X * 0.2 + DIVIDER),
|
|
30
|
-
yOffset: -1 * DIVIDER,
|
|
31
|
-
xDimension: SLOT_X * 1.2 + DIVIDER * 2,
|
|
32
|
-
yDimension: SLOT_Y + DIVIDER * 2,
|
|
33
|
-
childXOffset: 0,
|
|
34
|
-
childYOffset: 0,
|
|
35
|
-
childXDimension: SLOT_X,
|
|
36
|
-
childYDimension: SLOT_Y,
|
|
37
|
-
},
|
|
38
|
-
[TEMPERATURE_MODULE_TYPE]: {
|
|
39
|
-
xOffset: -1 * (SLOT_X * 0.4 + DIVIDER),
|
|
40
|
-
yOffset: -1 * DIVIDER,
|
|
41
|
-
xDimension: SLOT_X * 1.4 + DIVIDER * 2,
|
|
42
|
-
yDimension: SLOT_Y + DIVIDER * 2,
|
|
43
|
-
childXOffset: 0,
|
|
44
|
-
childYOffset: 0,
|
|
45
|
-
childXDimension: SLOT_X,
|
|
46
|
-
childYDimension: SLOT_Y,
|
|
47
|
-
},
|
|
48
|
-
[THERMOCYCLER_MODULE_TYPE]: {
|
|
49
|
-
xOffset: -8,
|
|
50
|
-
yOffset: 0,
|
|
51
|
-
xDimension: SLOT_X + DIVIDER + 32,
|
|
52
|
-
yDimension: SLOT_Y * 2.4,
|
|
53
|
-
childXOffset: 12,
|
|
54
|
-
childYOffset: SLOT_Y,
|
|
55
|
-
childXDimension: SLOT_X,
|
|
56
|
-
childYDimension: SLOT_Y,
|
|
57
|
-
},
|
|
58
|
-
// TODO(sh, 2022-02-28): This is stubbed out using magdeck dimensions, all of this logic should be deprecated
|
|
59
|
-
[HEATERSHAKER_MODULE_TYPE]: {
|
|
60
|
-
xOffset: -1 * (SLOT_X * 0.2 + DIVIDER),
|
|
61
|
-
yOffset: -1 * DIVIDER,
|
|
62
|
-
xDimension: SLOT_X * 1.2 + DIVIDER * 2,
|
|
63
|
-
yDimension: SLOT_Y + DIVIDER * 2,
|
|
64
|
-
childXOffset: 0,
|
|
65
|
-
childYOffset: 0,
|
|
66
|
-
childXDimension: SLOT_X,
|
|
67
|
-
childYDimension: SLOT_Y,
|
|
68
|
-
},
|
|
69
|
-
// TODO(sh, 2022-02-28): This is stubbed out using magdeck dimensions, all of this logic should be deprecated
|
|
70
|
-
[MAGNETIC_BLOCK_TYPE]: {
|
|
71
|
-
xOffset: -1 * (SLOT_X * 0.2 + DIVIDER),
|
|
72
|
-
yOffset: -1 * DIVIDER,
|
|
73
|
-
xDimension: SLOT_X * 1.2 + DIVIDER * 2,
|
|
74
|
-
yDimension: SLOT_Y + DIVIDER * 2,
|
|
75
|
-
childXOffset: 0,
|
|
76
|
-
childYOffset: 0,
|
|
77
|
-
childXDimension: SLOT_X,
|
|
78
|
-
childYDimension: SLOT_Y,
|
|
79
|
-
},
|
|
80
|
-
}
|
|
81
|
-
export const getModuleVizDims = (
|
|
82
|
-
orientation: ModuleOrientation,
|
|
83
|
-
moduleType: ModuleType
|
|
84
|
-
): ModuleVizDims => {
|
|
85
|
-
const dims = MODULE_VIZ_DIMS[moduleType]
|
|
86
|
-
if (orientation === 'left') return dims
|
|
87
|
-
// if orientation is 'right', get origins by rotating 180 about slot center
|
|
88
|
-
return {
|
|
89
|
-
...dims,
|
|
90
|
-
xOffset: SLOT_X - dims.xOffset - dims.xDimension,
|
|
91
|
-
yOffset: SLOT_Y - dims.yOffset - dims.yDimension,
|
|
92
|
-
childXOffset: SLOT_X - dims.childXOffset - dims.childXDimension,
|
|
93
|
-
childYOffset: SLOT_Y - dims.childYOffset - dims.childYDimension,
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
type DeckSlot = string
|
|
97
|
-
const LEFT_SIDE_SLOTS: DeckSlot[] = ['1', '4', '7', '10', SPAN7_8_10_11_SLOT]
|
|
98
|
-
export const inferModuleOrientationFromSlot = (
|
|
99
|
-
slot: DeckSlot
|
|
100
|
-
): ModuleOrientation => {
|
|
101
|
-
// NOTE: defaults to 'left' even for center slots and spanning slots.
|
|
102
|
-
// That's consistent with non-rotatable modules (thermocycler) being
|
|
103
|
-
// considered as 'left' all the time, like we do in MODULE_VIZ_DIMS.
|
|
104
|
-
if (!LEFT_SIDE_SLOTS.includes(slot)) {
|
|
105
|
-
return 'right'
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return 'left'
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export const inferModuleOrientationFromXCoordinate = (
|
|
112
|
-
xCoordinate: number
|
|
113
|
-
): ModuleOrientation => {
|
|
114
|
-
if (xCoordinate === 0) {
|
|
115
|
-
return 'left'
|
|
116
|
-
}
|
|
117
|
-
return 'right'
|
|
118
|
-
}
|