@opentrons/shared-data 0.0.1-alpha.20 → 0.0.1-alpha.21

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 (151) hide show
  1. package/package.json +1 -1
  2. package/js/__tests__/__snapshots__/pipettes.test.ts.snap +0 -5969
  3. package/js/__tests__/deckSchemas.test.ts +0 -87
  4. package/js/__tests__/errors.test.js +0 -21
  5. package/js/__tests__/getAreSlotsAdjacent.test.ts +0 -128
  6. package/js/__tests__/getWellNamePerMultiTip.test.ts +0 -162
  7. package/js/__tests__/labwareDefQuirks.test.ts +0 -37
  8. package/js/__tests__/labwareDefSchemaV1.test.ts +0 -82
  9. package/js/__tests__/labwareDefSchemaV2.test.ts +0 -298
  10. package/js/__tests__/moduleAccessors.test.ts +0 -50
  11. package/js/__tests__/moduleSpecsSchema.test.ts +0 -77
  12. package/js/__tests__/pipetteSchemaV2.test.ts +0 -107
  13. package/js/__tests__/pipetteSpecSchemas.test.ts +0 -48
  14. package/js/__tests__/pipettes.test.ts +0 -58
  15. package/js/__tests__/protocolSchemaV4.test.ts +0 -137
  16. package/js/__tests__/protocolSchemaV5.test.ts +0 -137
  17. package/js/__tests__/protocolSchemaV6.test.ts +0 -132
  18. package/js/__tests__/protocolSchemaV7.test.ts +0 -64
  19. package/js/__tests__/protocolValidation.test.ts +0 -83
  20. package/js/__tests__/sortWells.test.ts +0 -40
  21. package/js/__tests__/splitWellsOnColumn.test.ts +0 -21
  22. package/js/__tests__/validateErrors.test.js +0 -34
  23. package/js/constants.ts +0 -338
  24. package/js/cypressUtils.ts +0 -35
  25. package/js/errors.ts +0 -33
  26. package/js/fixtures.ts +0 -161
  27. package/js/getLabware.ts +0 -154
  28. package/js/gripper.ts +0 -29
  29. package/js/helpers/__tests__/getAdapterName.test.ts +0 -31
  30. package/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.ts +0 -12
  31. package/js/helpers/__tests__/getVectorDifference.test.ts +0 -25
  32. package/js/helpers/__tests__/getVectorSum.test.ts +0 -21
  33. package/js/helpers/__tests__/labwareInference.test.ts +0 -84
  34. package/js/helpers/__tests__/orderWells.test.ts +0 -87
  35. package/js/helpers/__tests__/parseProtocolData.test.ts +0 -165
  36. package/js/helpers/__tests__/volume.test.ts +0 -108
  37. package/js/helpers/__tests__/wellSets.test.ts +0 -352
  38. package/js/helpers/get96Channel384WellPlateWells.ts +0 -44
  39. package/js/helpers/getAddressableAreasInProtocol.ts +0 -59
  40. package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +0 -30
  41. package/js/helpers/getModuleVizDims.ts +0 -118
  42. package/js/helpers/getOccludedSlotCountForModule.ts +0 -13
  43. package/js/helpers/getVectorDifference.ts +0 -12
  44. package/js/helpers/getVectorSum.ts +0 -12
  45. package/js/helpers/getWellNamePerMultiTip.ts +0 -86
  46. package/js/helpers/getWellTotalVolume.ts +0 -16
  47. package/js/helpers/index.ts +0 -347
  48. package/js/helpers/labwareInference.ts +0 -92
  49. package/js/helpers/orderWells.ts +0 -69
  50. package/js/helpers/parseProtocolData.ts +0 -141
  51. package/js/helpers/volume.ts +0 -35
  52. package/js/helpers/wellIsRect.ts +0 -6
  53. package/js/helpers/wellSets.ts +0 -155
  54. package/js/index.ts +0 -14
  55. package/js/labwareTools/__tests__/__snapshots__/createIrregularLabware.test.ts.snap +0 -3
  56. package/js/labwareTools/__tests__/__snapshots__/createLabware.test.ts.snap +0 -3
  57. package/js/labwareTools/__tests__/createDefaultDisplayName.test.ts +0 -111
  58. package/js/labwareTools/__tests__/createIrregularLabware.test.ts +0 -226
  59. package/js/labwareTools/__tests__/createLabware.test.ts +0 -147
  60. package/js/labwareTools/index.ts +0 -452
  61. package/js/modules.ts +0 -97
  62. package/js/pipettes.ts +0 -89
  63. package/js/protocols.ts +0 -290
  64. package/js/schema.ts +0 -80
  65. package/js/scripts/generateDeckLayersFromSVG.js +0 -46
  66. package/js/titleCase.ts +0 -30
  67. package/js/types.ts +0 -600
  68. package/python/.coveragerc +0 -4
  69. package/python/.flake8 +0 -32
  70. package/python/Config.in +0 -10
  71. package/python/Makefile +0 -134
  72. package/python/Pipfile +0 -28
  73. package/python/Pipfile.lock +0 -645
  74. package/python/buildroot.mk +0 -30
  75. package/python/mypy.ini +0 -41
  76. package/python/opentrons_shared_data/__init__.py +0 -17
  77. package/python/opentrons_shared_data/_version.py +0 -20
  78. package/python/opentrons_shared_data/command/__init__.py +0 -52
  79. package/python/opentrons_shared_data/deck/__init__.py +0 -96
  80. package/python/opentrons_shared_data/deck/dev_types.py +0 -180
  81. package/python/opentrons_shared_data/errors/__init__.py +0 -30
  82. package/python/opentrons_shared_data/errors/categories.py +0 -60
  83. package/python/opentrons_shared_data/errors/codes.py +0 -108
  84. package/python/opentrons_shared_data/errors/exceptions.py +0 -915
  85. package/python/opentrons_shared_data/gripper/__init__.py +0 -63
  86. package/python/opentrons_shared_data/gripper/constants.py +0 -6
  87. package/python/opentrons_shared_data/gripper/gripper_definition.py +0 -101
  88. package/python/opentrons_shared_data/labware/__init__.py +0 -22
  89. package/python/opentrons_shared_data/labware/constants.py +0 -7
  90. package/python/opentrons_shared_data/labware/dev_types.py +0 -140
  91. package/python/opentrons_shared_data/labware/labware_definition.py +0 -328
  92. package/python/opentrons_shared_data/load.py +0 -57
  93. package/python/opentrons_shared_data/module/__init__.py +0 -74
  94. package/python/opentrons_shared_data/module/dev_types.py +0 -141
  95. package/python/opentrons_shared_data/pipette/__init__.py +0 -107
  96. package/python/opentrons_shared_data/pipette/dev_types.py +0 -177
  97. package/python/opentrons_shared_data/pipette/file_operation_helpers.py +0 -37
  98. package/python/opentrons_shared_data/pipette/load_data.py +0 -261
  99. package/python/opentrons_shared_data/pipette/model_constants.py +0 -123
  100. package/python/opentrons_shared_data/pipette/mutable_configurations.py +0 -431
  101. package/python/opentrons_shared_data/pipette/pipette_definition.py +0 -503
  102. package/python/opentrons_shared_data/pipette/pipette_load_name_conversions.py +0 -240
  103. package/python/opentrons_shared_data/pipette/scripts/__init__.py +0 -0
  104. package/python/opentrons_shared_data/pipette/scripts/build_json_script.py +0 -469
  105. package/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py +0 -450
  106. package/python/opentrons_shared_data/pipette/types.py +0 -193
  107. package/python/opentrons_shared_data/protocol/__init__.py +0 -13
  108. package/python/opentrons_shared_data/protocol/constants.py +0 -98
  109. package/python/opentrons_shared_data/protocol/dev_types.py +0 -436
  110. package/python/opentrons_shared_data/protocol/models/__init__.py +0 -48
  111. package/python/opentrons_shared_data/protocol/models/protocol_schema_v6.py +0 -145
  112. package/python/opentrons_shared_data/protocol/models/protocol_schema_v7.py +0 -95
  113. package/python/opentrons_shared_data/protocol/models/protocol_schema_v8.py +0 -110
  114. package/python/opentrons_shared_data/protocol/models/shared_models.py +0 -111
  115. package/python/opentrons_shared_data/py.typed +0 -0
  116. package/python/opentrons_shared_data/robot/__init__.py +0 -33
  117. package/python/opentrons_shared_data/robot/dev_types.py +0 -37
  118. package/python/pytest.ini +0 -2
  119. package/python/setup.cfg +0 -5
  120. package/python/setup.py +0 -179
  121. package/python/tests/__init__.py +0 -1
  122. package/python/tests/conftest.py +0 -0
  123. package/python/tests/deck/__init__.py +0 -0
  124. package/python/tests/deck/test_list_names.py +0 -12
  125. package/python/tests/deck/test_position.py +0 -113
  126. package/python/tests/deck/test_typechecks.py +0 -28
  127. package/python/tests/errors/__init__.py +0 -1
  128. package/python/tests/errors/test_error_completeness.py +0 -19
  129. package/python/tests/errors/test_exceptions.py +0 -74
  130. package/python/tests/gripper/__init__.py +0 -0
  131. package/python/tests/gripper/test_definition.py +0 -30
  132. package/python/tests/gripper/test_load.py +0 -16
  133. package/python/tests/labware/__init__.py +0 -13
  134. package/python/tests/labware/test_typechecks.py +0 -21
  135. package/python/tests/module/__init__.py +0 -20
  136. package/python/tests/module/test_load.py +0 -49
  137. package/python/tests/module/test_typechecks.py +0 -34
  138. package/python/tests/pipette/__init__.py +0 -0
  139. package/python/tests/pipette/test_load_data.py +0 -103
  140. package/python/tests/pipette/test_mutable_configurations.py +0 -266
  141. package/python/tests/pipette/test_pipette_definition.py +0 -183
  142. package/python/tests/pipette/test_pipette_load_name_conversions.py +0 -222
  143. package/python/tests/pipette/test_typechecks.py +0 -50
  144. package/python/tests/pipette/test_validate_schema.py +0 -37
  145. package/python/tests/protocol/__init__.py +0 -15
  146. package/python/tests/protocol/test_protocol_schema_v6.py +0 -107
  147. package/python/tests/protocol/test_protocol_schema_v7.py +0 -34
  148. package/python/tests/protocol/test_protocol_schema_v8.py +0 -20
  149. package/python/tests/protocol/test_typechecks.py +0 -36
  150. package/python/tests/robot/__init__.py +0 -0
  151. package/python/tests/robot/test_typechecks.py +0 -20
@@ -1,469 +0,0 @@
1
- import argparse
2
- import csv
3
- import json
4
- from ast import literal_eval
5
- from typing import Optional, Dict, Union, Any, List
6
- from pathlib import Path
7
- from pydantic import BaseModel
8
- import math
9
-
10
- from ... import get_shared_data_root
11
- from ..pipette_definition import (
12
- PipetteGeometryDefinition,
13
- PipetteLiquidPropertiesDefinition,
14
- PipettePhysicalPropertiesDefinition,
15
- PlungerPositions,
16
- SupportedTipsDefinition,
17
- MotorConfigurations,
18
- PartialTipDefinition,
19
- AvailableSensorDefinition,
20
- PickUpTipConfigurations,
21
- PressFitPickUpTipConfiguration,
22
- DropTipConfigurations,
23
- PlungerEjectDropTipConfiguration,
24
- )
25
-
26
- from ..dev_types import PipetteModelSpec
27
-
28
-
29
- PIPETTE_DEFINITION_ROOT = Path("pipette") / "definitions" / "2"
30
- GEOMETRY_ROOT = get_shared_data_root() / PIPETTE_DEFINITION_ROOT / "geometry"
31
- GENERAL_ROOT = get_shared_data_root() / PIPETTE_DEFINITION_ROOT / "general"
32
- LIQUID_ROOT = get_shared_data_root() / PIPETTE_DEFINITION_ROOT / "liquid"
33
-
34
- GENERAL_SCHEMA = "#/pipette/schemas/2/pipettePropertiesSchema.json"
35
- LIQUID_SCHEMA = "#/pipette/schemas/2/pipetteLiquidPropertiesSchema.json"
36
- GEOMETRY_SCHEMA = "#/pipette/schemas/2/pipetteGeometryPropertiesSchema.json"
37
-
38
-
39
- def _build_pickup_tip_data(
40
- model_configurations: Optional[PipetteModelSpec] = None,
41
- ) -> PickUpTipConfigurations:
42
- presses = 0
43
- increment = 0
44
- distance = 0.0
45
- if model_configurations:
46
- current = model_configurations["pickUpCurrent"]["value"]
47
- speed = model_configurations["pickUpSpeed"]["value"]
48
- presses = model_configurations["pickUpPresses"]["value"]
49
- increment = int(model_configurations["pickUpIncrement"]["value"])
50
- distance = model_configurations["pickUpDistance"]["value"]
51
- else:
52
- print("Handling pick up tip configurations\n")
53
- speed = float(input("please provide the speed\n"))
54
- presses = int(input("please provide the number of presses for force pick up\n"))
55
- increment = int(
56
- input(
57
- "please provide the increment to move the pipette down for force pickup\n"
58
- )
59
- )
60
- distance = float(
61
- input("please provide the starting distance for pick up tip\n")
62
- )
63
- print(f"TODO: Current {current} is not used yet")
64
- return PickUpTipConfigurations(
65
- pressFit=PressFitPickUpTipConfiguration(
66
- speed=speed,
67
- presses=presses,
68
- increment=increment,
69
- distance=distance,
70
- currentByTipCount={},
71
- )
72
- )
73
-
74
-
75
- def _build_drop_tip_data(
76
- model_configurations: Optional[PipetteModelSpec] = None,
77
- ) -> DropTipConfigurations:
78
- if model_configurations:
79
- current = model_configurations["dropTipCurrent"]["value"]
80
- speed = model_configurations["dropTipSpeed"]["value"]
81
- else:
82
- print("Handling drop tip configurations\n")
83
- speed = float(input("please provide the speed\n"))
84
- return DropTipConfigurations(
85
- plungerEject=PlungerEjectDropTipConfiguration(
86
- current=current,
87
- speed=speed,
88
- )
89
- )
90
-
91
-
92
- def _build_plunger_positions(
93
- model_configurations: Optional[PipetteModelSpec] = None,
94
- ) -> PlungerPositions:
95
- if model_configurations:
96
- top = model_configurations["top"]["value"]
97
- bottom = model_configurations["bottom"]["value"]
98
- blow_out = model_configurations["blowout"]["value"]
99
- drop_tip = model_configurations["dropTip"]["value"]
100
- else:
101
- print("Handling plunger motor positions\n")
102
- top = float(input("Please provide the top plunger position\n"))
103
- bottom = float(input("Please provide the bottom plunger position\n"))
104
- blow_out = float(input("Please provide the blow out plunger position\n"))
105
- drop_tip = float(input("Please provide the drop tip plunger position\n"))
106
- return PlungerPositions(top=top, bottom=bottom, blowout=blow_out, drop=drop_tip)
107
-
108
-
109
- def _build_motor_configurations(
110
- model_configurations: Optional[PipetteModelSpec] = None,
111
- ) -> MotorConfigurations:
112
- if model_configurations:
113
- run = model_configurations["plungerCurrent"]["value"]
114
- idle = model_configurations.get("idleCurrent", run)
115
- else:
116
- print("Handling default plunger motor currents\n")
117
- idle = float(
118
- input("Please provide the default idle current of the plunger motor\n")
119
- )
120
- run = float(
121
- input("Please provide the default run current of the plunger motor\n")
122
- )
123
- return MotorConfigurations(idle=idle, run=run)
124
-
125
-
126
- def _build_partial_tip_configurations(channels: int) -> PartialTipDefinition:
127
- if channels == 8:
128
- return PartialTipDefinition(
129
- partialTipSupported=True, availableConfigurations=[1, 2, 3, 4, 5, 6, 7, 8]
130
- )
131
- elif channels == 96:
132
- return PartialTipDefinition(
133
- partialTipSupported=True, availableConfigurations=[1, 8, 12, 96]
134
- )
135
- else:
136
- return PartialTipDefinition(partialTipSupported=False)
137
-
138
-
139
- def build_geometry_model_v2(
140
- input_dictionary: Dict[str, Any]
141
- ) -> PipetteGeometryDefinition:
142
- return PipetteGeometryDefinition.parse_obj(input_dictionary)
143
-
144
-
145
- def build_liquid_model_v2(
146
- input_dictionary: Dict[str, Any],
147
- supported_tip_configurations: Dict[str, SupportedTipsDefinition],
148
- ) -> PipetteLiquidPropertiesDefinition:
149
- if input_dictionary:
150
- if input_dictionary.get("partialTipConfigurations"):
151
- return PipetteLiquidPropertiesDefinition.parse_obj(
152
- {**input_dictionary, "supportedTips": supported_tip_configurations}
153
- )
154
- else:
155
- return PipetteLiquidPropertiesDefinition.parse_obj(
156
- {
157
- **input_dictionary,
158
- "supportedTips": supported_tip_configurations,
159
- }
160
- )
161
- max_volume = int(input("please provide the max volume of the pipette\n"))
162
- min_volume = float(input("please provide the min volume of the pipette\n"))
163
- default_tipracks = input(
164
- "please input the load names of default tipracks separated by commas\n"
165
- )
166
- list_default_tipracks = default_tipracks.split(",")
167
- return PipetteLiquidPropertiesDefinition.parse_obj(
168
- {
169
- "supportedTips": supported_tip_configurations,
170
- "maxVolume": max_volume,
171
- "minVolume": min_volume,
172
- "defaultTipracks": list_default_tipracks,
173
- }
174
- )
175
-
176
-
177
- def build_physical_model_v2(
178
- input_dictionary: Optional[Dict[str, Any]], pipette_type: Optional[str] = None
179
- ) -> PipettePhysicalPropertiesDefinition:
180
- if input_dictionary:
181
- available_sensors = AvailableSensorDefinition(
182
- sensors=input_dictionary.pop("availableSensors", [])
183
- )
184
- back_compat_names = input_dictionary.pop("backCompatNames", [])
185
- return PipettePhysicalPropertiesDefinition.parse_obj(
186
- {
187
- **input_dictionary,
188
- "availableSensors": available_sensors,
189
- "backCompatNames": back_compat_names,
190
- }
191
- )
192
- print(f"Handling general pipette information for {pipette_type}\n")
193
- display_name = input("please provide the product name of the pipette\n")
194
-
195
- display_category = input("please provide the model generation of the pipette\n")
196
- input_available_sensors = input(
197
- "Please provide a list of available sensors, separated by comma\n"
198
- )
199
- channels = input(f"Please provide the number of channels your {pipette_type} has\n")
200
- shaft_diam = float(input(f"Please provide the shaft diameter of {pipette_type}\n"))
201
- shaft_ul_per_mm = float(
202
- input(f"Please provide the uL to mm conversion for {pipette_type}\n")
203
- )
204
- pick_up_tip_configurations = _build_pickup_tip_data()
205
- drop_tip_configurations = _build_drop_tip_data()
206
- plunger_positions = _build_plunger_positions()
207
- plunger_motor_configurations = _build_motor_configurations()
208
- partial_tip_configurations = _build_partial_tip_configurations(int(channels))
209
-
210
- back_compat_names_str = input(
211
- "Please list compatible pipette names separated by commas or hit enter if none"
212
- )
213
- if back_compat_names_str:
214
- back_compat_names = [i.strip() for i in back_compat_names_str.split(",")]
215
- else:
216
- back_compat_names = []
217
- return PipettePhysicalPropertiesDefinition.parse_obj(
218
- {
219
- "displayName": display_name,
220
- "model": pipette_type,
221
- "displayCategory": display_category,
222
- "pickUpTipConfigurations": pick_up_tip_configurations,
223
- "dropTipConfigurations": drop_tip_configurations,
224
- "plungerMotorConfigurations": plunger_motor_configurations,
225
- "plungerPositionsConfigurations": plunger_positions,
226
- "availableSensors": AvailableSensorDefinition(
227
- sensors=input_available_sensors.split(",")
228
- ),
229
- "partialTipConfigurations": partial_tip_configurations,
230
- "channels": channels,
231
- "shaftDiameter": shaft_diam,
232
- "shaftULperMM": shaft_ul_per_mm,
233
- "backCompatNames": back_compat_names,
234
- }
235
- )
236
-
237
-
238
- def build_supported_tips(input_dictionary: Dict[str, Any]) -> SupportedTipsDefinition:
239
- return SupportedTipsDefinition.parse_obj(input_dictionary)
240
-
241
-
242
- def save_to_file(
243
- directorypath: Path,
244
- file_name: str,
245
- data: Union[BaseModel, Dict[str, Any]],
246
- schema_path: str,
247
- ) -> None:
248
- """
249
- Function used to save data to a file
250
- """
251
-
252
- directorypath.mkdir(parents=True, exist_ok=True)
253
- filepath = directorypath / f"{file_name}.json"
254
- if isinstance(data, BaseModel):
255
- # We have to rely on the json serialization of the
256
- # pydantic model to properly convert special objects
257
- # such as (pipetteModelType) to a string. However,
258
- # we also want to add in a new key on top of the
259
- # data in the pydantic model so we need to convert it
260
- # back to a dictionary before saving to file.
261
- json_basemodel = data.json(by_alias=True)
262
- dict_basemodel = json.loads(json_basemodel)
263
- dict_basemodel["$otSharedSchema"] = schema_path
264
- filepath.write_text(
265
- json.dumps(dict_basemodel, ensure_ascii=False), encoding="utf-8"
266
- )
267
- else:
268
- data["$otSharedSchema"] = schema_path
269
- filepath.write_text(json.dumps(data, ensure_ascii=False), encoding="utf-8")
270
-
271
-
272
- def migrate_new_blow_out_configs_v2() -> None:
273
- pipette_volumes = {
274
- 1: ["p10", "p50", "p300", "p1000"],
275
- 2: ["p20", "p300", "p1000"],
276
- 3: ["p50", "p1000"],
277
- }
278
-
279
- for pipette_gen in range(1, 4): # gen 1, gen 2, gen 3
280
- print(f"\nTaking data for gen{pipette_gen} pipettes:")
281
- # overwrite and pass in dict with user input for each gen
282
- shaft_diameters = {
283
- vol: float(input(f"Enter shaft diameter for gen{pipette_gen} {vol}: "))
284
- for vol in pipette_volumes[pipette_gen]
285
- }
286
- fill_blowout_configs(pipette_gen, shaft_diameters, pipette_volumes[pipette_gen])
287
-
288
-
289
- def fill_blowout_configs(
290
- pipette_gen: int, shaft_diameters: Dict[str, float], volumes: List[str]
291
- ) -> None:
292
-
293
- general_config_files = Path(GENERAL_ROOT).glob("*")
294
- for pipette_type in general_config_files: # single, eight, 96-channel
295
- for volume in volumes: # pipette max volume- p10, p20, p50, etc.
296
- shaft_diameter = shaft_diameters[volume]
297
- # calculate uL per mm, default blowout vol
298
- ul_per_mm = math.pi * (shaft_diameter / 2) ** 2
299
- # get path for every file version for the pipette gen at hand
300
- volume_path = Path(pipette_type / volume)
301
- for general_file_version in volume_path.glob(f"{str(pipette_gen)}_*.json"):
302
- with open(general_file_version, "r") as file:
303
- general_config_dict = json.load(file)
304
- general_config_dict["shaftDiameter"] = round(shaft_diameter, 3)
305
- general_config_dict["shaftULperMM"] = round(ul_per_mm, 3)
306
-
307
- # get file path to pass into save_to_file
308
- gen_path = GENERAL_ROOT / pipette_type / volume
309
- version_str = str(general_file_version).split("/")[-1][:-5]
310
- save_to_file(gen_path, version_str, general_config_dict, GENERAL_SCHEMA)
311
-
312
-
313
- def build_new_pipette_model_v2(
314
- pipette_functions_dict: Dict[str, Any], pipette_model_csv: str
315
- ) -> None:
316
- """
317
- Build a brand new pipette model from user inputted data.
318
- """
319
- top_level_pipette_model = {}
320
- with open(pipette_model_csv, "r") as f:
321
- reader = csv.reader(f)
322
- current_key = None
323
- for row in reader:
324
- if row[0]:
325
- current_key = row[0]
326
- top_level_pipette_model[current_key] = {row[1]: literal_eval(row[2])}
327
- elif current_key:
328
- top_level_pipette_model[current_key][row[1]] = literal_eval(row[2])
329
- else:
330
- continue
331
- geometry_model = build_geometry_model_v2(top_level_pipette_model["geometry"])
332
- liquid_model = build_liquid_model_v2(
333
- top_level_pipette_model["liquid"],
334
- pipette_functions_dict,
335
- )
336
- liquid_model_dict = liquid_model.dict(by_alias=True)
337
- liquid_model_dict["supportedTips"] = {
338
- k.name: v for k, v in liquid_model_dict["supportedTips"].items()
339
- }
340
- pipette_type = f"p{liquid_model.max_volume}"
341
- physical_model = build_physical_model_v2(
342
- {
343
- **top_level_pipette_model["general"],
344
- "plungerMotorConfigurations": top_level_pipette_model[
345
- "plungerMotorConfigurations"
346
- ],
347
- "plungerPositionsConfigurations": top_level_pipette_model[
348
- "plungerPositionsConfigurations"
349
- ],
350
- "pickUpTipConfigurations": top_level_pipette_model[
351
- "pickUpTipConfigurations"
352
- ],
353
- "dropTipConfigurations": top_level_pipette_model["dropTipConfigurations"],
354
- "partialTipConfigurations": _build_partial_tip_configurations(
355
- top_level_pipette_model["general"]["channels"]
356
- ),
357
- },
358
- pipette_type,
359
- )
360
-
361
- major_version = input("please provide the major version of this pipette model\n")
362
- minor_version = input("please provide the minor version of this pipette model\n")
363
-
364
- file_name = f"{major_version}_{minor_version}"
365
- current_pipette_path = Path(physical_model.channels.name.lower()) / pipette_type
366
-
367
- save_to_file(
368
- GEOMETRY_ROOT / current_pipette_path, file_name, geometry_model, GEOMETRY_SCHEMA
369
- )
370
- save_to_file(
371
- GENERAL_ROOT / current_pipette_path, file_name, physical_model, GENERAL_SCHEMA
372
- )
373
- save_to_file(
374
- LIQUID_ROOT / current_pipette_path, file_name, liquid_model_dict, LIQUID_SCHEMA
375
- )
376
-
377
-
378
- def main() -> None:
379
- """Entry point."""
380
- parser = argparse.ArgumentParser(
381
- description="96 channel tip handling testing script."
382
- )
383
- parser.add_argument(
384
- "--path_to_pipette_model",
385
- type=str,
386
- help="the csv filled with data to build a pipette model",
387
- default=None,
388
- )
389
- parser.add_argument(
390
- "--migrate_blowout_configs",
391
- type=bool,
392
- help="If true, migrate new blowout configs to existing json files",
393
- default=False,
394
- )
395
-
396
- args = parser.parse_args()
397
- if args.migrate_blowout_configs:
398
- migrate_new_blow_out_configs_v2()
399
- else:
400
- using_csv = "" if args.path_to_pipette_model else "out"
401
- print(f"Building new pipette function with{using_csv} using csv")
402
-
403
- next_tip = True
404
- pipette_functions_dict: Dict[str, Any] = {}
405
- while next_tip:
406
- print("Preparing pipetting function table from csv\n")
407
- tip_volume = input("Please provide the next tip volume\n")
408
- tiprack = input(
409
- "Please provide the tiprack/tip type associated with this data\n"
410
- )
411
- path_to_data = input("Please provide the data path to the csv\n")
412
- csv_dict = pipette_functions_dict.get(f"t{tip_volume}", {})
413
- with open(path_to_data, "r") as f:
414
- reader = csv.reader(f)
415
- pipetting_key = None
416
- for row in reader:
417
- current_key_exists = csv_dict.get(row[0])
418
- if row[0] == "aspirate" or row[0] == "dispense":
419
- pipetting_key = row[0]
420
- if current_key_exists:
421
- csv_dict[pipetting_key][f"{tiprack}"].append(
422
- [float(row[1]), float(row[2]), float(row[3])]
423
- )
424
- else:
425
- csv_dict[pipetting_key] = {
426
- f"{tiprack}": [
427
- [float(row[1]), float(row[2]), float(row[3])]
428
- ]
429
- }
430
- elif pipetting_key and not row[0]:
431
- csv_dict[pipetting_key][f"{tiprack}"].append(
432
- [float(row[1]), float(row[2]), float(row[3])]
433
- )
434
- else:
435
- pipetting_key = None
436
- if current_key_exists:
437
- continue
438
- csv_dict[row[0]] = row[1]
439
- pipette_functions_dict[f"t{tip_volume}"] = csv_dict
440
- cont = input("Additional tips? Please enter y/n")
441
-
442
- next_tip = cont == "y" or cont == "yes"
443
- converted_pipette_functions_dict = {
444
- k: build_supported_tips(d) for k, d in pipette_functions_dict.items()
445
- }
446
-
447
- print(
448
- "Please review the aspirate and dispense functions once the pipette model is built.\n"
449
- )
450
- build_new_pipette_model_v2(
451
- converted_pipette_functions_dict, args.path_to_pipette_model
452
- )
453
-
454
-
455
- if __name__ == "__main__":
456
- """
457
- A script to automate building a pipette configuration definition.
458
-
459
- This script can either perform migrations from a v1 -> v2 schema format
460
- or build a brand new script from scratch.
461
-
462
- When building a new pipette configuration model, you will either need
463
- to provide CSVs or use command line inputs.
464
-
465
- If you choose CSVs you will need one CSV for the general pipette configuration
466
- data (such as pipette model or number of channels) and one for every tip
467
- type that this pipette model can support.
468
- """
469
- main()