@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.
Files changed (154) hide show
  1. package/Makefile +1 -1
  2. package/lib/opentrons-shared-data.js +1 -1
  3. package/lib/opentrons-shared-data.js.map +1 -1
  4. package/package.json +1 -1
  5. package/js/__tests__/__snapshots__/pipettes.test.ts.snap +0 -5969
  6. package/js/__tests__/deckSchemas.test.ts +0 -87
  7. package/js/__tests__/errors.test.js +0 -21
  8. package/js/__tests__/getAreSlotsAdjacent.test.ts +0 -128
  9. package/js/__tests__/getWellNamePerMultiTip.test.ts +0 -162
  10. package/js/__tests__/labwareDefQuirks.test.ts +0 -37
  11. package/js/__tests__/labwareDefSchemaV1.test.ts +0 -82
  12. package/js/__tests__/labwareDefSchemaV2.test.ts +0 -298
  13. package/js/__tests__/moduleAccessors.test.ts +0 -50
  14. package/js/__tests__/moduleSpecsSchema.test.ts +0 -77
  15. package/js/__tests__/pipetteSchemaV2.test.ts +0 -107
  16. package/js/__tests__/pipetteSpecSchemas.test.ts +0 -48
  17. package/js/__tests__/pipettes.test.ts +0 -58
  18. package/js/__tests__/protocolSchemaV4.test.ts +0 -137
  19. package/js/__tests__/protocolSchemaV5.test.ts +0 -137
  20. package/js/__tests__/protocolSchemaV6.test.ts +0 -132
  21. package/js/__tests__/protocolSchemaV7.test.ts +0 -64
  22. package/js/__tests__/protocolValidation.test.ts +0 -83
  23. package/js/__tests__/sortWells.test.ts +0 -40
  24. package/js/__tests__/splitWellsOnColumn.test.ts +0 -21
  25. package/js/__tests__/validateErrors.test.js +0 -34
  26. package/js/constants.ts +0 -338
  27. package/js/cypressUtils.ts +0 -35
  28. package/js/errors.ts +0 -33
  29. package/js/fixtures.ts +0 -161
  30. package/js/getLabware.ts +0 -154
  31. package/js/gripper.ts +0 -29
  32. package/js/helpers/__tests__/getAdapterName.test.ts +0 -31
  33. package/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.ts +0 -12
  34. package/js/helpers/__tests__/getVectorDifference.test.ts +0 -25
  35. package/js/helpers/__tests__/getVectorSum.test.ts +0 -21
  36. package/js/helpers/__tests__/labwareInference.test.ts +0 -84
  37. package/js/helpers/__tests__/orderWells.test.ts +0 -87
  38. package/js/helpers/__tests__/parseProtocolData.test.ts +0 -165
  39. package/js/helpers/__tests__/volume.test.ts +0 -108
  40. package/js/helpers/__tests__/wellSets.test.ts +0 -352
  41. package/js/helpers/get96Channel384WellPlateWells.ts +0 -44
  42. package/js/helpers/getAddressableAreasInProtocol.ts +0 -59
  43. package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +0 -30
  44. package/js/helpers/getModuleVizDims.ts +0 -118
  45. package/js/helpers/getOccludedSlotCountForModule.ts +0 -13
  46. package/js/helpers/getVectorDifference.ts +0 -12
  47. package/js/helpers/getVectorSum.ts +0 -12
  48. package/js/helpers/getWellNamePerMultiTip.ts +0 -86
  49. package/js/helpers/getWellTotalVolume.ts +0 -16
  50. package/js/helpers/index.ts +0 -347
  51. package/js/helpers/labwareInference.ts +0 -92
  52. package/js/helpers/orderWells.ts +0 -69
  53. package/js/helpers/parseProtocolData.ts +0 -141
  54. package/js/helpers/volume.ts +0 -35
  55. package/js/helpers/wellIsRect.ts +0 -6
  56. package/js/helpers/wellSets.ts +0 -155
  57. package/js/index.ts +0 -14
  58. package/js/labwareTools/__tests__/__snapshots__/createIrregularLabware.test.ts.snap +0 -3
  59. package/js/labwareTools/__tests__/__snapshots__/createLabware.test.ts.snap +0 -3
  60. package/js/labwareTools/__tests__/createDefaultDisplayName.test.ts +0 -111
  61. package/js/labwareTools/__tests__/createIrregularLabware.test.ts +0 -226
  62. package/js/labwareTools/__tests__/createLabware.test.ts +0 -147
  63. package/js/labwareTools/index.ts +0 -452
  64. package/js/modules.ts +0 -97
  65. package/js/pipettes.ts +0 -89
  66. package/js/protocols.ts +0 -290
  67. package/js/schema.ts +0 -80
  68. package/js/scripts/generateDeckLayersFromSVG.js +0 -46
  69. package/js/titleCase.ts +0 -30
  70. package/js/types.ts +0 -600
  71. package/python/.coveragerc +0 -4
  72. package/python/.flake8 +0 -32
  73. package/python/Config.in +0 -10
  74. package/python/Makefile +0 -134
  75. package/python/Pipfile +0 -28
  76. package/python/Pipfile.lock +0 -645
  77. package/python/buildroot.mk +0 -30
  78. package/python/mypy.ini +0 -41
  79. package/python/opentrons_shared_data/__init__.py +0 -17
  80. package/python/opentrons_shared_data/_version.py +0 -20
  81. package/python/opentrons_shared_data/command/__init__.py +0 -52
  82. package/python/opentrons_shared_data/deck/__init__.py +0 -96
  83. package/python/opentrons_shared_data/deck/dev_types.py +0 -180
  84. package/python/opentrons_shared_data/errors/__init__.py +0 -30
  85. package/python/opentrons_shared_data/errors/categories.py +0 -60
  86. package/python/opentrons_shared_data/errors/codes.py +0 -108
  87. package/python/opentrons_shared_data/errors/exceptions.py +0 -915
  88. package/python/opentrons_shared_data/gripper/__init__.py +0 -63
  89. package/python/opentrons_shared_data/gripper/constants.py +0 -6
  90. package/python/opentrons_shared_data/gripper/gripper_definition.py +0 -101
  91. package/python/opentrons_shared_data/labware/__init__.py +0 -22
  92. package/python/opentrons_shared_data/labware/constants.py +0 -7
  93. package/python/opentrons_shared_data/labware/dev_types.py +0 -140
  94. package/python/opentrons_shared_data/labware/labware_definition.py +0 -328
  95. package/python/opentrons_shared_data/load.py +0 -57
  96. package/python/opentrons_shared_data/module/__init__.py +0 -74
  97. package/python/opentrons_shared_data/module/dev_types.py +0 -141
  98. package/python/opentrons_shared_data/pipette/__init__.py +0 -107
  99. package/python/opentrons_shared_data/pipette/dev_types.py +0 -177
  100. package/python/opentrons_shared_data/pipette/file_operation_helpers.py +0 -37
  101. package/python/opentrons_shared_data/pipette/load_data.py +0 -261
  102. package/python/opentrons_shared_data/pipette/model_constants.py +0 -123
  103. package/python/opentrons_shared_data/pipette/mutable_configurations.py +0 -431
  104. package/python/opentrons_shared_data/pipette/pipette_definition.py +0 -503
  105. package/python/opentrons_shared_data/pipette/pipette_load_name_conversions.py +0 -240
  106. package/python/opentrons_shared_data/pipette/scripts/__init__.py +0 -0
  107. package/python/opentrons_shared_data/pipette/scripts/build_json_script.py +0 -469
  108. package/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py +0 -450
  109. package/python/opentrons_shared_data/pipette/types.py +0 -193
  110. package/python/opentrons_shared_data/protocol/__init__.py +0 -13
  111. package/python/opentrons_shared_data/protocol/constants.py +0 -98
  112. package/python/opentrons_shared_data/protocol/dev_types.py +0 -436
  113. package/python/opentrons_shared_data/protocol/models/__init__.py +0 -48
  114. package/python/opentrons_shared_data/protocol/models/protocol_schema_v6.py +0 -145
  115. package/python/opentrons_shared_data/protocol/models/protocol_schema_v7.py +0 -95
  116. package/python/opentrons_shared_data/protocol/models/protocol_schema_v8.py +0 -110
  117. package/python/opentrons_shared_data/protocol/models/shared_models.py +0 -111
  118. package/python/opentrons_shared_data/py.typed +0 -0
  119. package/python/opentrons_shared_data/robot/__init__.py +0 -33
  120. package/python/opentrons_shared_data/robot/dev_types.py +0 -37
  121. package/python/pytest.ini +0 -2
  122. package/python/setup.cfg +0 -5
  123. package/python/setup.py +0 -179
  124. package/python/tests/__init__.py +0 -1
  125. package/python/tests/conftest.py +0 -0
  126. package/python/tests/deck/__init__.py +0 -0
  127. package/python/tests/deck/test_list_names.py +0 -12
  128. package/python/tests/deck/test_position.py +0 -113
  129. package/python/tests/deck/test_typechecks.py +0 -28
  130. package/python/tests/errors/__init__.py +0 -1
  131. package/python/tests/errors/test_error_completeness.py +0 -19
  132. package/python/tests/errors/test_exceptions.py +0 -74
  133. package/python/tests/gripper/__init__.py +0 -0
  134. package/python/tests/gripper/test_definition.py +0 -30
  135. package/python/tests/gripper/test_load.py +0 -16
  136. package/python/tests/labware/__init__.py +0 -13
  137. package/python/tests/labware/test_typechecks.py +0 -21
  138. package/python/tests/module/__init__.py +0 -20
  139. package/python/tests/module/test_load.py +0 -49
  140. package/python/tests/module/test_typechecks.py +0 -34
  141. package/python/tests/pipette/__init__.py +0 -0
  142. package/python/tests/pipette/test_load_data.py +0 -103
  143. package/python/tests/pipette/test_mutable_configurations.py +0 -266
  144. package/python/tests/pipette/test_pipette_definition.py +0 -183
  145. package/python/tests/pipette/test_pipette_load_name_conversions.py +0 -222
  146. package/python/tests/pipette/test_typechecks.py +0 -50
  147. package/python/tests/pipette/test_validate_schema.py +0 -37
  148. package/python/tests/protocol/__init__.py +0 -15
  149. package/python/tests/protocol/test_protocol_schema_v6.py +0 -107
  150. package/python/tests/protocol/test_protocol_schema_v7.py +0 -34
  151. package/python/tests/protocol/test_protocol_schema_v8.py +0 -20
  152. package/python/tests/protocol/test_typechecks.py +0 -36
  153. package/python/tests/robot/__init__.py +0 -0
  154. package/python/tests/robot/test_typechecks.py +0 -20
@@ -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
- })
@@ -1,452 +0,0 @@
1
- import Ajv from 'ajv'
2
- import flatten from 'lodash/flatten'
3
- import range from 'lodash/range'
4
- import round from 'lodash/round'
5
-
6
- import labwareSchema from '../../labware/schemas/2.json'
7
-
8
- import {
9
- toWellName,
10
- sortWells,
11
- splitWellsOnColumn,
12
- getDisplayVolume,
13
- getAsciiVolumeUnits,
14
- ensureVolumeUnits,
15
- } from '../helpers/index'
16
-
17
- import type {
18
- LabwareDefinition2 as Definition,
19
- LabwareMetadata as Metadata,
20
- LabwareDimensions as Dimensions,
21
- LabwareBrand as Brand,
22
- LabwareParameters as Params,
23
- LabwareWell as Well,
24
- LabwareWellProperties as InputWell,
25
- LabwareWellMap as WellMap,
26
- LabwareWellGroup as WellGroup,
27
- LabwareOffset as Offset,
28
- LabwareVolumeUnits as VolumeUnits,
29
- } from '../types'
30
-
31
- // NOTE: leaving this 'beta' to reduce conflicts with future labware cloud namespaces
32
- export const DEFAULT_CUSTOM_NAMESPACE = 'custom_beta'
33
-
34
- const SCHEMA_VERSION = 2
35
- const DEFAULT_BRAND_NAME = 'generic'
36
-
37
- interface Cell {
38
- row: number
39
- column: number
40
- }
41
-
42
- // This represents creating a "range" of well names with step intervals included
43
- // For example, starting at well "A1" with a column stride of 2 would result in
44
- // the grid name being ordered as: "A1", "B1"..."A3", "B3"..etc
45
- interface GridStart {
46
- rowStart: string
47
- colStart: string
48
- rowStride: number
49
- colStride: number
50
- }
51
-
52
- type InputParams = Omit<Params, 'loadName'>
53
-
54
- type InputWellGroup = Omit<WellGroup, 'wells'>
55
-
56
- export interface BaseLabwareProps {
57
- metadata: Metadata
58
- parameters: InputParams
59
- dimensions: Dimensions
60
- brand?: Brand
61
- version?: number
62
- namespace?: string
63
- loadNamePostfix?: string[]
64
- strict?: boolean | null // If true, throws error on failed validation
65
- }
66
-
67
- export interface RegularLabwareProps extends BaseLabwareProps {
68
- offset: Offset
69
- grid: Cell
70
- spacing: Cell
71
- well: InputWell
72
- group?: InputWellGroup
73
- }
74
-
75
- export interface IrregularLabwareProps extends BaseLabwareProps {
76
- offset: Offset[]
77
- grid: Cell[]
78
- spacing: Cell[]
79
- well: InputWell[]
80
- gridStart: GridStart[]
81
- group?: InputWellGroup[]
82
- }
83
-
84
- const ajv = new Ajv({ allErrors: true, jsonPointers: true })
85
- const validate = ajv.compile(labwareSchema)
86
-
87
- function validateDefinition(
88
- definition: Definition,
89
- strict: boolean | null | undefined = true
90
- ): Definition {
91
- const valid = validate(definition)
92
-
93
- if (!valid) {
94
- console.error('Definition:', definition)
95
- console.error('Validation Errors:', validate.errors)
96
-
97
- if (strict) {
98
- throw new Error(
99
- 'Generated labware failed to validate, please check your inputs'
100
- )
101
- }
102
- }
103
-
104
- return definition
105
- }
106
-
107
- export function _irregularWellName(
108
- rowIdx: number,
109
- colIdx: number,
110
- gridStart: GridStart
111
- ): string {
112
- const rowNum =
113
- rowIdx * gridStart.rowStride + gridStart.rowStart.charCodeAt(0) - 65
114
- const colNum = colIdx * gridStart.colStride + parseInt(gridStart.colStart) - 1
115
- return toWellName({
116
- rowNum,
117
- colNum,
118
- })
119
- }
120
-
121
- export function _calculateWellCoord(
122
- rowIdx: number,
123
- colIdx: number,
124
- spacing: Cell,
125
- offset: Offset,
126
- well: InputWell
127
- ): Well {
128
- const coords = {
129
- x: round(colIdx * spacing.column + offset.x, 2),
130
- y: round(rowIdx * spacing.row + offset.y, 2),
131
- z: round(offset.z - well.depth, 2),
132
- }
133
- // NOTE: Ian 2019-04-16 this silly "if circular" is to make Flow happy
134
- if (well.shape === 'circular') return { ...well, ...coords }
135
- return { ...well, ...coords }
136
- }
137
-
138
- interface Layout {
139
- wells: WellMap
140
- groups: WellGroup[]
141
- }
142
-
143
- function determineIrregularLayout(
144
- grids: Cell[],
145
- spacing: Cell[],
146
- offset: Offset[],
147
- gridStart: GridStart[],
148
- wells: InputWell[],
149
- group: InputWellGroup[] = []
150
- ): Layout {
151
- return grids.reduce<Layout>(
152
- (result, gridObj, gridIdx) => {
153
- const reverseRowIdx = range(gridObj.row - 1, -1)
154
- const inputGroup = group[gridIdx] || {
155
- metadata: {},
156
- }
157
- const currentGroup: WellGroup = { ...inputGroup, wells: [] }
158
-
159
- range(gridObj.column).forEach(colIdx => {
160
- range(gridObj.row).forEach(rowIdx => {
161
- const wellName = _irregularWellName(
162
- rowIdx,
163
- colIdx,
164
- gridStart[gridIdx]
165
- )
166
-
167
- currentGroup.wells.push(wellName)
168
- result.wells[wellName] = _calculateWellCoord(
169
- reverseRowIdx[rowIdx],
170
- colIdx,
171
- spacing[gridIdx],
172
- offset[gridIdx],
173
- wells[gridIdx]
174
- )
175
- })
176
- })
177
- return {
178
- wells: result.wells,
179
- groups: [...result.groups, currentGroup],
180
- }
181
- },
182
- {
183
- wells: {},
184
- groups: [],
185
- }
186
- )
187
- }
188
-
189
- export function _generateIrregularLoadName(args: {
190
- grid: Cell[]
191
- well: InputWell[]
192
- totalWellCount: number
193
- units: VolumeUnits
194
- brand: string
195
- displayCategory: string
196
- loadNamePostfix?: string[]
197
- }): string {
198
- const {
199
- grid,
200
- well,
201
- totalWellCount,
202
- units,
203
- brand,
204
- displayCategory,
205
- loadNamePostfix = [],
206
- } = args
207
- const loadNameUnits = getAsciiVolumeUnits(units)
208
- const wellComboArray = grid.map((gridObj, gridIdx) => {
209
- const numWells = gridObj.row * gridObj.column
210
- const wellVolume = getDisplayVolume(well[gridIdx].totalLiquidVolume, units)
211
- return `${numWells}x${wellVolume}${loadNameUnits}`
212
- })
213
- return joinLoadName([
214
- brand,
215
- totalWellCount,
216
- displayCategory,
217
- wellComboArray,
218
- ...loadNamePostfix,
219
- ])
220
- }
221
-
222
- // Decide order of wells for single grid containers
223
- function determineOrdering(grid: Cell): string[][] {
224
- const ordering = range(grid.column).map(colNum =>
225
- range(grid.row).map(rowNum =>
226
- toWellName({
227
- rowNum,
228
- colNum,
229
- })
230
- )
231
- )
232
- return ordering
233
- }
234
-
235
- // Decide order of wells for multi-grid containers
236
- export function determineIrregularOrdering(wellsArray: string[]): string[][] {
237
- const sortedArray = wellsArray.sort(sortWells)
238
- const ordering = splitWellsOnColumn(sortedArray)
239
- return ordering
240
- }
241
-
242
- // Private helper functions to calculate the XYZ coordinates of a give well
243
- // Will return a nested object of all well objects for a labware
244
- function calculateCoordinates(
245
- wellProps: InputWell,
246
- ordering: string[][],
247
- spacing: Cell,
248
- offset: Offset,
249
- dimensions: Dimensions
250
- ): WellMap {
251
- const { yDimension } = dimensions
252
- return ordering.reduce<WellMap>((wellMap, column, cIndex) => {
253
- return column.reduce<WellMap>(
254
- (colWellMap, wellName, rIndex) => ({
255
- ...colWellMap,
256
- [wellName]: {
257
- ...wellProps,
258
- x: round(cIndex * spacing.column + offset.x, 2),
259
- y: round(yDimension - offset.y - rIndex * spacing.row, 2),
260
- z: round(offset.z - wellProps.depth, 2),
261
- },
262
- }),
263
- wellMap
264
- )
265
- }, {})
266
- }
267
-
268
- function ensureBrand(brand?: Brand): Brand {
269
- return (
270
- brand || {
271
- brand: DEFAULT_BRAND_NAME,
272
- }
273
- )
274
- }
275
-
276
- // joins the input array with _ to create a name, making sure to lowercase the
277
- // result and remove all invalid characters (allowed characters: [a-z0-9_.])
278
- function joinLoadName(
279
- fragments: Array<string | number | Array<string | number>>
280
- ): string {
281
- return flatten(fragments)
282
- .map(s => String(s).replace(/_/g, ''))
283
- .join('_')
284
- .toLowerCase()
285
- .replace(/[^a-z0-9_.]/g, '')
286
- }
287
-
288
- export interface RegularNameProps {
289
- displayCategory: string
290
- displayVolumeUnits: VolumeUnits
291
- gridRows: number
292
- gridColumns: number
293
- totalLiquidVolume: number
294
- brandName?: string
295
- loadNamePostfix?: string[]
296
- }
297
-
298
- export function createRegularLoadName(args: RegularNameProps): string {
299
- const {
300
- gridRows,
301
- gridColumns,
302
- displayCategory,
303
- totalLiquidVolume,
304
- displayVolumeUnits,
305
- brandName = DEFAULT_BRAND_NAME,
306
- loadNamePostfix = [],
307
- } = args
308
- const numWells = gridRows * gridColumns
309
- return joinLoadName([
310
- brandName,
311
- numWells,
312
- displayCategory,
313
- `${getDisplayVolume(
314
- totalLiquidVolume,
315
- displayVolumeUnits
316
- )}${getAsciiVolumeUnits(displayVolumeUnits)}`,
317
- ...loadNamePostfix,
318
- ])
319
- }
320
-
321
- const capitalize = (_s: string): string => {
322
- const s = _s.trim()
323
-
324
- return `${s.slice(0, 1).toUpperCase()}${s.slice(1)}`
325
- }
326
-
327
- // TODO: Ian 2019-08-23 consider using this in the labware creation functions instead of manually entering displayName
328
- export function createDefaultDisplayName(args: RegularNameProps): string {
329
- const {
330
- gridRows,
331
- gridColumns,
332
- displayCategory,
333
- totalLiquidVolume,
334
- displayVolumeUnits,
335
- brandName = DEFAULT_BRAND_NAME,
336
- loadNamePostfix = [],
337
- } = args
338
- const numWells = gridRows * gridColumns
339
- return [
340
- ...brandName.split(' ').map(capitalize),
341
- numWells,
342
- capitalize(displayCategory.replace(/([a-z])([A-Z])/g, '$1 $2')),
343
- getDisplayVolume(totalLiquidVolume, displayVolumeUnits),
344
- displayVolumeUnits,
345
- ...loadNamePostfix.map(capitalize),
346
- ]
347
- .filter(s => s !== '')
348
- .join(' ')
349
- .replace(/\s+/g, ' ')
350
- .trim()
351
- }
352
- // Generator function for labware definitions within a regular grid format
353
- // e.g. well plates, regular tuberacks (NOT 15_50ml) etc.
354
- // For further info on these parameters look at labware examples in __tests__
355
- // or the labware definition schema in labware/schemas/
356
- export function createRegularLabware(args: RegularLabwareProps): Definition {
357
- const { offset, dimensions, grid, spacing, well, loadNamePostfix } = args
358
- const strict = args.strict
359
- const version = args.version || 1
360
- const namespace = args.namespace || DEFAULT_CUSTOM_NAMESPACE
361
- const ordering = determineOrdering(grid)
362
- const brand = ensureBrand(args.brand)
363
- const groupBase = args.group || {
364
- metadata: {},
365
- }
366
- const metadata = {
367
- ...args.metadata,
368
- displayVolumeUnits: ensureVolumeUnits(args.metadata.displayVolumeUnits),
369
- }
370
- const loadName = createRegularLoadName({
371
- gridColumns: grid.column,
372
- gridRows: grid.row,
373
- displayCategory: metadata.displayCategory,
374
- displayVolumeUnits: metadata.displayVolumeUnits,
375
- totalLiquidVolume: well.totalLiquidVolume,
376
- brandName: brand.brand,
377
- loadNamePostfix,
378
- })
379
- return validateDefinition(
380
- {
381
- ordering,
382
- brand,
383
- metadata,
384
- dimensions,
385
- wells: calculateCoordinates(well, ordering, spacing, offset, dimensions),
386
- groups: [{ ...groupBase, wells: flatten(ordering) }],
387
- parameters: { ...args.parameters, loadName },
388
- namespace,
389
- version,
390
- schemaVersion: SCHEMA_VERSION,
391
- cornerOffsetFromSlot: {
392
- x: 0,
393
- y: 0,
394
- z: 0,
395
- },
396
- },
397
- strict
398
- )
399
- }
400
- // Generator function for labware definitions within an irregular grid format
401
- // e.g. crystallization plates, 15_50ml tuberacks and anything with multiple "grids"
402
- export function createIrregularLabware(
403
- args: IrregularLabwareProps
404
- ): Definition {
405
- const { offset, dimensions, grid, spacing, well, gridStart, group } = args
406
- const strict = args.strict
407
- const namespace = args.namespace || DEFAULT_CUSTOM_NAMESPACE
408
- const version = args.version || 1
409
- const { wells, groups } = determineIrregularLayout(
410
- grid,
411
- spacing,
412
- offset,
413
- gridStart,
414
- well,
415
- group
416
- )
417
- const brand = ensureBrand(args.brand)
418
- const metadata = {
419
- ...args.metadata,
420
- displayVolumeUnits: ensureVolumeUnits(args.metadata.displayVolumeUnits),
421
- }
422
-
423
- const loadName = _generateIrregularLoadName({
424
- grid,
425
- well,
426
- totalWellCount: Object.keys(wells).length,
427
- units: metadata.displayVolumeUnits,
428
- displayCategory: metadata.displayCategory,
429
- brand: brand.brand,
430
- })
431
-
432
- return validateDefinition(
433
- {
434
- wells,
435
- groups,
436
- brand,
437
- metadata,
438
- dimensions,
439
- parameters: { ...args.parameters, loadName, format: 'irregular' },
440
- ordering: determineIrregularOrdering(Object.keys(wells)),
441
- namespace,
442
- version,
443
- schemaVersion: SCHEMA_VERSION,
444
- cornerOffsetFromSlot: {
445
- x: 0,
446
- y: 0,
447
- z: 0,
448
- },
449
- },
450
- strict
451
- )
452
- }
package/js/modules.ts DELETED
@@ -1,97 +0,0 @@
1
- import magneticModuleV1 from '../module/definitions/3/magneticModuleV1.json'
2
- import magneticModuleV2 from '../module/definitions/3/magneticModuleV2.json'
3
- import temperatureModuleV1 from '../module/definitions/3/temperatureModuleV1.json'
4
- import temperatureModuleV2 from '../module/definitions/3/temperatureModuleV2.json'
5
- import thermocyclerModuleV1 from '../module/definitions/3/thermocyclerModuleV1.json'
6
- import thermocyclerModuleV2 from '../module/definitions/3/thermocyclerModuleV2.json'
7
- import heaterShakerModuleV1 from '../module/definitions/3/heaterShakerModuleV1.json'
8
- import magneticBlockV1 from '../module/definitions/3/magneticBlockV1.json'
9
-
10
- import {
11
- MAGDECK,
12
- MAGNETIC_MODULE_V1,
13
- MAGNETIC_MODULE_V2,
14
- TEMPDECK,
15
- TEMPERATURE_MODULE_V1,
16
- TEMPERATURE_MODULE_V2,
17
- THERMOCYCLER,
18
- THERMOCYCLER_MODULE_V1,
19
- THERMOCYCLER_MODULE_V2,
20
- HEATERSHAKER_MODULE_V1,
21
- MAGNETIC_BLOCK_V1,
22
- } from './constants'
23
-
24
- import type {
25
- ModuleModel,
26
- ModuleModelWithLegacy,
27
- ModuleType,
28
- ModuleDefinition,
29
- } from './types'
30
-
31
- // TODO(bc, 2021-09-18): generate typescript types directly from JSON schema
32
- // having to maintain TS types side by side with the schema is a liability
33
- export const getModuleDef2 = (moduleModel: ModuleModel): ModuleDefinition => {
34
- switch (moduleModel) {
35
- case MAGNETIC_MODULE_V1:
36
- return magneticModuleV1 as ModuleDefinition
37
-
38
- case MAGNETIC_MODULE_V2:
39
- return (magneticModuleV2 as unknown) as ModuleDefinition
40
-
41
- case TEMPERATURE_MODULE_V1:
42
- return temperatureModuleV1 as ModuleDefinition
43
-
44
- case TEMPERATURE_MODULE_V2:
45
- return (temperatureModuleV2 as unknown) as ModuleDefinition
46
-
47
- case THERMOCYCLER_MODULE_V1:
48
- return thermocyclerModuleV1 as ModuleDefinition
49
-
50
- case THERMOCYCLER_MODULE_V2:
51
- return (thermocyclerModuleV2 as unknown) as ModuleDefinition
52
-
53
- case HEATERSHAKER_MODULE_V1:
54
- return (heaterShakerModuleV1 as unknown) as ModuleDefinition
55
-
56
- case MAGNETIC_BLOCK_V1:
57
- return (magneticBlockV1 as unknown) as ModuleDefinition
58
-
59
- default:
60
- throw new Error(`Invalid module model ${moduleModel as string}`)
61
- }
62
- }
63
-
64
- export function normalizeModuleModel(
65
- legacyModule: ModuleModelWithLegacy
66
- ): ModuleModel {
67
- switch (legacyModule) {
68
- case TEMPDECK:
69
- return TEMPERATURE_MODULE_V1
70
-
71
- case MAGDECK:
72
- return MAGNETIC_MODULE_V1
73
-
74
- case THERMOCYCLER:
75
- return THERMOCYCLER_MODULE_V1
76
-
77
- default:
78
- throw new Error(`Invalid legacy module model ${legacyModule as string}`)
79
- }
80
- }
81
-
82
- export function getModuleType(moduleModel: ModuleModel): ModuleType {
83
- return getModuleDef2(moduleModel).moduleType
84
- }
85
-
86
- // use module model (not type!) to get model-specific displayName for UI
87
- export function getModuleDisplayName(moduleModel: ModuleModel): string {
88
- return getModuleDef2(moduleModel).displayName
89
- }
90
-
91
- export function checkModuleCompatibility(
92
- modelA: ModuleModel,
93
- modelB: ModuleModel
94
- ): boolean {
95
- const bDef = getModuleDef2(modelB)
96
- return modelA === modelB || bDef.compatibleWith.includes(modelA)
97
- }