@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,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()