opentrons 8.6.0a1__py3-none-any.whl

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.

Potentially problematic release.


This version of opentrons might be problematic. Click here for more details.

Files changed (600) hide show
  1. opentrons/__init__.py +150 -0
  2. opentrons/_version.py +34 -0
  3. opentrons/calibration_storage/__init__.py +54 -0
  4. opentrons/calibration_storage/deck_configuration.py +62 -0
  5. opentrons/calibration_storage/encoder_decoder.py +31 -0
  6. opentrons/calibration_storage/file_operators.py +142 -0
  7. opentrons/calibration_storage/helpers.py +103 -0
  8. opentrons/calibration_storage/ot2/__init__.py +34 -0
  9. opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
  10. opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
  11. opentrons/calibration_storage/ot2/models/__init__.py +0 -0
  12. opentrons/calibration_storage/ot2/models/v1.py +149 -0
  13. opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
  14. opentrons/calibration_storage/ot2/tip_length.py +281 -0
  15. opentrons/calibration_storage/ot3/__init__.py +31 -0
  16. opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
  17. opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
  18. opentrons/calibration_storage/ot3/models/__init__.py +0 -0
  19. opentrons/calibration_storage/ot3/models/v1.py +122 -0
  20. opentrons/calibration_storage/ot3/module_offset.py +138 -0
  21. opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
  22. opentrons/calibration_storage/types.py +45 -0
  23. opentrons/cli/__init__.py +21 -0
  24. opentrons/cli/__main__.py +5 -0
  25. opentrons/cli/analyze.py +501 -0
  26. opentrons/config/__init__.py +631 -0
  27. opentrons/config/advanced_settings.py +871 -0
  28. opentrons/config/defaults_ot2.py +214 -0
  29. opentrons/config/defaults_ot3.py +499 -0
  30. opentrons/config/feature_flags.py +86 -0
  31. opentrons/config/gripper_config.py +55 -0
  32. opentrons/config/reset.py +203 -0
  33. opentrons/config/robot_configs.py +187 -0
  34. opentrons/config/types.py +183 -0
  35. opentrons/drivers/__init__.py +0 -0
  36. opentrons/drivers/absorbance_reader/__init__.py +11 -0
  37. opentrons/drivers/absorbance_reader/abstract.py +72 -0
  38. opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
  39. opentrons/drivers/absorbance_reader/driver.py +81 -0
  40. opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
  41. opentrons/drivers/absorbance_reader/simulator.py +84 -0
  42. opentrons/drivers/asyncio/__init__.py +0 -0
  43. opentrons/drivers/asyncio/communication/__init__.py +22 -0
  44. opentrons/drivers/asyncio/communication/async_serial.py +183 -0
  45. opentrons/drivers/asyncio/communication/errors.py +88 -0
  46. opentrons/drivers/asyncio/communication/serial_connection.py +552 -0
  47. opentrons/drivers/command_builder.py +102 -0
  48. opentrons/drivers/flex_stacker/__init__.py +13 -0
  49. opentrons/drivers/flex_stacker/abstract.py +214 -0
  50. opentrons/drivers/flex_stacker/driver.py +768 -0
  51. opentrons/drivers/flex_stacker/errors.py +68 -0
  52. opentrons/drivers/flex_stacker/simulator.py +309 -0
  53. opentrons/drivers/flex_stacker/types.py +367 -0
  54. opentrons/drivers/flex_stacker/utils.py +19 -0
  55. opentrons/drivers/heater_shaker/__init__.py +5 -0
  56. opentrons/drivers/heater_shaker/abstract.py +76 -0
  57. opentrons/drivers/heater_shaker/driver.py +204 -0
  58. opentrons/drivers/heater_shaker/simulator.py +94 -0
  59. opentrons/drivers/mag_deck/__init__.py +6 -0
  60. opentrons/drivers/mag_deck/abstract.py +44 -0
  61. opentrons/drivers/mag_deck/driver.py +208 -0
  62. opentrons/drivers/mag_deck/simulator.py +63 -0
  63. opentrons/drivers/rpi_drivers/__init__.py +33 -0
  64. opentrons/drivers/rpi_drivers/dev_types.py +94 -0
  65. opentrons/drivers/rpi_drivers/gpio.py +282 -0
  66. opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
  67. opentrons/drivers/rpi_drivers/interfaces.py +15 -0
  68. opentrons/drivers/rpi_drivers/types.py +364 -0
  69. opentrons/drivers/rpi_drivers/usb.py +102 -0
  70. opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
  71. opentrons/drivers/serial_communication.py +151 -0
  72. opentrons/drivers/smoothie_drivers/__init__.py +4 -0
  73. opentrons/drivers/smoothie_drivers/connection.py +51 -0
  74. opentrons/drivers/smoothie_drivers/constants.py +121 -0
  75. opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
  76. opentrons/drivers/smoothie_drivers/errors.py +49 -0
  77. opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
  78. opentrons/drivers/smoothie_drivers/simulator.py +99 -0
  79. opentrons/drivers/smoothie_drivers/types.py +16 -0
  80. opentrons/drivers/temp_deck/__init__.py +10 -0
  81. opentrons/drivers/temp_deck/abstract.py +54 -0
  82. opentrons/drivers/temp_deck/driver.py +197 -0
  83. opentrons/drivers/temp_deck/simulator.py +57 -0
  84. opentrons/drivers/thermocycler/__init__.py +12 -0
  85. opentrons/drivers/thermocycler/abstract.py +99 -0
  86. opentrons/drivers/thermocycler/driver.py +395 -0
  87. opentrons/drivers/thermocycler/simulator.py +126 -0
  88. opentrons/drivers/types.py +107 -0
  89. opentrons/drivers/utils.py +222 -0
  90. opentrons/execute.py +742 -0
  91. opentrons/hardware_control/__init__.py +65 -0
  92. opentrons/hardware_control/__main__.py +77 -0
  93. opentrons/hardware_control/adapters.py +98 -0
  94. opentrons/hardware_control/api.py +1347 -0
  95. opentrons/hardware_control/backends/__init__.py +7 -0
  96. opentrons/hardware_control/backends/controller.py +400 -0
  97. opentrons/hardware_control/backends/errors.py +9 -0
  98. opentrons/hardware_control/backends/estop_state.py +164 -0
  99. opentrons/hardware_control/backends/flex_protocol.py +497 -0
  100. opentrons/hardware_control/backends/ot3controller.py +1930 -0
  101. opentrons/hardware_control/backends/ot3simulator.py +900 -0
  102. opentrons/hardware_control/backends/ot3utils.py +664 -0
  103. opentrons/hardware_control/backends/simulator.py +442 -0
  104. opentrons/hardware_control/backends/status_bar_state.py +240 -0
  105. opentrons/hardware_control/backends/subsystem_manager.py +431 -0
  106. opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
  107. opentrons/hardware_control/backends/types.py +14 -0
  108. opentrons/hardware_control/constants.py +6 -0
  109. opentrons/hardware_control/dev_types.py +125 -0
  110. opentrons/hardware_control/emulation/__init__.py +0 -0
  111. opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
  112. opentrons/hardware_control/emulation/app.py +56 -0
  113. opentrons/hardware_control/emulation/connection_handler.py +38 -0
  114. opentrons/hardware_control/emulation/heater_shaker.py +150 -0
  115. opentrons/hardware_control/emulation/magdeck.py +60 -0
  116. opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
  117. opentrons/hardware_control/emulation/module_server/client.py +78 -0
  118. opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
  119. opentrons/hardware_control/emulation/module_server/models.py +31 -0
  120. opentrons/hardware_control/emulation/module_server/server.py +110 -0
  121. opentrons/hardware_control/emulation/parser.py +74 -0
  122. opentrons/hardware_control/emulation/proxy.py +241 -0
  123. opentrons/hardware_control/emulation/run_emulator.py +68 -0
  124. opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
  125. opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
  126. opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
  127. opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
  128. opentrons/hardware_control/emulation/settings.py +119 -0
  129. opentrons/hardware_control/emulation/simulations.py +133 -0
  130. opentrons/hardware_control/emulation/smoothie.py +192 -0
  131. opentrons/hardware_control/emulation/tempdeck.py +69 -0
  132. opentrons/hardware_control/emulation/thermocycler.py +128 -0
  133. opentrons/hardware_control/emulation/types.py +10 -0
  134. opentrons/hardware_control/emulation/util.py +38 -0
  135. opentrons/hardware_control/errors.py +43 -0
  136. opentrons/hardware_control/execution_manager.py +164 -0
  137. opentrons/hardware_control/instruments/__init__.py +5 -0
  138. opentrons/hardware_control/instruments/instrument_abc.py +39 -0
  139. opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
  140. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
  141. opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
  142. opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
  143. opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
  144. opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
  145. opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
  146. opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
  147. opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
  148. opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
  149. opentrons/hardware_control/module_control.py +332 -0
  150. opentrons/hardware_control/modules/__init__.py +69 -0
  151. opentrons/hardware_control/modules/absorbance_reader.py +373 -0
  152. opentrons/hardware_control/modules/errors.py +7 -0
  153. opentrons/hardware_control/modules/flex_stacker.py +948 -0
  154. opentrons/hardware_control/modules/heater_shaker.py +426 -0
  155. opentrons/hardware_control/modules/lid_temp_status.py +35 -0
  156. opentrons/hardware_control/modules/magdeck.py +233 -0
  157. opentrons/hardware_control/modules/mod_abc.py +245 -0
  158. opentrons/hardware_control/modules/module_calibration.py +93 -0
  159. opentrons/hardware_control/modules/plate_temp_status.py +61 -0
  160. opentrons/hardware_control/modules/tempdeck.py +299 -0
  161. opentrons/hardware_control/modules/thermocycler.py +731 -0
  162. opentrons/hardware_control/modules/types.py +417 -0
  163. opentrons/hardware_control/modules/update.py +255 -0
  164. opentrons/hardware_control/modules/utils.py +73 -0
  165. opentrons/hardware_control/motion_utilities.py +318 -0
  166. opentrons/hardware_control/nozzle_manager.py +422 -0
  167. opentrons/hardware_control/ot3_calibration.py +1171 -0
  168. opentrons/hardware_control/ot3api.py +3227 -0
  169. opentrons/hardware_control/pause_manager.py +31 -0
  170. opentrons/hardware_control/poller.py +112 -0
  171. opentrons/hardware_control/protocols/__init__.py +106 -0
  172. opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
  173. opentrons/hardware_control/protocols/calibratable.py +45 -0
  174. opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
  175. opentrons/hardware_control/protocols/configurable.py +48 -0
  176. opentrons/hardware_control/protocols/event_sourcer.py +18 -0
  177. opentrons/hardware_control/protocols/execution_controllable.py +33 -0
  178. opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
  179. opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
  180. opentrons/hardware_control/protocols/gripper_controller.py +55 -0
  181. opentrons/hardware_control/protocols/hardware_manager.py +51 -0
  182. opentrons/hardware_control/protocols/identifiable.py +16 -0
  183. opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
  184. opentrons/hardware_control/protocols/liquid_handler.py +266 -0
  185. opentrons/hardware_control/protocols/module_provider.py +16 -0
  186. opentrons/hardware_control/protocols/motion_controller.py +243 -0
  187. opentrons/hardware_control/protocols/position_estimator.py +45 -0
  188. opentrons/hardware_control/protocols/simulatable.py +10 -0
  189. opentrons/hardware_control/protocols/stoppable.py +9 -0
  190. opentrons/hardware_control/protocols/types.py +27 -0
  191. opentrons/hardware_control/robot_calibration.py +224 -0
  192. opentrons/hardware_control/scripts/README.md +28 -0
  193. opentrons/hardware_control/scripts/__init__.py +1 -0
  194. opentrons/hardware_control/scripts/gripper_control.py +208 -0
  195. opentrons/hardware_control/scripts/ot3gripper +7 -0
  196. opentrons/hardware_control/scripts/ot3repl +7 -0
  197. opentrons/hardware_control/scripts/repl.py +187 -0
  198. opentrons/hardware_control/scripts/tc_control.py +97 -0
  199. opentrons/hardware_control/simulator_setup.py +260 -0
  200. opentrons/hardware_control/thread_manager.py +431 -0
  201. opentrons/hardware_control/threaded_async_lock.py +97 -0
  202. opentrons/hardware_control/types.py +792 -0
  203. opentrons/hardware_control/util.py +234 -0
  204. opentrons/legacy_broker.py +53 -0
  205. opentrons/legacy_commands/__init__.py +1 -0
  206. opentrons/legacy_commands/commands.py +483 -0
  207. opentrons/legacy_commands/helpers.py +153 -0
  208. opentrons/legacy_commands/module_commands.py +215 -0
  209. opentrons/legacy_commands/protocol_commands.py +54 -0
  210. opentrons/legacy_commands/publisher.py +155 -0
  211. opentrons/legacy_commands/robot_commands.py +51 -0
  212. opentrons/legacy_commands/types.py +1115 -0
  213. opentrons/motion_planning/__init__.py +32 -0
  214. opentrons/motion_planning/adjacent_slots_getters.py +168 -0
  215. opentrons/motion_planning/deck_conflict.py +396 -0
  216. opentrons/motion_planning/errors.py +35 -0
  217. opentrons/motion_planning/types.py +42 -0
  218. opentrons/motion_planning/waypoints.py +218 -0
  219. opentrons/ordered_set.py +138 -0
  220. opentrons/protocol_api/__init__.py +105 -0
  221. opentrons/protocol_api/_liquid.py +157 -0
  222. opentrons/protocol_api/_liquid_properties.py +814 -0
  223. opentrons/protocol_api/_nozzle_layout.py +31 -0
  224. opentrons/protocol_api/_parameter_context.py +300 -0
  225. opentrons/protocol_api/_parameters.py +31 -0
  226. opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
  227. opentrons/protocol_api/_types.py +43 -0
  228. opentrons/protocol_api/config.py +23 -0
  229. opentrons/protocol_api/core/__init__.py +23 -0
  230. opentrons/protocol_api/core/common.py +33 -0
  231. opentrons/protocol_api/core/core_map.py +74 -0
  232. opentrons/protocol_api/core/engine/__init__.py +22 -0
  233. opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
  234. opentrons/protocol_api/core/engine/deck_conflict.py +348 -0
  235. opentrons/protocol_api/core/engine/exceptions.py +19 -0
  236. opentrons/protocol_api/core/engine/instrument.py +2391 -0
  237. opentrons/protocol_api/core/engine/labware.py +238 -0
  238. opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
  239. opentrons/protocol_api/core/engine/module_core.py +1025 -0
  240. opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
  241. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
  242. opentrons/protocol_api/core/engine/point_calculations.py +64 -0
  243. opentrons/protocol_api/core/engine/protocol.py +1153 -0
  244. opentrons/protocol_api/core/engine/robot.py +139 -0
  245. opentrons/protocol_api/core/engine/stringify.py +74 -0
  246. opentrons/protocol_api/core/engine/transfer_components_executor.py +990 -0
  247. opentrons/protocol_api/core/engine/well.py +241 -0
  248. opentrons/protocol_api/core/instrument.py +459 -0
  249. opentrons/protocol_api/core/labware.py +151 -0
  250. opentrons/protocol_api/core/legacy/__init__.py +11 -0
  251. opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
  252. opentrons/protocol_api/core/legacy/deck.py +369 -0
  253. opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
  254. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
  255. opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
  256. opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
  257. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
  258. opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
  259. opentrons/protocol_api/core/legacy/load_info.py +67 -0
  260. opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
  261. opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
  262. opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
  263. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
  264. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
  265. opentrons/protocol_api/core/module.py +484 -0
  266. opentrons/protocol_api/core/protocol.py +311 -0
  267. opentrons/protocol_api/core/robot.py +51 -0
  268. opentrons/protocol_api/core/well.py +116 -0
  269. opentrons/protocol_api/core/well_grid.py +45 -0
  270. opentrons/protocol_api/create_protocol_context.py +177 -0
  271. opentrons/protocol_api/deck.py +223 -0
  272. opentrons/protocol_api/disposal_locations.py +244 -0
  273. opentrons/protocol_api/instrument_context.py +3212 -0
  274. opentrons/protocol_api/labware.py +1579 -0
  275. opentrons/protocol_api/module_contexts.py +1425 -0
  276. opentrons/protocol_api/module_validation_and_errors.py +61 -0
  277. opentrons/protocol_api/protocol_context.py +1688 -0
  278. opentrons/protocol_api/robot_context.py +303 -0
  279. opentrons/protocol_api/validation.py +761 -0
  280. opentrons/protocol_engine/__init__.py +155 -0
  281. opentrons/protocol_engine/actions/__init__.py +65 -0
  282. opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
  283. opentrons/protocol_engine/actions/action_handler.py +13 -0
  284. opentrons/protocol_engine/actions/actions.py +302 -0
  285. opentrons/protocol_engine/actions/get_state_update.py +38 -0
  286. opentrons/protocol_engine/clients/__init__.py +5 -0
  287. opentrons/protocol_engine/clients/sync_client.py +174 -0
  288. opentrons/protocol_engine/clients/transports.py +197 -0
  289. opentrons/protocol_engine/commands/__init__.py +757 -0
  290. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
  291. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
  292. opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
  293. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
  294. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
  295. opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
  296. opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
  297. opentrons/protocol_engine/commands/aspirate.py +244 -0
  298. opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
  299. opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
  300. opentrons/protocol_engine/commands/blow_out.py +146 -0
  301. opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
  302. opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
  303. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
  304. opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
  305. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
  306. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
  307. opentrons/protocol_engine/commands/command.py +308 -0
  308. opentrons/protocol_engine/commands/command_unions.py +974 -0
  309. opentrons/protocol_engine/commands/comment.py +57 -0
  310. opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
  311. opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
  312. opentrons/protocol_engine/commands/custom.py +67 -0
  313. opentrons/protocol_engine/commands/dispense.py +194 -0
  314. opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
  315. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  316. opentrons/protocol_engine/commands/drop_tip.py +232 -0
  317. opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
  318. opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
  319. opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
  320. opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
  321. opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
  322. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
  323. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
  324. opentrons/protocol_engine/commands/flex_stacker/store.py +326 -0
  325. opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
  326. opentrons/protocol_engine/commands/get_next_tip.py +134 -0
  327. opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
  328. opentrons/protocol_engine/commands/hash_command_params.py +38 -0
  329. opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
  330. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
  331. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
  332. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
  333. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
  334. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
  335. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
  336. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
  337. opentrons/protocol_engine/commands/home.py +100 -0
  338. opentrons/protocol_engine/commands/identify_module.py +86 -0
  339. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  340. opentrons/protocol_engine/commands/liquid_probe.py +464 -0
  341. opentrons/protocol_engine/commands/load_labware.py +210 -0
  342. opentrons/protocol_engine/commands/load_lid.py +154 -0
  343. opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
  344. opentrons/protocol_engine/commands/load_liquid.py +95 -0
  345. opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
  346. opentrons/protocol_engine/commands/load_module.py +223 -0
  347. opentrons/protocol_engine/commands/load_pipette.py +167 -0
  348. opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
  349. opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
  350. opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
  351. opentrons/protocol_engine/commands/move_labware.py +546 -0
  352. opentrons/protocol_engine/commands/move_relative.py +102 -0
  353. opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
  354. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
  355. opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
  356. opentrons/protocol_engine/commands/move_to_well.py +119 -0
  357. opentrons/protocol_engine/commands/movement_common.py +338 -0
  358. opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
  359. opentrons/protocol_engine/commands/pipetting_common.py +443 -0
  360. opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
  361. opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
  362. opentrons/protocol_engine/commands/reload_labware.py +90 -0
  363. opentrons/protocol_engine/commands/retract_axis.py +75 -0
  364. opentrons/protocol_engine/commands/robot/__init__.py +70 -0
  365. opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
  366. opentrons/protocol_engine/commands/robot/common.py +18 -0
  367. opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
  368. opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
  369. opentrons/protocol_engine/commands/robot/move_to.py +94 -0
  370. opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
  371. opentrons/protocol_engine/commands/save_position.py +109 -0
  372. opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
  373. opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
  374. opentrons/protocol_engine/commands/set_status_bar.py +89 -0
  375. opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
  376. opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
  377. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
  378. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
  379. opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
  380. opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
  381. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
  382. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
  383. opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
  384. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
  385. opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
  386. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
  387. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
  388. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
  389. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
  390. opentrons/protocol_engine/commands/touch_tip.py +189 -0
  391. opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
  392. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
  393. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
  394. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
  395. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
  396. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
  397. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
  398. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
  399. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
  400. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
  401. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
  402. opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
  403. opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
  404. opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
  405. opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
  406. opentrons/protocol_engine/create_protocol_engine.py +193 -0
  407. opentrons/protocol_engine/engine_support.py +28 -0
  408. opentrons/protocol_engine/error_recovery_policy.py +81 -0
  409. opentrons/protocol_engine/errors/__init__.py +191 -0
  410. opentrons/protocol_engine/errors/error_occurrence.py +182 -0
  411. opentrons/protocol_engine/errors/exceptions.py +1308 -0
  412. opentrons/protocol_engine/execution/__init__.py +50 -0
  413. opentrons/protocol_engine/execution/command_executor.py +216 -0
  414. opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
  415. opentrons/protocol_engine/execution/door_watcher.py +119 -0
  416. opentrons/protocol_engine/execution/equipment.py +819 -0
  417. opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
  418. opentrons/protocol_engine/execution/gantry_mover.py +686 -0
  419. opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
  420. opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
  421. opentrons/protocol_engine/execution/labware_movement.py +297 -0
  422. opentrons/protocol_engine/execution/movement.py +349 -0
  423. opentrons/protocol_engine/execution/pipetting.py +607 -0
  424. opentrons/protocol_engine/execution/queue_worker.py +86 -0
  425. opentrons/protocol_engine/execution/rail_lights.py +25 -0
  426. opentrons/protocol_engine/execution/run_control.py +33 -0
  427. opentrons/protocol_engine/execution/status_bar.py +34 -0
  428. opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
  429. opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
  430. opentrons/protocol_engine/execution/tip_handler.py +550 -0
  431. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  432. opentrons/protocol_engine/notes/__init__.py +17 -0
  433. opentrons/protocol_engine/notes/notes.py +59 -0
  434. opentrons/protocol_engine/plugins.py +104 -0
  435. opentrons/protocol_engine/protocol_engine.py +683 -0
  436. opentrons/protocol_engine/resources/__init__.py +26 -0
  437. opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
  438. opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
  439. opentrons/protocol_engine/resources/file_provider.py +161 -0
  440. opentrons/protocol_engine/resources/fixture_validation.py +58 -0
  441. opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
  442. opentrons/protocol_engine/resources/labware_validation.py +73 -0
  443. opentrons/protocol_engine/resources/model_utils.py +32 -0
  444. opentrons/protocol_engine/resources/module_data_provider.py +44 -0
  445. opentrons/protocol_engine/resources/ot3_validation.py +21 -0
  446. opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
  447. opentrons/protocol_engine/slot_standardization.py +128 -0
  448. opentrons/protocol_engine/state/__init__.py +1 -0
  449. opentrons/protocol_engine/state/_abstract_store.py +27 -0
  450. opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
  451. opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
  452. opentrons/protocol_engine/state/_move_types.py +83 -0
  453. opentrons/protocol_engine/state/_well_math.py +193 -0
  454. opentrons/protocol_engine/state/addressable_areas.py +699 -0
  455. opentrons/protocol_engine/state/command_history.py +309 -0
  456. opentrons/protocol_engine/state/commands.py +1158 -0
  457. opentrons/protocol_engine/state/config.py +39 -0
  458. opentrons/protocol_engine/state/files.py +57 -0
  459. opentrons/protocol_engine/state/fluid_stack.py +138 -0
  460. opentrons/protocol_engine/state/geometry.py +2359 -0
  461. opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
  462. opentrons/protocol_engine/state/labware.py +1459 -0
  463. opentrons/protocol_engine/state/liquid_classes.py +82 -0
  464. opentrons/protocol_engine/state/liquids.py +73 -0
  465. opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
  466. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
  467. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
  468. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
  469. opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
  470. opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
  471. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
  472. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
  473. opentrons/protocol_engine/state/modules.py +1500 -0
  474. opentrons/protocol_engine/state/motion.py +373 -0
  475. opentrons/protocol_engine/state/pipettes.py +905 -0
  476. opentrons/protocol_engine/state/state.py +421 -0
  477. opentrons/protocol_engine/state/state_summary.py +36 -0
  478. opentrons/protocol_engine/state/tips.py +420 -0
  479. opentrons/protocol_engine/state/update_types.py +904 -0
  480. opentrons/protocol_engine/state/wells.py +290 -0
  481. opentrons/protocol_engine/types/__init__.py +308 -0
  482. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  483. opentrons/protocol_engine/types/command_annotations.py +53 -0
  484. opentrons/protocol_engine/types/deck_configuration.py +81 -0
  485. opentrons/protocol_engine/types/execution.py +96 -0
  486. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  487. opentrons/protocol_engine/types/instrument.py +47 -0
  488. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  489. opentrons/protocol_engine/types/labware.py +131 -0
  490. opentrons/protocol_engine/types/labware_movement.py +22 -0
  491. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  492. opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
  493. opentrons/protocol_engine/types/liquid.py +40 -0
  494. opentrons/protocol_engine/types/liquid_class.py +59 -0
  495. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  496. opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
  497. opentrons/protocol_engine/types/location.py +194 -0
  498. opentrons/protocol_engine/types/module.py +303 -0
  499. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  500. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  501. opentrons/protocol_engine/types/tip.py +18 -0
  502. opentrons/protocol_engine/types/util.py +21 -0
  503. opentrons/protocol_engine/types/well_position.py +124 -0
  504. opentrons/protocol_reader/__init__.py +37 -0
  505. opentrons/protocol_reader/extract_labware_definitions.py +66 -0
  506. opentrons/protocol_reader/file_format_validator.py +152 -0
  507. opentrons/protocol_reader/file_hasher.py +27 -0
  508. opentrons/protocol_reader/file_identifier.py +284 -0
  509. opentrons/protocol_reader/file_reader_writer.py +90 -0
  510. opentrons/protocol_reader/input_file.py +16 -0
  511. opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
  512. opentrons/protocol_reader/protocol_reader.py +188 -0
  513. opentrons/protocol_reader/protocol_source.py +124 -0
  514. opentrons/protocol_reader/role_analyzer.py +86 -0
  515. opentrons/protocol_runner/__init__.py +26 -0
  516. opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
  517. opentrons/protocol_runner/json_file_reader.py +55 -0
  518. opentrons/protocol_runner/json_translator.py +314 -0
  519. opentrons/protocol_runner/legacy_command_mapper.py +848 -0
  520. opentrons/protocol_runner/legacy_context_plugin.py +116 -0
  521. opentrons/protocol_runner/protocol_runner.py +530 -0
  522. opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
  523. opentrons/protocol_runner/run_orchestrator.py +496 -0
  524. opentrons/protocol_runner/task_queue.py +95 -0
  525. opentrons/protocols/__init__.py +6 -0
  526. opentrons/protocols/advanced_control/__init__.py +0 -0
  527. opentrons/protocols/advanced_control/common.py +38 -0
  528. opentrons/protocols/advanced_control/mix.py +60 -0
  529. opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
  530. opentrons/protocols/advanced_control/transfers/common.py +180 -0
  531. opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
  532. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
  533. opentrons/protocols/api_support/__init__.py +0 -0
  534. opentrons/protocols/api_support/constants.py +8 -0
  535. opentrons/protocols/api_support/deck_type.py +110 -0
  536. opentrons/protocols/api_support/definitions.py +18 -0
  537. opentrons/protocols/api_support/instrument.py +151 -0
  538. opentrons/protocols/api_support/labware_like.py +233 -0
  539. opentrons/protocols/api_support/tip_tracker.py +175 -0
  540. opentrons/protocols/api_support/types.py +32 -0
  541. opentrons/protocols/api_support/util.py +403 -0
  542. opentrons/protocols/bundle.py +89 -0
  543. opentrons/protocols/duration/__init__.py +4 -0
  544. opentrons/protocols/duration/errors.py +5 -0
  545. opentrons/protocols/duration/estimator.py +628 -0
  546. opentrons/protocols/execution/__init__.py +0 -0
  547. opentrons/protocols/execution/dev_types.py +181 -0
  548. opentrons/protocols/execution/errors.py +40 -0
  549. opentrons/protocols/execution/execute.py +84 -0
  550. opentrons/protocols/execution/execute_json_v3.py +275 -0
  551. opentrons/protocols/execution/execute_json_v4.py +359 -0
  552. opentrons/protocols/execution/execute_json_v5.py +28 -0
  553. opentrons/protocols/execution/execute_python.py +169 -0
  554. opentrons/protocols/execution/json_dispatchers.py +87 -0
  555. opentrons/protocols/execution/types.py +7 -0
  556. opentrons/protocols/geometry/__init__.py +0 -0
  557. opentrons/protocols/geometry/planning.py +297 -0
  558. opentrons/protocols/labware.py +312 -0
  559. opentrons/protocols/models/__init__.py +0 -0
  560. opentrons/protocols/models/json_protocol.py +679 -0
  561. opentrons/protocols/parameters/__init__.py +0 -0
  562. opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
  563. opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
  564. opentrons/protocols/parameters/exceptions.py +34 -0
  565. opentrons/protocols/parameters/parameter_definition.py +272 -0
  566. opentrons/protocols/parameters/types.py +17 -0
  567. opentrons/protocols/parameters/validation.py +267 -0
  568. opentrons/protocols/parse.py +671 -0
  569. opentrons/protocols/types.py +159 -0
  570. opentrons/py.typed +0 -0
  571. opentrons/resources/scripts/lpc21isp +0 -0
  572. opentrons/resources/smoothie-edge-8414642.hex +23010 -0
  573. opentrons/simulate.py +1065 -0
  574. opentrons/system/__init__.py +6 -0
  575. opentrons/system/camera.py +51 -0
  576. opentrons/system/log_control.py +59 -0
  577. opentrons/system/nmcli.py +856 -0
  578. opentrons/system/resin.py +24 -0
  579. opentrons/system/smoothie_update.py +15 -0
  580. opentrons/system/wifi.py +204 -0
  581. opentrons/tools/__init__.py +0 -0
  582. opentrons/tools/args_handler.py +22 -0
  583. opentrons/tools/write_pipette_memory.py +157 -0
  584. opentrons/types.py +618 -0
  585. opentrons/util/__init__.py +1 -0
  586. opentrons/util/async_helpers.py +166 -0
  587. opentrons/util/broker.py +84 -0
  588. opentrons/util/change_notifier.py +47 -0
  589. opentrons/util/entrypoint_util.py +278 -0
  590. opentrons/util/get_union_elements.py +26 -0
  591. opentrons/util/helpers.py +6 -0
  592. opentrons/util/linal.py +178 -0
  593. opentrons/util/logging_config.py +265 -0
  594. opentrons/util/logging_queue_handler.py +61 -0
  595. opentrons/util/performance_helpers.py +157 -0
  596. opentrons-8.6.0a1.dist-info/METADATA +37 -0
  597. opentrons-8.6.0a1.dist-info/RECORD +600 -0
  598. opentrons-8.6.0a1.dist-info/WHEEL +4 -0
  599. opentrons-8.6.0a1.dist-info/entry_points.txt +3 -0
  600. opentrons-8.6.0a1.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,231 @@
1
+ """Utility functions for transfer_liquid, consolidate_liquid and distribute_liquid"""
2
+ from __future__ import annotations
3
+
4
+ from typing import Literal, Sequence, List, Optional, TYPE_CHECKING
5
+ from dataclasses import dataclass
6
+
7
+ from opentrons.protocol_engine.errors import (
8
+ LiquidHeightUnknownError,
9
+ IncompleteLabwareDefinitionError,
10
+ )
11
+ from opentrons.protocol_engine.state._well_math import (
12
+ wells_covered_by_pipette_configuration,
13
+ )
14
+ from opentrons.types import NozzleMapInterface, NozzleConfigurationType
15
+
16
+ if TYPE_CHECKING:
17
+ from logging import Logger
18
+ from opentrons.types import Location
19
+ from opentrons.protocol_api.core.engine import WellCore
20
+ from opentrons.protocol_api.labware import Well, Labware
21
+
22
+
23
+ @dataclass
24
+ class LocationCheckDescriptors:
25
+ location_type: Literal["submerge start", "retract end"]
26
+ pipetting_action: Literal["aspirate", "dispense"]
27
+
28
+
29
+ def raise_if_location_inside_liquid(
30
+ location: Location,
31
+ well_core: WellCore,
32
+ location_check_descriptors: LocationCheckDescriptors,
33
+ logger: Logger,
34
+ ) -> None:
35
+ """Raise an error if the location in question would be inside the liquid.
36
+
37
+ This checker will raise an error if we can find the liquid height
38
+ AND the location in question is below this height.
39
+
40
+ If we can't find the liquid height, then we simply log the details and no error is raised.
41
+ """
42
+ try:
43
+ liquid_height_from_bottom = well_core.current_liquid_height()
44
+ except (IncompleteLabwareDefinitionError, LiquidHeightUnknownError):
45
+ # IncompleteLabwareDefinitionError is raised when there's no inner geometry
46
+ # defined for the well. So, we can't find the liquid height even if liquid volume is known.
47
+ # LiquidHeightUnknownError is raised when we don't have liquid volume info
48
+ # and no probing has been done either.
49
+ liquid_height_from_bottom = None
50
+ if isinstance(liquid_height_from_bottom, (int, float)):
51
+ if liquid_height_from_bottom + well_core.get_bottom(0).z > location.point.z:
52
+ raise RuntimeError(
53
+ f"{location_check_descriptors.location_type.capitalize()} location {location} is"
54
+ f" inside the liquid in well {well_core.get_display_name()} when it should be outside"
55
+ f"(above) the liquid."
56
+ )
57
+ else:
58
+ # We could raise an error here but that would restrict the use of
59
+ # liquid classes-based transfer to only when LPD is enabled or when liquids are
60
+ # loaded in protocols using `load_liquid`. This can be quite restrictive
61
+ # so we will not raise but just log the details.
62
+ logger.info(
63
+ f"Could not verify height of liquid in well {well_core.get_display_name()}, either"
64
+ f" because the liquid in this well has not been probed or"
65
+ f" liquid was not loaded in this well using `load_liquid` or"
66
+ f" inner geometry is not available for the target well."
67
+ f" Proceeding without verifying if {location_check_descriptors.location_type}"
68
+ f" location is outside the liquid."
69
+ )
70
+
71
+
72
+ def group_wells_for_multi_channel_transfer(
73
+ targets: Sequence[Well],
74
+ nozzle_map: NozzleMapInterface,
75
+ target_name: Literal["source", "destination"],
76
+ ) -> List[Well]:
77
+ """Takes a list of wells and a nozzle map and returns a list of target wells to address every well given
78
+
79
+ This currently only supports 8-tip columns, 12-tip rows and full 96-channel configurations,
80
+ and only is used for 96 and 384 well plates. This assumes the wells are being given in a
81
+ contiguous order (or every other for 384), and will raise if a well is found that does not overlap
82
+ with the first target well given for a sequence, or if not all wells are given for that sequence.
83
+ """
84
+ configuration = nozzle_map.configuration
85
+ active_nozzles = nozzle_map.tip_count
86
+
87
+ if (
88
+ (
89
+ (
90
+ configuration == NozzleConfigurationType.COLUMN
91
+ or configuration == NozzleConfigurationType.FULL
92
+ )
93
+ and active_nozzles == 8
94
+ )
95
+ or (configuration == NozzleConfigurationType.ROW and active_nozzles == 12)
96
+ or active_nozzles == 96
97
+ ):
98
+ return _group_wells_for_nozzle_configuration(
99
+ list(targets), nozzle_map, target_name
100
+ )
101
+ else:
102
+ raise ValueError(
103
+ "Unsupported nozzle configuration for well grouping. Set group_wells to False"
104
+ " to only target wells with the primary nozzle for this configuration."
105
+ )
106
+
107
+
108
+ def _group_wells_for_nozzle_configuration( # noqa: C901
109
+ targets: List[Well],
110
+ nozzle_map: NozzleMapInterface,
111
+ target_name: Literal["source", "destination"],
112
+ ) -> List[Well]:
113
+ """Groups wells together for a column, row, or full 96 configuration and returns a reduced list of target wells."""
114
+ grouped_wells = []
115
+ active_wells_covered: List[str] = []
116
+ active_labware: Optional[Labware] = None
117
+ alternate_384_well_coverage_count = 0
118
+ labware_format: Optional[str] = None
119
+
120
+ # We are assuming the wells are ordered A1, B1, C1... A2, B2, C2..., for columns and
121
+ # A1, A2, A3... B1, B2, B3 for rows. So if the active nozzle is on H row/12 column,
122
+ # reverse the list so the correct primary nozzle is chosen
123
+ reverse_lookup = (
124
+ nozzle_map.starting_nozzle == "H12"
125
+ or (
126
+ nozzle_map.configuration == NozzleConfigurationType.COLUMN
127
+ and nozzle_map.starting_nozzle == "H1"
128
+ )
129
+ or (
130
+ nozzle_map.configuration == NozzleConfigurationType.ROW
131
+ and nozzle_map.starting_nozzle == "A12"
132
+ )
133
+ )
134
+ if reverse_lookup:
135
+ targets.reverse()
136
+
137
+ for well in targets:
138
+ # If we have wells that are covered by the pipette's nozzles while primary nozzle is over
139
+ # a target well that aren't accounted for, check if the current well is in that list
140
+ if active_wells_covered:
141
+ if well.parent != active_labware:
142
+ raise ValueError(
143
+ f"Could not group {target_name} wells to match pipette's nozzle configuration. Ensure that the"
144
+ " wells are ordered correctly (e.g. rows() for a row layout or columns() for a column layout), or"
145
+ " set group_wells to False to only target wells with the primary nozzle."
146
+ )
147
+
148
+ if well.well_name in active_wells_covered:
149
+ active_wells_covered.remove(well.well_name)
150
+ # If it's a 384 well plate, contiguous wells are not covered by the pipette targeting the
151
+ # initial target well. To support these kinds of transfers given a list of contiguous wells,
152
+ # allow another target well (or up to 4 total for a full 96-tip config) and add those wells
153
+ # to the list of covered wells
154
+ elif labware_format == "384Standard" and (
155
+ alternate_384_well_coverage_count == 0
156
+ or (
157
+ nozzle_map.tip_count == 96 and alternate_384_well_coverage_count < 3
158
+ )
159
+ ):
160
+ active_wells_covered.extend(
161
+ list(
162
+ wells_covered_by_pipette_configuration(
163
+ nozzle_map, # type: ignore[arg-type]
164
+ well.well_name,
165
+ labware_wells_by_column=[
166
+ [labware_well.well_name for labware_well in column]
167
+ for column in well.parent.columns()
168
+ ],
169
+ )
170
+ )
171
+ )
172
+ active_wells_covered.remove(well.well_name)
173
+ grouped_wells.append(well)
174
+ alternate_384_well_coverage_count += 1
175
+ else:
176
+ raise ValueError(
177
+ f"Could not group {target_name} wells to match pipette's nozzle configuration. Ensure that the"
178
+ " wells are ordered correctly (e.g. rows() for a row layout or columns() for a column layout), or"
179
+ " set group_wells to False to only target wells with the primary nozzle."
180
+ )
181
+ # If we have no active wells covered to account for, add a new target well and list of covered wells to check
182
+ else:
183
+ # If the labware is not a 96 or 384 well plate, add this well to the final result and move on to the next
184
+ labware_format = well.parent.parameters["format"]
185
+ if labware_format != "96Standard" and labware_format != "384Standard":
186
+ grouped_wells.append(well)
187
+ continue
188
+
189
+ active_wells_covered = list(
190
+ wells_covered_by_pipette_configuration(
191
+ nozzle_map, # type: ignore[arg-type]
192
+ well.well_name,
193
+ labware_wells_by_column=[
194
+ [labware_well.well_name for labware_well in column]
195
+ for column in well.parent.columns()
196
+ ],
197
+ )
198
+ )
199
+ active_wells_covered.remove(well.well_name)
200
+ grouped_wells.append(well)
201
+ active_labware = well.parent
202
+ alternate_384_well_coverage_count = 0
203
+
204
+ if active_wells_covered:
205
+ raise ValueError(
206
+ f"Pipette will access {target_name} wells not provided in the liquid handling command."
207
+ f" Set group_wells to False or include these wells: {active_wells_covered}"
208
+ )
209
+
210
+ # If we reversed the lookup of wells, reverse the grouped wells we will return
211
+ if reverse_lookup:
212
+ grouped_wells.reverse()
213
+
214
+ return grouped_wells
215
+
216
+
217
+ def check_current_volume_before_dispensing(
218
+ current_volume: float,
219
+ dispense_volume: float,
220
+ ) -> None:
221
+ """Check if the current volume is valid for dispensing the dispense volume."""
222
+ if current_volume < dispense_volume:
223
+ # Although this should never happen, we can get into an unexpected state
224
+ # following error recovery and not have the expected amount of liquid in the tip.
225
+ # If this happens, we want to raise a useful error so the user can understand
226
+ # the cause of the problem. If we don't make this check for current volume,
227
+ # an unhelpful error might get raised when a '..byVolume' property encounters
228
+ # a negative volume (current_volume - dispense_volume).
229
+ raise RuntimeError(
230
+ f"Cannot dispense {dispense_volume}uL when the tip has only {current_volume}uL."
231
+ )
File without changes
@@ -0,0 +1,8 @@
1
+ from pathlib import Path
2
+
3
+ from opentrons.config import get_opentrons_path
4
+
5
+ OPENTRONS_NAMESPACE = "opentrons"
6
+ CUSTOM_NAMESPACE = "custom_beta"
7
+ STANDARD_DEFS_PATH = Path("labware/definitions")
8
+ USER_DEFS_PATH = get_opentrons_path("labware_user_definitions_dir_v2")
@@ -0,0 +1,110 @@
1
+ from typing import Sequence, Dict, Optional, Any
2
+
3
+ from opentrons_shared_data.robot.types import RobotType
4
+ from opentrons_shared_data.errors import ErrorCodes
5
+ from opentrons_shared_data.errors.exceptions import EnumeratedError
6
+
7
+ from opentrons.config import feature_flags
8
+
9
+ from opentrons.protocol_reader.protocol_source import (
10
+ ProtocolConfig,
11
+ PythonProtocolConfig,
12
+ JsonProtocolConfig,
13
+ )
14
+ from opentrons.protocols.api_support.types import APIVersion
15
+
16
+
17
+ # TODO(mm, 2023-05-10): Deduplicate these constants with
18
+ # opentrons.protocol_engine.types.DeckType and consider moving to shared-data.
19
+ SHORT_TRASH_DECK = "ot2_short_trash"
20
+ STANDARD_OT2_DECK = "ot2_standard"
21
+ STANDARD_OT3_DECK = "ot3_standard"
22
+
23
+
24
+ LOAD_FIXED_TRASH_GATE_VERSION_PYTHON = APIVersion(2, 15)
25
+ LOAD_FIXED_TRASH_GATE_VERSION_JSON = 7
26
+
27
+
28
+ class NoTrashDefinedError(EnumeratedError):
29
+ """
30
+ Error raised when a protocol attempts to automatically access a trash bin without one being loaded.
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ message: Optional[str] = None,
36
+ detail: Optional[Dict[str, Any]] = None,
37
+ wrapping: Optional[Sequence[EnumeratedError]] = None,
38
+ ) -> None:
39
+ """Build a ProtocolEngineError."""
40
+ super().__init__(
41
+ code=ErrorCodes.GENERAL_ERROR,
42
+ message=message,
43
+ detail=detail,
44
+ wrapping=wrapping,
45
+ )
46
+
47
+
48
+ def should_load_fixed_trash_labware_for_python_protocol(
49
+ api_version: APIVersion,
50
+ ) -> bool:
51
+ """Whether to automatically load the fixed trash as a labware for a Python protocol at protocol start."""
52
+ return api_version <= LOAD_FIXED_TRASH_GATE_VERSION_PYTHON
53
+
54
+
55
+ def should_load_fixed_trash_area_for_python_protocol(
56
+ api_version: APIVersion, robot_type: RobotType
57
+ ) -> bool:
58
+ """Whether to automatically load the fixed trash addressable area for OT-2 protocols on 2.16 and above."""
59
+ return (
60
+ api_version > LOAD_FIXED_TRASH_GATE_VERSION_PYTHON
61
+ and robot_type == "OT-2 Standard"
62
+ )
63
+
64
+
65
+ def should_load_fixed_trash(protocol_config: ProtocolConfig) -> bool:
66
+ """Decide whether to automatically load fixed trash labware on the deck based on version."""
67
+ load_fixed_trash = False
68
+ if isinstance(protocol_config, PythonProtocolConfig):
69
+ return should_load_fixed_trash_labware_for_python_protocol(
70
+ protocol_config.api_version
71
+ )
72
+ # TODO(jbl 2023-10-27), when schema v8 is out, use a new deck version field to support fixed trash protocols
73
+ elif isinstance(protocol_config, JsonProtocolConfig):
74
+ load_fixed_trash = (
75
+ protocol_config.schema_version <= LOAD_FIXED_TRASH_GATE_VERSION_JSON
76
+ )
77
+
78
+ return load_fixed_trash
79
+
80
+
81
+ def guess_from_global_config() -> str:
82
+ """Return the deck type that the host device physically has.
83
+
84
+ This only makes sense when the software is running on a real robot.
85
+
86
+ When simulating or analyzing a protocol, especially off-robot, don't use this, because it may
87
+ not match the protocol's declared robot type. Use `for_analysis` instead.
88
+ """
89
+ if feature_flags.enable_ot3_hardware_controller():
90
+ return STANDARD_OT3_DECK
91
+ elif feature_flags.short_fixed_trash():
92
+ return SHORT_TRASH_DECK
93
+ else:
94
+ return STANDARD_OT2_DECK
95
+
96
+
97
+ def for_simulation(robot_type: RobotType) -> str:
98
+ """Return the deck type that should be used for simulating and analyzing a protocol.
99
+
100
+ Params:
101
+ robot_type: The robot type that the protocol is meant to run on.
102
+ """
103
+ if robot_type == "OT-2 Standard":
104
+ # OT-2 protocols don't have a way of defining whether they're meant to run on a short-trash
105
+ # or standard deck. So when we're simulating an OT-2 protocol, we need to make an
106
+ # arbitrary choice for which deck type to use.
107
+ return STANDARD_OT2_DECK
108
+ elif robot_type == "OT-3 Standard":
109
+ # OT-3s currently only have a single deck type.
110
+ return STANDARD_OT3_DECK
@@ -0,0 +1,18 @@
1
+ from .types import APIVersion
2
+
3
+ MAX_SUPPORTED_VERSION = APIVersion(2, 25)
4
+ """The maximum supported protocol API version in this release."""
5
+
6
+ MIN_SUPPORTED_VERSION = APIVersion(2, 0)
7
+ """The minimum supported protocol API version in this release, across all robot types."""
8
+
9
+ MIN_SUPPORTED_VERSION_FOR_FLEX = APIVersion(2, 15)
10
+ """The minimum protocol API version supported by the Opentrons Flex.
11
+
12
+ It's an infrastructural requirement for this to be at least newer than 2.14. Before then,
13
+ the protocol API is backed by the legacy non-Protocol-engine backend, which is not prepared to
14
+ handle anything but OT-2s.
15
+
16
+ The additional bump to 2.15 is because that's what we tested on, and because it adds all the
17
+ Flex-specific features.
18
+ """
@@ -0,0 +1,151 @@
1
+ import logging
2
+ from typing import Optional, Any
3
+
4
+ from opentrons_shared_data.labware.types import (
5
+ LabwareDefinition2 as LabwareDefinition2Dict,
6
+ )
7
+
8
+ from opentrons import types
9
+ from opentrons.calibration_storage.helpers import uri_from_definition
10
+ from opentrons.calibration_storage.types import TipLengthCalNotFound
11
+ from opentrons.hardware_control.dev_types import PipetteDict
12
+
13
+ # TODO (lc 09-26-2022) We should conditionally import ot2 or ot3 calibration
14
+ from opentrons.hardware_control.instruments.ot2 import (
15
+ instrument_calibration as instr_cal,
16
+ )
17
+ from opentrons.protocol_api.labware import Labware
18
+ from opentrons.protocols.api_support.types import APIVersion
19
+ from opentrons_shared_data.protocol.types import (
20
+ LiquidHandlingCommand,
21
+ BlowoutLocation,
22
+ )
23
+
24
+
25
+ def validate_blowout_location(
26
+ api_version: APIVersion,
27
+ liquid_handling_command: LiquidHandlingCommand,
28
+ blowout_location: Optional[Any],
29
+ ) -> None:
30
+ """Validate the blowout location."""
31
+ if blowout_location and api_version < APIVersion(2, 8):
32
+ raise ValueError(
33
+ "Cannot specify blowout location when using api"
34
+ + " version below 2.8, current version is {api_version}".format(
35
+ api_version=api_version
36
+ )
37
+ )
38
+
39
+ elif liquid_handling_command == "consolidate" and blowout_location == "source well":
40
+ raise ValueError("blowout location for consolidate cannot be source well")
41
+ elif (
42
+ liquid_handling_command == "distribute"
43
+ and blowout_location == "destination well"
44
+ ):
45
+ raise ValueError("blowout location for distribute cannot be destination well")
46
+ elif (
47
+ liquid_handling_command == "transfer"
48
+ and blowout_location
49
+ and blowout_location not in [location.value for location in BlowoutLocation]
50
+ ):
51
+ raise ValueError(
52
+ "blowout location should be either 'source well', "
53
+ + " 'destination well', or 'trash'"
54
+ + f" but it is {blowout_location}"
55
+ )
56
+
57
+
58
+ def tip_length_for(
59
+ pipette: PipetteDict, tip_rack_definition: LabwareDefinition2Dict
60
+ ) -> float:
61
+ """Get the tip length, including overlap, for a tip from this rack"""
62
+ try:
63
+ return instr_cal.load_tip_length_for_pipette(
64
+ pipette["pipette_id"], tip_rack_definition
65
+ ).tip_length
66
+ except TipLengthCalNotFound:
67
+ tip_overlap = pipette["tip_overlap"].get(
68
+ uri_from_definition(tip_rack_definition),
69
+ pipette["tip_overlap"]["default"],
70
+ )
71
+ tip_length = tip_rack_definition["parameters"]["tipLength"]
72
+ return tip_length - tip_overlap
73
+
74
+
75
+ VALID_PIP_TIPRACK_VOL = {
76
+ "FLEX": {"p50": [50], "p200": [50, 200], "p1000": [50, 200, 1000]},
77
+ "OT2": {
78
+ "p10": [10, 20],
79
+ "p20": [10, 20],
80
+ "p50": [50, 200, 300],
81
+ "p300": [200, 300],
82
+ "p1000": [1000],
83
+ },
84
+ }
85
+
86
+
87
+ def validate_tiprack(
88
+ instrument_name: str, tip_rack: Labware, log: logging.Logger
89
+ ) -> None:
90
+ """Validate a tiprack logging a warning message."""
91
+ if not tip_rack.is_tiprack:
92
+ raise ValueError(f"Labware {tip_rack.load_name} is not a tip rack.")
93
+
94
+ # TODO AA 2020-06-24 - we should instead add the acceptable Opentrons
95
+ # tipracks to the pipette as a refactor
96
+ if tip_rack.uri.startswith("opentrons/"):
97
+ tiprack_vol = tip_rack.wells()[0].max_volume
98
+ instr_metadata = instrument_name.split("_")
99
+ gen_lookup = (
100
+ "FLEX" if ("flex" in instr_metadata or "96" in instr_metadata) else "OT2"
101
+ )
102
+
103
+ # TODO (spp, 2025-01-30): do what AA's note above says or at least,
104
+ # fetch the 'pip_type' below from the 'model' field in pipette definitions
105
+ # so that we don't have to figure it out from pipette names
106
+ if instrument_name.split("_")[0] == "flex":
107
+ # Flex's API load names have the format 'flex_1channel_1000'
108
+ # From API v2.23 on, this is the name returned by InstrumentContext.name
109
+ pip_type = "p" + instrument_name.split("_")[2]
110
+ else:
111
+ # Until API v2.23, InstrumentContext.name returned the engine-specific names
112
+ # of Flex pipettes. These names, as well as OT2 pipette names,
113
+ # have the format- 'p1000_single_gen2' or 'p1000_single_flex'
114
+ pip_type = instrument_name.split("_")[0]
115
+ valid_vols = VALID_PIP_TIPRACK_VOL[gen_lookup][pip_type]
116
+ if tiprack_vol not in valid_vols:
117
+ log.warning(
118
+ f"The pipette {instrument_name} and its tip rack {tip_rack.load_name}"
119
+ " appear to be mismatched. Please check your protocol."
120
+ )
121
+
122
+
123
+ def validate_takes_liquid(
124
+ location: types.Location, reject_module: bool, reject_adapter: bool
125
+ ) -> None:
126
+ """Validate that a location is a valid liquid handling target.
127
+
128
+ Args:
129
+ location: target location.
130
+ reject_module: if set to True, disallow liquid handling directly to module
131
+ reject_adapter: if set to True, check that labware is not an adapter
132
+
133
+ Raises:
134
+ ValueError: the given location is not a valid liquid handling target.
135
+ """
136
+ labware = None
137
+
138
+ if location.labware.is_labware:
139
+ labware = location.labware.as_labware()
140
+
141
+ if location.labware.is_well:
142
+ labware = location.labware.as_well().parent
143
+
144
+ if location.labware.is_module and reject_module:
145
+ raise ValueError("Cannot aspirate/dispense directly to a module")
146
+
147
+ if labware is not None and labware.is_tiprack:
148
+ raise ValueError("Cannot aspirate/dispense to a tip rack")
149
+
150
+ if reject_adapter and (labware is not None and labware.is_adapter):
151
+ raise ValueError("Cannot aspirate/dispense to an adapter")