@opentrons/shared-data 0.1.2-alpha.1 → 0.1.2-alpha.3
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/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 -38
- 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 -405
- package/js/cypressUtils.ts +0 -35
- package/js/errors.ts +0 -33
- package/js/fixtures.ts +0 -156
- package/js/getLabware.ts +0 -145
- 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__/getSimplestFlexDeckConfig.test.ts +0 -176
- 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 -98
- package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +0 -30
- package/js/helpers/getModuleVizDims.ts +0 -118
- package/js/helpers/getOccludedSlotCountForModule.ts +0 -13
- package/js/helpers/getSimplestFlexDeckConfig.ts +0 -183
- 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 -348
- 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 -561
package/js/helpers/wellSets.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
// A "well set" is an array of wells corresponding to each tip of an 8 channel pipette.
|
|
2
|
-
// Eg ['A1', 'C1', 'E1', 'G1', 'I1', 'K1', 'M1', 'O1'] is a well set in a 384 plate.
|
|
3
|
-
//
|
|
4
|
-
// A trough-like well that encompasses all 8 tips at once has a well set
|
|
5
|
-
// ['A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A1']
|
|
6
|
-
//
|
|
7
|
-
// Well sets are determined by geometry.
|
|
8
|
-
//
|
|
9
|
-
// Labware with multiple positions for an 8-channel pipette have multiple well sets.
|
|
10
|
-
// For example, a 96 plate has 12 well sets, one for each column.
|
|
11
|
-
// A 384 plate has 48 well sets, 2 for each column b/c it has staggered columns.
|
|
12
|
-
//
|
|
13
|
-
// If a labware has no possible well sets, then it is not compatible with multi-channel pipettes.
|
|
14
|
-
import uniq from 'lodash/uniq'
|
|
15
|
-
|
|
16
|
-
import { getWellNamePerMultiTip } from './getWellNamePerMultiTip'
|
|
17
|
-
import { get96Channel384WellPlateWells, getLabwareDefURI, orderWells } from '.'
|
|
18
|
-
import type { LabwareDefinition2, PipetteNameSpecs } from '../types'
|
|
19
|
-
|
|
20
|
-
type WellSetByPrimaryWell = string[][]
|
|
21
|
-
|
|
22
|
-
// Compute all well sets for a labware def (non-memoized)
|
|
23
|
-
function _getAllWellSetsForLabware(
|
|
24
|
-
labwareDef: LabwareDefinition2
|
|
25
|
-
): WellSetByPrimaryWell {
|
|
26
|
-
const allWells: string[] = Object.keys(labwareDef.wells)
|
|
27
|
-
|
|
28
|
-
return allWells.reduce(
|
|
29
|
-
(acc: WellSetByPrimaryWell, well: string): WellSetByPrimaryWell => {
|
|
30
|
-
const wellSet = getWellNamePerMultiTip(labwareDef, well, 8)
|
|
31
|
-
if (wellSet === null) {
|
|
32
|
-
return acc
|
|
33
|
-
} else {
|
|
34
|
-
return [...acc, wellSet]
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
[]
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// creates memoized getAllWellSetsForLabware + getWellSetForMultichannel fns.
|
|
42
|
-
export interface WellSetHelpers {
|
|
43
|
-
getAllWellSetsForLabware: (
|
|
44
|
-
labwareDef: LabwareDefinition2
|
|
45
|
-
) => WellSetByPrimaryWell
|
|
46
|
-
|
|
47
|
-
getWellSetForMultichannel: (
|
|
48
|
-
labwareDef: LabwareDefinition2,
|
|
49
|
-
well: string,
|
|
50
|
-
channels: 8 | 96
|
|
51
|
-
) => string[] | null | undefined
|
|
52
|
-
|
|
53
|
-
canPipetteUseLabware: (
|
|
54
|
-
pipetteSpec: PipetteNameSpecs,
|
|
55
|
-
labwareDef?: LabwareDefinition2,
|
|
56
|
-
trashName?: string
|
|
57
|
-
) => boolean
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export const makeWellSetHelpers = (): WellSetHelpers => {
|
|
61
|
-
const cache: Partial<{
|
|
62
|
-
[labwareDefURI: string]: {
|
|
63
|
-
labwareDef: LabwareDefinition2
|
|
64
|
-
wellSetByPrimaryWell: WellSetByPrimaryWell
|
|
65
|
-
} | null
|
|
66
|
-
}> = {}
|
|
67
|
-
|
|
68
|
-
const getAllWellSetsForLabware = (
|
|
69
|
-
labwareDef: LabwareDefinition2
|
|
70
|
-
): WellSetByPrimaryWell => {
|
|
71
|
-
const labwareDefURI = getLabwareDefURI(labwareDef)
|
|
72
|
-
const c = cache[labwareDefURI]
|
|
73
|
-
|
|
74
|
-
// use cached version only if labwareDef is shallowly equal, in case
|
|
75
|
-
// custom labware defs are changed without giving them a new URI
|
|
76
|
-
if (c && c.labwareDef === labwareDef) {
|
|
77
|
-
return c.wellSetByPrimaryWell
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const wellSetByPrimaryWell = _getAllWellSetsForLabware(labwareDef)
|
|
81
|
-
|
|
82
|
-
cache[labwareDefURI] = {
|
|
83
|
-
labwareDef,
|
|
84
|
-
wellSetByPrimaryWell,
|
|
85
|
-
}
|
|
86
|
-
return wellSetByPrimaryWell
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const getWellSetForMultichannel = (
|
|
90
|
-
labwareDef: LabwareDefinition2,
|
|
91
|
-
well: string,
|
|
92
|
-
channels: 8 | 96
|
|
93
|
-
): string[] | null | undefined => {
|
|
94
|
-
/** Given a well for a labware, returns the well set it belongs to (or null)
|
|
95
|
-
* for 8-channel access.
|
|
96
|
-
* Ie: C2 for 96-flat => ['A2', 'B2', 'C2', ... 'H2']
|
|
97
|
-
* Or A1 for trough => ['A1', 'A1', 'A1', ...]
|
|
98
|
-
**/
|
|
99
|
-
const allWellSetsFor8Channel = getAllWellSetsForLabware(labwareDef)
|
|
100
|
-
/** getting all wells from the plate and turning into 1D array for 96-channel
|
|
101
|
-
*/
|
|
102
|
-
const orderedWellsFor96Channel = orderWells(
|
|
103
|
-
labwareDef.ordering,
|
|
104
|
-
't2b',
|
|
105
|
-
'l2r'
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
let ninetySixChannelWells = orderedWellsFor96Channel
|
|
109
|
-
/** special casing 384 well plates to be every other well
|
|
110
|
-
* both on the x and y ases.
|
|
111
|
-
*/
|
|
112
|
-
if (orderedWellsFor96Channel.length === 384) {
|
|
113
|
-
ninetySixChannelWells = get96Channel384WellPlateWells(
|
|
114
|
-
orderedWellsFor96Channel,
|
|
115
|
-
well
|
|
116
|
-
)
|
|
117
|
-
}
|
|
118
|
-
return channels === 8
|
|
119
|
-
? allWellSetsFor8Channel.find((wellSet: string[]) =>
|
|
120
|
-
wellSet.includes(well)
|
|
121
|
-
)
|
|
122
|
-
: ninetySixChannelWells
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const canPipetteUseLabware = (
|
|
126
|
-
pipetteSpec: PipetteNameSpecs,
|
|
127
|
-
labwareDef?: LabwareDefinition2,
|
|
128
|
-
trashName?: string
|
|
129
|
-
): boolean => {
|
|
130
|
-
if (pipetteSpec.channels === 1 || trashName != null) {
|
|
131
|
-
// assume all labware can be used by single-channel
|
|
132
|
-
return true
|
|
133
|
-
}
|
|
134
|
-
if (labwareDef != null) {
|
|
135
|
-
const allWellSets = getAllWellSetsForLabware(labwareDef)
|
|
136
|
-
return allWellSets.some(wellSet => {
|
|
137
|
-
const uniqueWells = uniq(wellSet)
|
|
138
|
-
// if all wells are non-null, and there are either 1 (reservoir-like)
|
|
139
|
-
// or 8 (well plate-like) unique wells in the set,
|
|
140
|
-
// then assume both 8 and 96 channel pipettes will work
|
|
141
|
-
return (
|
|
142
|
-
uniqueWells.every(well => well != null) &&
|
|
143
|
-
[1, 8].includes(uniqueWells.length)
|
|
144
|
-
)
|
|
145
|
-
})
|
|
146
|
-
} else {
|
|
147
|
-
return false
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return {
|
|
151
|
-
getAllWellSetsForLabware,
|
|
152
|
-
getWellSetForMultichannel,
|
|
153
|
-
canPipetteUseLabware,
|
|
154
|
-
}
|
|
155
|
-
}
|
package/js/index.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export * from './constants'
|
|
2
|
-
export * from './getLabware'
|
|
3
|
-
export * from './helpers'
|
|
4
|
-
export * from './pipettes'
|
|
5
|
-
export * from './types'
|
|
6
|
-
export * from './labwareTools'
|
|
7
|
-
export * from './modules'
|
|
8
|
-
export * from './fixtures'
|
|
9
|
-
export * from './gripper'
|
|
10
|
-
export * from '../protocol'
|
|
11
|
-
export * from '../deck'
|
|
12
|
-
export * from './titleCase'
|
|
13
|
-
export * from './errors'
|
|
14
|
-
export * from './fixtures'
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { createDefaultDisplayName } from '..'
|
|
2
|
-
|
|
3
|
-
import type { RegularNameProps } from '..'
|
|
4
|
-
|
|
5
|
-
interface TestCase {
|
|
6
|
-
testName: string
|
|
7
|
-
args: RegularNameProps
|
|
8
|
-
expected: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
describe('createDefaultDisplayName', () => {
|
|
12
|
-
const testCases: TestCase[] = [
|
|
13
|
-
{
|
|
14
|
-
testName: 'handle the minimal case',
|
|
15
|
-
args: {
|
|
16
|
-
displayCategory: 'wellPlate',
|
|
17
|
-
displayVolumeUnits: 'µL',
|
|
18
|
-
gridRows: 2,
|
|
19
|
-
gridColumns: 3,
|
|
20
|
-
totalLiquidVolume: 123,
|
|
21
|
-
},
|
|
22
|
-
expected: 'Generic 6 Well Plate 123 µL',
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
testName: 'handle a decimal in volume',
|
|
26
|
-
args: {
|
|
27
|
-
displayCategory: 'wellPlate',
|
|
28
|
-
displayVolumeUnits: 'µL',
|
|
29
|
-
gridRows: 2,
|
|
30
|
-
gridColumns: 3,
|
|
31
|
-
totalLiquidVolume: 12.3,
|
|
32
|
-
},
|
|
33
|
-
expected: 'Generic 6 Well Plate 12.3 µL',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
testName: 'calculate wells = rows x cols',
|
|
37
|
-
args: {
|
|
38
|
-
displayCategory: 'wellPlate',
|
|
39
|
-
displayVolumeUnits: 'µL',
|
|
40
|
-
gridRows: 8,
|
|
41
|
-
gridColumns: 10,
|
|
42
|
-
totalLiquidVolume: 123,
|
|
43
|
-
},
|
|
44
|
-
expected: 'Generic 80 Well Plate 123 µL',
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
testName: 'handle tube rack (example of a different displayCategory)',
|
|
48
|
-
args: {
|
|
49
|
-
displayCategory: 'tubeRack',
|
|
50
|
-
displayVolumeUnits: 'µL',
|
|
51
|
-
gridRows: 2,
|
|
52
|
-
gridColumns: 3,
|
|
53
|
-
totalLiquidVolume: 123,
|
|
54
|
-
},
|
|
55
|
-
expected: 'Generic 6 Tube Rack 123 µL',
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
testName: 'append loadNamePostfix',
|
|
59
|
-
args: {
|
|
60
|
-
displayCategory: 'wellPlate',
|
|
61
|
-
displayVolumeUnits: 'µL',
|
|
62
|
-
gridRows: 2,
|
|
63
|
-
gridColumns: 3,
|
|
64
|
-
totalLiquidVolume: 123,
|
|
65
|
-
loadNamePostfix: ['spam ', ' blah', 'PCR'],
|
|
66
|
-
},
|
|
67
|
-
expected: 'Generic 6 Well Plate 123 µL Spam Blah PCR',
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
testName: 'support brand name when specified (ignore extra whitespace)',
|
|
71
|
-
args: {
|
|
72
|
-
displayCategory: 'wellPlate',
|
|
73
|
-
displayVolumeUnits: 'µL',
|
|
74
|
-
gridRows: 2,
|
|
75
|
-
gridColumns: 3,
|
|
76
|
-
totalLiquidVolume: 123,
|
|
77
|
-
brandName: ' cool brand ',
|
|
78
|
-
},
|
|
79
|
-
expected: 'Cool Brand 6 Well Plate 123 µL',
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
testName: 'support brand name when specified (capitalization)',
|
|
83
|
-
args: {
|
|
84
|
-
displayCategory: 'wellPlate',
|
|
85
|
-
displayVolumeUnits: 'µL',
|
|
86
|
-
gridRows: 2,
|
|
87
|
-
gridColumns: 3,
|
|
88
|
-
totalLiquidVolume: 123,
|
|
89
|
-
brandName: ' BIO tech',
|
|
90
|
-
},
|
|
91
|
-
expected: 'BIO Tech 6 Well Plate 123 µL',
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
testName: 'support mL when specified (volume number always in µL!)',
|
|
95
|
-
args: {
|
|
96
|
-
displayCategory: 'wellPlate',
|
|
97
|
-
displayVolumeUnits: 'mL',
|
|
98
|
-
gridRows: 2,
|
|
99
|
-
gridColumns: 3,
|
|
100
|
-
totalLiquidVolume: 123,
|
|
101
|
-
},
|
|
102
|
-
expected: 'Generic 6 Well Plate 0.123 mL',
|
|
103
|
-
},
|
|
104
|
-
]
|
|
105
|
-
|
|
106
|
-
testCases.forEach(({ testName, args, expected }) => {
|
|
107
|
-
it(`should ${testName}`, () => {
|
|
108
|
-
expect(createDefaultDisplayName(args)).toEqual(expected)
|
|
109
|
-
})
|
|
110
|
-
})
|
|
111
|
-
})
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
import omit from 'lodash/omit'
|
|
2
|
-
import range from 'lodash/range'
|
|
3
|
-
|
|
4
|
-
import { splitWellsOnColumn, sortWells } from '../../helpers/index'
|
|
5
|
-
import fixture_irregular_example_1 from '../../../labware/fixtures/2/fixture_irregular_example_1.json'
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
createIrregularLabware,
|
|
9
|
-
_irregularWellName,
|
|
10
|
-
_generateIrregularLoadName,
|
|
11
|
-
_calculateWellCoord,
|
|
12
|
-
} from '..'
|
|
13
|
-
|
|
14
|
-
import type { LabwareDefinition2, LabwareWellProperties } from '../../types'
|
|
15
|
-
import type { IrregularLabwareProps } from '..'
|
|
16
|
-
|
|
17
|
-
// NOTE: loadName needs to be replaced here b/c fixture has a non-default loadName
|
|
18
|
-
const exampleLabware1 = {
|
|
19
|
-
...fixture_irregular_example_1,
|
|
20
|
-
parameters: {
|
|
21
|
-
...fixture_irregular_example_1.parameters,
|
|
22
|
-
loadName: 'generic_55_tuberack_50x3ml_5x10ml',
|
|
23
|
-
},
|
|
24
|
-
} as LabwareDefinition2
|
|
25
|
-
|
|
26
|
-
describe('test helper functions', () => {
|
|
27
|
-
it('Well name generated correctly', () => {
|
|
28
|
-
const grid = { row: 2, column: 2 }
|
|
29
|
-
|
|
30
|
-
const gridStart = [
|
|
31
|
-
{ rowStart: 'A', colStart: '1', rowStride: 1, colStride: 2 },
|
|
32
|
-
{ rowStart: 'B', colStart: '1', rowStride: 3, colStride: 1 },
|
|
33
|
-
]
|
|
34
|
-
const expected1 = ['A1', 'B1', 'A3', 'B3']
|
|
35
|
-
const expected2 = ['B1', 'E1', 'B2', 'E2']
|
|
36
|
-
|
|
37
|
-
range(grid.column).forEach(colIdx => {
|
|
38
|
-
range(grid.row).forEach(rowIdx => {
|
|
39
|
-
const idx = colIdx * grid.row + rowIdx
|
|
40
|
-
|
|
41
|
-
const wellName1 = _irregularWellName(rowIdx, colIdx, gridStart[0])
|
|
42
|
-
|
|
43
|
-
expect(expected1[idx]).toEqual(wellName1)
|
|
44
|
-
|
|
45
|
-
const wellName2 = _irregularWellName(rowIdx, colIdx, gridStart[1])
|
|
46
|
-
|
|
47
|
-
expect(expected2[idx]).toEqual(wellName2)
|
|
48
|
-
})
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('XYZ generates correctly for each grid', () => {
|
|
53
|
-
const grid = { row: 1, column: 5 }
|
|
54
|
-
const offset = { x: 1, y: 0.5, z: 55.5 }
|
|
55
|
-
const spacing = [
|
|
56
|
-
{ row: 10, column: 10 },
|
|
57
|
-
{ row: 5, column: 14 },
|
|
58
|
-
]
|
|
59
|
-
const well = [
|
|
60
|
-
omit(exampleLabware1.wells.A1, ['x', 'y', 'z']),
|
|
61
|
-
omit(exampleLabware1.wells.B1, ['x', 'y', 'z']),
|
|
62
|
-
] as LabwareWellProperties[]
|
|
63
|
-
|
|
64
|
-
const expectedX1 = [1, 11, 21, 31, 41]
|
|
65
|
-
const expectedY1 = [0.5]
|
|
66
|
-
const expectedX2 = [1, 15, 29, 43, 57]
|
|
67
|
-
const expectedY2 = [0.5]
|
|
68
|
-
|
|
69
|
-
range(grid.column).forEach(colIdx => {
|
|
70
|
-
range(grid.row).forEach(rowIdx => {
|
|
71
|
-
const well1 = _calculateWellCoord(
|
|
72
|
-
rowIdx,
|
|
73
|
-
colIdx,
|
|
74
|
-
spacing[0],
|
|
75
|
-
offset,
|
|
76
|
-
well[0]
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
expect(well1.x).toBeCloseTo(expectedX1[colIdx], 2)
|
|
80
|
-
expect(well1.y).toBeCloseTo(expectedY1[rowIdx], 2)
|
|
81
|
-
expect(well1.z).toBeCloseTo(offset.z - well[0].depth, 2)
|
|
82
|
-
|
|
83
|
-
const well2 = _calculateWellCoord(
|
|
84
|
-
rowIdx,
|
|
85
|
-
colIdx,
|
|
86
|
-
spacing[1],
|
|
87
|
-
offset,
|
|
88
|
-
well[1]
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
expect(well2.x).toBeCloseTo(expectedX2[colIdx], 2)
|
|
92
|
-
expect(well2.y).toBeCloseTo(expectedY2[rowIdx], 2)
|
|
93
|
-
expect(well2.z).toBeCloseTo(offset.z - well[1].depth, 2)
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
})
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
describe('test createIrregularLabware function', () => {
|
|
100
|
-
let labware1: LabwareDefinition2
|
|
101
|
-
let labware1Args: IrregularLabwareProps
|
|
102
|
-
|
|
103
|
-
beforeEach(() => {
|
|
104
|
-
labware1Args = {
|
|
105
|
-
namespace: 'fixture',
|
|
106
|
-
metadata: {
|
|
107
|
-
displayName: 'Fake Irregular Container',
|
|
108
|
-
displayCategory: 'tubeRack',
|
|
109
|
-
displayVolumeUnits: 'mL',
|
|
110
|
-
tags: ['fake', 'opentrons'],
|
|
111
|
-
},
|
|
112
|
-
parameters: {
|
|
113
|
-
format: 'irregular',
|
|
114
|
-
isTiprack: false,
|
|
115
|
-
isMagneticModuleCompatible: false,
|
|
116
|
-
},
|
|
117
|
-
dimensions: {
|
|
118
|
-
xDimension: 127.76,
|
|
119
|
-
yDimension: 85.48,
|
|
120
|
-
zDimension: 64.48,
|
|
121
|
-
},
|
|
122
|
-
well: [
|
|
123
|
-
{
|
|
124
|
-
depth: 10.54,
|
|
125
|
-
shape: 'circular',
|
|
126
|
-
diameter: 10,
|
|
127
|
-
totalLiquidVolume: 3000,
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
depth: 20.54,
|
|
131
|
-
shape: 'circular',
|
|
132
|
-
diameter: 15,
|
|
133
|
-
totalLiquidVolume: 10000,
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
offset: [
|
|
137
|
-
{ x: 10, y: 10, z: 69.48 },
|
|
138
|
-
{ x: 15, y: 15, z: 69.48 },
|
|
139
|
-
],
|
|
140
|
-
grid: [
|
|
141
|
-
{ row: 5, column: 10 },
|
|
142
|
-
{ row: 1, column: 5 },
|
|
143
|
-
],
|
|
144
|
-
spacing: [
|
|
145
|
-
{ row: 5, column: 10 },
|
|
146
|
-
{ row: 5, column: 10 },
|
|
147
|
-
],
|
|
148
|
-
gridStart: [
|
|
149
|
-
{ rowStart: 'A', colStart: '1', rowStride: 2, colStride: 1 },
|
|
150
|
-
{ rowStart: 'B', colStart: '1', rowStride: 1, colStride: 1 },
|
|
151
|
-
],
|
|
152
|
-
}
|
|
153
|
-
labware1 = createIrregularLabware(labware1Args)
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
it('irregular ordering generates as expected', () => {
|
|
157
|
-
const keyList = Object.keys(labware1.wells)
|
|
158
|
-
const generatedOrdering = splitWellsOnColumn(keyList.sort(sortWells))
|
|
159
|
-
expect(labware1.ordering).toEqual(generatedOrdering)
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
it('check labware matches fixture', () => {
|
|
163
|
-
expect(labware1).toEqual(exampleLabware1)
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
it('labware loadName generated correctly for multi-grid labware', () => {
|
|
167
|
-
const loadName = _generateIrregularLoadName({
|
|
168
|
-
grid: [
|
|
169
|
-
{ row: 3, column: 2 },
|
|
170
|
-
{ row: 1, column: 4 },
|
|
171
|
-
],
|
|
172
|
-
well: [
|
|
173
|
-
{
|
|
174
|
-
depth: 20,
|
|
175
|
-
shape: 'circular',
|
|
176
|
-
totalLiquidVolume: 400,
|
|
177
|
-
} as LabwareWellProperties,
|
|
178
|
-
{
|
|
179
|
-
depth: 110,
|
|
180
|
-
shape: 'circular',
|
|
181
|
-
totalLiquidVolume: 2000,
|
|
182
|
-
} as LabwareWellProperties,
|
|
183
|
-
],
|
|
184
|
-
totalWellCount: 10,
|
|
185
|
-
units: 'µL',
|
|
186
|
-
displayCategory: 'wellPlate',
|
|
187
|
-
brand: 'some brand',
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
expect(loadName).toEqual('somebrand_10_wellplate_6x400ul_4x2000ul')
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
it('labware loadName generated correctly for multi-grid labware in other units', () => {
|
|
194
|
-
const loadName = _generateIrregularLoadName({
|
|
195
|
-
grid: [{ row: 3, column: 2 }],
|
|
196
|
-
well: [
|
|
197
|
-
{
|
|
198
|
-
depth: 20,
|
|
199
|
-
shape: 'circular',
|
|
200
|
-
totalLiquidVolume: 4000,
|
|
201
|
-
} as LabwareWellProperties,
|
|
202
|
-
],
|
|
203
|
-
totalWellCount: 6,
|
|
204
|
-
units: 'mL',
|
|
205
|
-
displayCategory: 'wellPlate',
|
|
206
|
-
brand: 'some brand',
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
expect(loadName).toEqual('somebrand_6_wellplate_6x4ml')
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
it('failing to validate against labware schema throws w/o "strict"', () => {
|
|
213
|
-
const args = {
|
|
214
|
-
...labware1Args,
|
|
215
|
-
// negative y offset should fail schema validation by making well `y` negative
|
|
216
|
-
offset: [
|
|
217
|
-
{ x: 10, y: -9999, z: 69.48 },
|
|
218
|
-
{ x: 15, y: -9999, z: 69.48 },
|
|
219
|
-
],
|
|
220
|
-
}
|
|
221
|
-
expect(() => createIrregularLabware(args)).toThrowErrorMatchingSnapshot()
|
|
222
|
-
expect(() =>
|
|
223
|
-
createIrregularLabware({ ...args, strict: false })
|
|
224
|
-
).not.toThrow()
|
|
225
|
-
})
|
|
226
|
-
})
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import omit from 'lodash/omit'
|
|
2
|
-
import range from 'lodash/range'
|
|
3
|
-
import { createRegularLabware } from '..'
|
|
4
|
-
import fixture_regular_example_1 from '../../../labware/fixtures/2/fixture_regular_example_1.json'
|
|
5
|
-
import fixture_regular_example_2 from '../../../labware/fixtures/2/fixture_regular_example_2.json'
|
|
6
|
-
|
|
7
|
-
import type {
|
|
8
|
-
LabwareDefinition2,
|
|
9
|
-
LabwareWellProperties,
|
|
10
|
-
LabwareOffset,
|
|
11
|
-
} from '../../types'
|
|
12
|
-
|
|
13
|
-
import type { RegularLabwareProps } from '..'
|
|
14
|
-
|
|
15
|
-
// NOTE: loadName needs to be replaced here b/c fixture has a non-default loadName
|
|
16
|
-
const exampleLabware1 = {
|
|
17
|
-
...fixture_regular_example_1,
|
|
18
|
-
parameters: {
|
|
19
|
-
...fixture_regular_example_1.parameters,
|
|
20
|
-
loadName: 'opentrons_2_wellplate_100ul',
|
|
21
|
-
},
|
|
22
|
-
} as LabwareDefinition2
|
|
23
|
-
|
|
24
|
-
const exampleLabware2 = {
|
|
25
|
-
...fixture_regular_example_2,
|
|
26
|
-
parameters: {
|
|
27
|
-
...fixture_regular_example_2.parameters,
|
|
28
|
-
loadName: 'generic_6_wellplate_1ml',
|
|
29
|
-
},
|
|
30
|
-
} as LabwareDefinition2
|
|
31
|
-
|
|
32
|
-
describe('createLabware', () => {
|
|
33
|
-
let labware1: LabwareDefinition2
|
|
34
|
-
let labware2: LabwareDefinition2
|
|
35
|
-
let labware2Args: RegularLabwareProps
|
|
36
|
-
let well1: LabwareWellProperties
|
|
37
|
-
let well2: LabwareWellProperties
|
|
38
|
-
let offset1: LabwareOffset
|
|
39
|
-
let offset2: LabwareOffset
|
|
40
|
-
|
|
41
|
-
beforeEach(() => {
|
|
42
|
-
well1 = omit(exampleLabware1.wells.A1, [
|
|
43
|
-
'x',
|
|
44
|
-
'y',
|
|
45
|
-
'z',
|
|
46
|
-
]) as LabwareWellProperties
|
|
47
|
-
|
|
48
|
-
well2 = omit(exampleLabware2.wells.A1, [
|
|
49
|
-
'x',
|
|
50
|
-
'y',
|
|
51
|
-
'z',
|
|
52
|
-
]) as LabwareWellProperties
|
|
53
|
-
|
|
54
|
-
offset1 = { x: 10, y: 10, z: 55 }
|
|
55
|
-
offset2 = { x: 10, y: 10, z: 40 }
|
|
56
|
-
|
|
57
|
-
labware1 = createRegularLabware({
|
|
58
|
-
metadata: exampleLabware1.metadata,
|
|
59
|
-
parameters: exampleLabware1.parameters,
|
|
60
|
-
dimensions: exampleLabware1.dimensions,
|
|
61
|
-
offset: offset1,
|
|
62
|
-
grid: { row: 1, column: 2 },
|
|
63
|
-
spacing: { row: 10, column: 10 },
|
|
64
|
-
well: well1,
|
|
65
|
-
brand: exampleLabware1.brand,
|
|
66
|
-
namespace: 'fixture',
|
|
67
|
-
})
|
|
68
|
-
labware2Args = {
|
|
69
|
-
metadata: exampleLabware2.metadata,
|
|
70
|
-
parameters: exampleLabware2.parameters,
|
|
71
|
-
dimensions: exampleLabware2.dimensions,
|
|
72
|
-
offset: offset2,
|
|
73
|
-
grid: {
|
|
74
|
-
row: 3,
|
|
75
|
-
column: 2,
|
|
76
|
-
},
|
|
77
|
-
spacing: {
|
|
78
|
-
row: 10,
|
|
79
|
-
column: 10,
|
|
80
|
-
},
|
|
81
|
-
well: well2,
|
|
82
|
-
namespace: 'fixture',
|
|
83
|
-
}
|
|
84
|
-
labware2 = createRegularLabware(labware2Args)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
it('snapshot tests', () => {
|
|
88
|
-
expect(labware1).toEqual(exampleLabware1)
|
|
89
|
-
expect(labware2).toEqual(exampleLabware2)
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it('ordering generates as expected', () => {
|
|
93
|
-
expect(exampleLabware2.ordering).toEqual(labware2.ordering)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it('well XYZ generates correctly', () => {
|
|
97
|
-
const spacing = { row: 10, column: 10 }
|
|
98
|
-
const grid = { row: 3, column: 2 }
|
|
99
|
-
const { yDimension } = exampleLabware2.dimensions
|
|
100
|
-
|
|
101
|
-
const labware3 = createRegularLabware({
|
|
102
|
-
metadata: exampleLabware2.metadata,
|
|
103
|
-
parameters: exampleLabware2.parameters,
|
|
104
|
-
dimensions: exampleLabware2.dimensions,
|
|
105
|
-
offset: offset2,
|
|
106
|
-
grid,
|
|
107
|
-
spacing,
|
|
108
|
-
well: well2,
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
const expectedXByCol = range(
|
|
112
|
-
offset2.x,
|
|
113
|
-
offset2.x + grid.column * spacing.column,
|
|
114
|
-
spacing.column
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
const expectedYByRow = range(
|
|
118
|
-
yDimension - offset2.y,
|
|
119
|
-
yDimension - offset2.y - spacing.row * grid.row,
|
|
120
|
-
-spacing.row
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
labware3.ordering.forEach((column, cIndex) => {
|
|
124
|
-
column.forEach((wellName, rIndex) => {
|
|
125
|
-
const well = labware3.wells[wellName]
|
|
126
|
-
|
|
127
|
-
expect(well.x).toBeCloseTo(expectedXByCol[cIndex], 2)
|
|
128
|
-
expect(well.y).toBeCloseTo(expectedYByRow[rIndex], 2)
|
|
129
|
-
expect(well.z).toBeCloseTo(offset2.z - well.depth, 2)
|
|
130
|
-
})
|
|
131
|
-
})
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
it('failing to validate against labware schema throws w/o "strict"', () => {
|
|
135
|
-
const args = {
|
|
136
|
-
...labware2Args,
|
|
137
|
-
// this spacing should make negative well `y` value and fail schema validation
|
|
138
|
-
spacing: {
|
|
139
|
-
row: 999,
|
|
140
|
-
column: 999,
|
|
141
|
-
},
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
expect(() => createRegularLabware(args)).toThrowErrorMatchingSnapshot()
|
|
145
|
-
expect(() => createRegularLabware({ ...args, strict: false })).not.toThrow()
|
|
146
|
-
})
|
|
147
|
-
})
|