@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,503 +0,0 @@
1
- import re
2
- from typing import List, Dict, Tuple, Optional
3
- from pydantic import BaseModel, Field, validator
4
- from typing_extensions import Literal
5
- from dataclasses import dataclass
6
-
7
- from . import types as pip_types, dev_types
8
-
9
- PLUNGER_CURRENT_MINIMUM = 0.1
10
- PLUNGER_CURRENT_MAXIMUM = 1.5
11
-
12
- NOZZLE_MAP_NAMES = re.compile(r"(?P<row>[A-Z]+)(?P<column>[0-9]+)")
13
- COLUMN_NAMES = re.compile(r"[0-9]+")
14
- ROW_NAMES = re.compile(r"[A-Z]+")
15
-
16
-
17
- # TODO (lc 12-5-2022) Ideally we can deprecate this
18
- # at somepoint once we load pipettes by channels and type
19
- @dataclass
20
- class PipetteNameType:
21
- pipette_type: pip_types.PipetteModelType
22
- pipette_channels: pip_types.PipetteChannelType
23
- pipette_generation: pip_types.PipetteGenerationType
24
-
25
- def __repr__(self) -> str:
26
- base_name = f"{self.pipette_type.name}_{str(self.pipette_channels)}"
27
- if self.pipette_generation == pip_types.PipetteGenerationType.GEN1:
28
- return base_name
29
- elif self.pipette_channels == pip_types.PipetteChannelType.NINETY_SIX_CHANNEL:
30
- return base_name
31
- else:
32
- return f"{base_name}_{self.pipette_generation.name.lower()}"
33
-
34
- def get_version(self) -> pip_types.PipetteVersionType:
35
- if self.pipette_generation == pip_types.PipetteGenerationType.FLEX:
36
- return pip_types.PipetteVersionType(3, 0)
37
- elif self.pipette_generation == pip_types.PipetteGenerationType.GEN2:
38
- return pip_types.PipetteVersionType(2, 0)
39
- else:
40
- return pip_types.PipetteVersionType(1, 0)
41
-
42
-
43
- @dataclass
44
- class PipetteModelVersionType:
45
- pipette_type: pip_types.PipetteModelType
46
- pipette_channels: pip_types.PipetteChannelType
47
- pipette_version: pip_types.PipetteVersionType
48
-
49
- def __repr__(self) -> str:
50
- base_name = f"{self.pipette_type.name}_{str(self.pipette_channels)}"
51
-
52
- return f"{base_name}_v{self.pipette_version}"
53
-
54
-
55
- class FlowRateDefinition(BaseModel):
56
- default: float = Field(..., description="Highest API level default fallback.")
57
- values_by_api_level: Dict[str, float] = Field(
58
- ..., description="flow rates keyed by API level.", alias="valuesByApiLevel"
59
- )
60
-
61
-
62
- PipetteFunctionKeyType = Literal["1", "2", "3"]
63
- ulPerMMType = Dict[PipetteFunctionKeyType, List[Tuple[float, float, float]]]
64
-
65
-
66
- class ulPerMMDefinition(BaseModel):
67
- default: ulPerMMType
68
-
69
-
70
- class SupportedTipsDefinition(BaseModel):
71
- """Tip parameters available for every tip size."""
72
-
73
- default_aspirate_flowrate: FlowRateDefinition = Field(
74
- ...,
75
- description="The flowrate used in aspirations by default.",
76
- alias="defaultAspirateFlowRate",
77
- )
78
- default_dispense_flowrate: FlowRateDefinition = Field(
79
- ...,
80
- description="The flowrate used in dispenses by default.",
81
- alias="defaultDispenseFlowRate",
82
- )
83
- default_blowout_flowrate: FlowRateDefinition = Field(
84
- ...,
85
- description="The flowrate used in blowouts by default.",
86
- alias="defaultBlowOutFlowRate",
87
- )
88
- default_flow_acceleration: float = Field(
89
- float("inf"), # no default works for all pipettes
90
- description="The acceleration used during aspirate/dispense/blowout in ul/s^2.",
91
- alias="defaultFlowAcceleration",
92
- )
93
- default_tip_length: float = Field(
94
- ...,
95
- description="The default tip length associated with this tip type.",
96
- alias="defaultTipLength",
97
- )
98
- default_return_tip_height: float = Field(
99
- default=0.5,
100
- description="The height to return a tip to its tiprack.",
101
- alias="defaultReturnTipHeight",
102
- )
103
- aspirate: ulPerMMDefinition = Field(
104
- ..., description="The default pipetting functions list for aspirate."
105
- )
106
- dispense: ulPerMMDefinition = Field(
107
- ..., description="The default pipetting functions list for dispensing."
108
- )
109
- default_push_out_volume: float = Field(
110
- ...,
111
- description="The default volume for a push-out during dispense.",
112
- alias="defaultPushOutVolume",
113
- )
114
-
115
-
116
- class MotorConfigurations(BaseModel):
117
- idle: float = Field(
118
- ..., description="The plunger motor current to use during idle states."
119
- )
120
- run: float = Field(
121
- ..., description="The plunger motor current to use during active states."
122
- )
123
-
124
-
125
- class PlungerPositions(BaseModel):
126
- top: float = Field(
127
- ...,
128
- description="The plunger position that describes max available volume of a pipette in mm.",
129
- )
130
- bottom: float = Field(
131
- ...,
132
- description="The plunger position that describes min available volume of a pipette in mm.",
133
- )
134
- blow_out: float = Field(
135
- ...,
136
- description="The plunger position past 0 volume to blow out liquid.",
137
- alias="blowout",
138
- )
139
- drop_tip: float = Field(
140
- ..., description="The plunger position used to drop tips.", alias="drop"
141
- )
142
-
143
-
144
- class PlungerHomingConfigurations(BaseModel):
145
- current: float = Field(
146
- default=0.0,
147
- description="The current to move the plunger axis for homing.",
148
- )
149
- speed: float = Field(
150
- ...,
151
- description="The speed to move the plunger axis for homing.",
152
- )
153
-
154
-
155
- class PressFitPickUpTipConfiguration(BaseModel):
156
- presses: int = Field(
157
- ...,
158
- description="The number of times to force pickup (incrementally more each time by increment)",
159
- )
160
- increment: float = Field(
161
- ...,
162
- description="The increment to move the pipette down on each force tip pickup press",
163
- )
164
- distance: float = Field(
165
- ..., description="The starting distance to begin a pick up tip from"
166
- )
167
- speed: float = Field(
168
- ..., description="The speed to move the Z axis for each force pickup"
169
- )
170
- current_by_tip_count: Dict[int, float] = Field(
171
- ...,
172
- description="A current dictionary look-up by partial tip configuration.",
173
- alias="currentByTipCount",
174
- )
175
-
176
-
177
- class CamActionPickUpTipConfiguration(BaseModel):
178
- distance: float = Field(..., description="How far to move the cams once engaged")
179
- speed: float = Field(..., description="How fast to move the cams when engaged")
180
- prep_move_distance: float = Field(
181
- ..., description="How far to move the cams to engage the rack"
182
- )
183
- prep_move_speed: float = Field(
184
- ..., description="How fast to move the cams when moving to the rack"
185
- )
186
- current_by_tip_count: Dict[int, float] = Field(
187
- ...,
188
- description="A current dictionary look-up by partial tip configuration.",
189
- alias="currentByTipCount",
190
- )
191
- connect_tiprack_distance_mm: float = Field(
192
- description="The distance to move the head down to connect with the tiprack before clamping.",
193
- alias="connectTiprackDistanceMM",
194
- )
195
-
196
-
197
- class PlungerEjectDropTipConfiguration(BaseModel):
198
- current: float = Field(
199
- ..., description="The current to use on the plunger motor when dropping a tip"
200
- )
201
- speed: float = Field(
202
- ..., description="How fast to move the plunger motor when dropping a tip"
203
- )
204
-
205
-
206
- class CamActionDropTipConfiguration(BaseModel):
207
- current: float = Field(
208
- ..., description="The current to use on the cam motors when dropping tips"
209
- )
210
- distance: float = Field(
211
- ..., description="The distance to move the cams when dropping tips"
212
- )
213
- speed: float = Field(
214
- ..., description="How fast to move the cams when dropping tips"
215
- )
216
- prep_move_distance: float = Field(
217
- ..., description="How far to move the cams after disengaging"
218
- )
219
- prep_move_speed: float = Field(
220
- ..., description="How fast to move the cams after disengaging"
221
- )
222
-
223
-
224
- class DropTipConfigurations(BaseModel):
225
- plunger_eject: Optional[PlungerEjectDropTipConfiguration] = Field(
226
- description="Configuration for tip drop via plunger eject", alias="plungerEject"
227
- )
228
- cam_action: Optional[CamActionDropTipConfiguration] = Field(
229
- description="Configuration for tip drop via cam action", alias="camAction"
230
- )
231
-
232
-
233
- class PickUpTipConfigurations(BaseModel):
234
- press_fit: PressFitPickUpTipConfiguration = Field(
235
- description="Configuration for tip pickup via press fit", alias="pressFit"
236
- )
237
- cam_action: Optional[CamActionPickUpTipConfiguration] = Field(
238
- default=None,
239
- description="Configuration for tip pickup via cam action",
240
- alias="camAction",
241
- )
242
-
243
-
244
- class AvailableSensorDefinition(BaseModel):
245
- """The number and type of sensors available in the pipette."""
246
-
247
- sensors: List[str] = Field(..., description="")
248
-
249
-
250
- class PartialTipDefinition(BaseModel):
251
- partial_tip_supported: bool = Field(
252
- ...,
253
- description="Whether partial tip pick up is supported.",
254
- alias="partialTipSupported",
255
- )
256
- available_configurations: List[int] = Field(
257
- default=None,
258
- description="A list of the types of partial tip configurations supported, listed by channel ints",
259
- alias="availableConfigurations",
260
- )
261
-
262
-
263
- class PipettePhysicalPropertiesDefinition(BaseModel):
264
- """The physical properties definition of a pipette."""
265
-
266
- display_name: str = Field(
267
- ...,
268
- description="The display or full product name of the pipette.",
269
- alias="displayName",
270
- )
271
- pipette_backcompat_names: List[dev_types.PipetteName] = Field(
272
- ...,
273
- description="A list of pipette names that are compatible with this pipette.",
274
- alias="backCompatNames",
275
- )
276
- pipette_type: pip_types.PipetteModelType = Field(
277
- ...,
278
- description="The pipette model type (related to number of channels).",
279
- alias="model",
280
- )
281
- display_category: pip_types.PipetteGenerationType = Field(
282
- ..., description="The product model of the pipette.", alias="displayCategory"
283
- )
284
- pick_up_tip_configurations: PickUpTipConfigurations = Field(
285
- ..., alias="pickUpTipConfigurations"
286
- )
287
- drop_tip_configurations: DropTipConfigurations = Field(
288
- ..., alias="dropTipConfigurations"
289
- )
290
- plunger_homing_configurations: PlungerHomingConfigurations = Field(
291
- ..., alias="plungerHomingConfigurations"
292
- )
293
- plunger_motor_configurations: MotorConfigurations = Field(
294
- ..., alias="plungerMotorConfigurations"
295
- )
296
- plunger_positions_configurations: Dict[
297
- pip_types.LiquidClasses, PlungerPositions
298
- ] = Field(..., alias="plungerPositionsConfigurations")
299
- available_sensors: AvailableSensorDefinition = Field(..., alias="availableSensors")
300
- partial_tip_configurations: PartialTipDefinition = Field(
301
- ..., alias="partialTipConfigurations"
302
- )
303
- channels: pip_types.PipetteChannelType = Field(
304
- ..., description="The maximum number of channels on the pipette."
305
- )
306
- shaft_diameter: float = Field(
307
- ..., description="The diameter of the pipette shaft.", alias="shaftDiameter"
308
- )
309
- shaft_ul_per_mm: float = Field(
310
- ...,
311
- description="The conversion rate between uL dispensed and mm of motor movement.",
312
- alias="shaftULperMM",
313
- )
314
- backlash_distance: float = Field(
315
- ...,
316
- description="The distance of backlash on the plunger motor.",
317
- alias="backlashDistance",
318
- )
319
- quirks: List[pip_types.Quirks] = Field(
320
- ..., description="The list of quirks available for the loaded configuration"
321
- )
322
- tip_presence_check_distance_mm: float = Field(
323
- default=0,
324
- description="The distance the high throughput tip motors will travel to check tip status.",
325
- alias="tipPresenceCheckDistanceMM",
326
- )
327
-
328
- end_tip_action_retract_distance_mm: float = Field(
329
- default=0.0,
330
- description="The distance to move the head up after a tip drop or pickup.",
331
- alias="endTipActionRetractDistanceMM",
332
- )
333
-
334
- @validator("pipette_type", pre=True)
335
- def convert_pipette_model_string(cls, v: str) -> pip_types.PipetteModelType:
336
- return pip_types.PipetteModelType(v)
337
-
338
- @validator("channels", pre=True)
339
- def convert_channels(cls, v: int) -> pip_types.PipetteChannelType:
340
- return pip_types.PipetteChannelType(v)
341
-
342
- @validator("display_category", pre=True)
343
- def convert_display_category(cls, v: str) -> pip_types.PipetteGenerationType:
344
- if not v:
345
- return pip_types.PipetteGenerationType.GEN1
346
- return pip_types.PipetteGenerationType(v)
347
-
348
- @validator("quirks", pre=True)
349
- def convert_quirks(cls, v: List[str]) -> List[pip_types.Quirks]:
350
- return [pip_types.Quirks(q) for q in v]
351
-
352
- @validator("plunger_positions_configurations", pre=True)
353
- def convert_plunger_positions(
354
- cls, v: Dict[str, PlungerPositions]
355
- ) -> Dict[pip_types.LiquidClasses, PlungerPositions]:
356
- return {pip_types.LiquidClasses[key]: value for key, value in v.items()}
357
-
358
- class Config:
359
- json_encoders = {
360
- pip_types.PipetteChannelType: lambda v: v.value,
361
- pip_types.PipetteModelType: lambda v: v.value,
362
- pip_types.PipetteGenerationType: lambda v: v.value,
363
- pip_types.Quirks: lambda v: v.value,
364
- }
365
-
366
-
367
- class PipetteRowDefinition(BaseModel):
368
- key: str
369
- ordered_nozzles: List[str] = Field(..., alias="orderedNozzles")
370
-
371
- @validator("key")
372
- def check_key_is_row(cls, v: str) -> str:
373
- if not ROW_NAMES.search(v):
374
- raise ValueError(f"{v} is not a valid row name")
375
- return v
376
-
377
-
378
- class PipetteColumnDefinition(BaseModel):
379
- key: str
380
- ordered_nozzles: List[str] = Field(..., alias="orderedNozzles")
381
-
382
- @validator("key")
383
- def check_key_is_column(cls, v: str) -> str:
384
- if not COLUMN_NAMES.search(v):
385
- raise ValueError(f"{v} is not a valid column name")
386
- return v
387
-
388
-
389
- class PipetteGeometryDefinition(BaseModel):
390
- """The geometry properties definition of a pipette."""
391
-
392
- nozzle_offset: List[float] = Field(..., alias="nozzleOffset")
393
- path_to_3D: str = Field(
394
- ...,
395
- description="The shared data relative path to the 3D representation of the pipette model.",
396
- alias="pathTo3D",
397
- )
398
- nozzle_map: Dict[str, List[float]] = Field(..., alias="nozzleMap")
399
- ordered_columns: List[PipetteColumnDefinition] = Field(..., alias="orderedColumns")
400
- ordered_rows: List[PipetteRowDefinition] = Field(..., alias="orderedRows")
401
-
402
- @validator("nozzle_map", pre=True)
403
- def check_nonempty_strings(
404
- cls, v: Dict[str, List[float]]
405
- ) -> Dict[str, List[float]]:
406
- # Note, the key should be able to be a regex but I think
407
- # we're not on a pydantic version that supports that.
408
- for k in v.keys():
409
- if not NOZZLE_MAP_NAMES.match(k):
410
- raise ValueError("{k} is not a valid key entry for nozzle map.")
411
- return v
412
-
413
-
414
- class PipetteLiquidPropertiesDefinition(BaseModel):
415
- """The liquid properties definition of a pipette."""
416
-
417
- supported_tips: Dict[pip_types.PipetteTipType, SupportedTipsDefinition] = Field(
418
- ..., alias="supportedTips"
419
- )
420
- tip_overlap_dictionary: Dict[str, float] = Field(
421
- ...,
422
- description="The default tip overlap associated with this tip type.",
423
- alias="defaultTipOverlapDictionary",
424
- )
425
- max_volume: int = Field(
426
- ...,
427
- description="The maximum supported volume of the pipette.",
428
- alias="maxVolume",
429
- )
430
- min_volume: float = Field(
431
- ...,
432
- description="The minimum supported volume of the pipette.",
433
- alias="minVolume",
434
- )
435
- default_tipracks: List[str] = Field(
436
- ...,
437
- description="A list of default tiprack paths.",
438
- regex="opentrons/[a-z0-9._]+/[0-9]",
439
- alias="defaultTipracks",
440
- )
441
-
442
- @validator("supported_tips", pre=True)
443
- def convert_aspirate_key_to_channel_type(
444
- cls, v: Dict[str, SupportedTipsDefinition]
445
- ) -> Dict[pip_types.PipetteTipType, SupportedTipsDefinition]:
446
- return {pip_types.PipetteTipType[key]: value for key, value in v.items()}
447
-
448
-
449
- class PipetteConfigurations(
450
- PipetteGeometryDefinition,
451
- PipettePhysicalPropertiesDefinition,
452
- ):
453
- """The full pipette configurations of a given model and version."""
454
-
455
- version: pip_types.PipetteVersionType = Field(
456
- ..., description="The version of the configuration loaded."
457
- )
458
- mount_configurations: pip_types.RobotMountConfigs = Field(
459
- ...,
460
- )
461
- liquid_properties: Dict[
462
- pip_types.LiquidClasses, PipetteLiquidPropertiesDefinition
463
- ] = Field(
464
- ..., description="A dictionary of liquid properties keyed by liquid classes."
465
- )
466
-
467
- @validator("liquid_properties", pre=True)
468
- def convert_liquid_properties_key(
469
- cls, v: Dict[str, PipetteLiquidPropertiesDefinition]
470
- ) -> Dict[pip_types.LiquidClasses, PipetteLiquidPropertiesDefinition]:
471
- return {pip_types.LiquidClasses[key]: value for key, value in v.items()}
472
-
473
-
474
- def liquid_class_for_volume_between_default_and_defaultlowvolume(
475
- volume: float,
476
- current_liquid_class_name: pip_types.LiquidClasses,
477
- available_liquid_classes: Dict[
478
- pip_types.LiquidClasses, PipetteLiquidPropertiesDefinition
479
- ],
480
- ) -> pip_types.LiquidClasses:
481
- """Determine the appropriate liquid class to use for a volume.
482
-
483
- This function has such a weird name because it is hardcoded to only use the liquid
484
- classes default and defaultLowVolume. It should no longer be used when those liquid
485
- classes change.
486
- """
487
- # For now, until we add more liquid classes, we're going to hardcode the default
488
- # and lowVolumeDefault liquid classes as the ones to switch between.
489
- has_lvd = pip_types.LiquidClasses.lowVolumeDefault in available_liquid_classes
490
-
491
- if not has_lvd:
492
- return pip_types.LiquidClasses.default
493
- if volume >= available_liquid_classes[pip_types.LiquidClasses.default].min_volume:
494
- return pip_types.LiquidClasses.default
495
- return pip_types.LiquidClasses.lowVolumeDefault
496
-
497
-
498
- def default_tip_for_liquid_class(
499
- liquid_class_config: PipetteLiquidPropertiesDefinition,
500
- ) -> pip_types.PipetteTipType:
501
- """Provide a "default tip", the one with the largest volume."""
502
- tip_names = liquid_class_config.supported_tips.keys()
503
- return sorted(tip_names, key=lambda tip: tip.value)[-1]