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.
- opentrons/__init__.py +150 -0
- opentrons/_version.py +34 -0
- opentrons/calibration_storage/__init__.py +54 -0
- opentrons/calibration_storage/deck_configuration.py +62 -0
- opentrons/calibration_storage/encoder_decoder.py +31 -0
- opentrons/calibration_storage/file_operators.py +142 -0
- opentrons/calibration_storage/helpers.py +103 -0
- opentrons/calibration_storage/ot2/__init__.py +34 -0
- opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
- opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
- opentrons/calibration_storage/ot2/models/__init__.py +0 -0
- opentrons/calibration_storage/ot2/models/v1.py +149 -0
- opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
- opentrons/calibration_storage/ot2/tip_length.py +281 -0
- opentrons/calibration_storage/ot3/__init__.py +31 -0
- opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
- opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
- opentrons/calibration_storage/ot3/models/__init__.py +0 -0
- opentrons/calibration_storage/ot3/models/v1.py +122 -0
- opentrons/calibration_storage/ot3/module_offset.py +138 -0
- opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
- opentrons/calibration_storage/types.py +45 -0
- opentrons/cli/__init__.py +21 -0
- opentrons/cli/__main__.py +5 -0
- opentrons/cli/analyze.py +501 -0
- opentrons/config/__init__.py +631 -0
- opentrons/config/advanced_settings.py +871 -0
- opentrons/config/defaults_ot2.py +214 -0
- opentrons/config/defaults_ot3.py +499 -0
- opentrons/config/feature_flags.py +86 -0
- opentrons/config/gripper_config.py +55 -0
- opentrons/config/reset.py +203 -0
- opentrons/config/robot_configs.py +187 -0
- opentrons/config/types.py +183 -0
- opentrons/drivers/__init__.py +0 -0
- opentrons/drivers/absorbance_reader/__init__.py +11 -0
- opentrons/drivers/absorbance_reader/abstract.py +72 -0
- opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
- opentrons/drivers/absorbance_reader/driver.py +81 -0
- opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
- opentrons/drivers/absorbance_reader/simulator.py +84 -0
- opentrons/drivers/asyncio/__init__.py +0 -0
- opentrons/drivers/asyncio/communication/__init__.py +22 -0
- opentrons/drivers/asyncio/communication/async_serial.py +183 -0
- opentrons/drivers/asyncio/communication/errors.py +88 -0
- opentrons/drivers/asyncio/communication/serial_connection.py +552 -0
- opentrons/drivers/command_builder.py +102 -0
- opentrons/drivers/flex_stacker/__init__.py +13 -0
- opentrons/drivers/flex_stacker/abstract.py +214 -0
- opentrons/drivers/flex_stacker/driver.py +768 -0
- opentrons/drivers/flex_stacker/errors.py +68 -0
- opentrons/drivers/flex_stacker/simulator.py +309 -0
- opentrons/drivers/flex_stacker/types.py +367 -0
- opentrons/drivers/flex_stacker/utils.py +19 -0
- opentrons/drivers/heater_shaker/__init__.py +5 -0
- opentrons/drivers/heater_shaker/abstract.py +76 -0
- opentrons/drivers/heater_shaker/driver.py +204 -0
- opentrons/drivers/heater_shaker/simulator.py +94 -0
- opentrons/drivers/mag_deck/__init__.py +6 -0
- opentrons/drivers/mag_deck/abstract.py +44 -0
- opentrons/drivers/mag_deck/driver.py +208 -0
- opentrons/drivers/mag_deck/simulator.py +63 -0
- opentrons/drivers/rpi_drivers/__init__.py +33 -0
- opentrons/drivers/rpi_drivers/dev_types.py +94 -0
- opentrons/drivers/rpi_drivers/gpio.py +282 -0
- opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
- opentrons/drivers/rpi_drivers/interfaces.py +15 -0
- opentrons/drivers/rpi_drivers/types.py +364 -0
- opentrons/drivers/rpi_drivers/usb.py +102 -0
- opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
- opentrons/drivers/serial_communication.py +151 -0
- opentrons/drivers/smoothie_drivers/__init__.py +4 -0
- opentrons/drivers/smoothie_drivers/connection.py +51 -0
- opentrons/drivers/smoothie_drivers/constants.py +121 -0
- opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
- opentrons/drivers/smoothie_drivers/errors.py +49 -0
- opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
- opentrons/drivers/smoothie_drivers/simulator.py +99 -0
- opentrons/drivers/smoothie_drivers/types.py +16 -0
- opentrons/drivers/temp_deck/__init__.py +10 -0
- opentrons/drivers/temp_deck/abstract.py +54 -0
- opentrons/drivers/temp_deck/driver.py +197 -0
- opentrons/drivers/temp_deck/simulator.py +57 -0
- opentrons/drivers/thermocycler/__init__.py +12 -0
- opentrons/drivers/thermocycler/abstract.py +99 -0
- opentrons/drivers/thermocycler/driver.py +395 -0
- opentrons/drivers/thermocycler/simulator.py +126 -0
- opentrons/drivers/types.py +107 -0
- opentrons/drivers/utils.py +222 -0
- opentrons/execute.py +742 -0
- opentrons/hardware_control/__init__.py +65 -0
- opentrons/hardware_control/__main__.py +77 -0
- opentrons/hardware_control/adapters.py +98 -0
- opentrons/hardware_control/api.py +1347 -0
- opentrons/hardware_control/backends/__init__.py +7 -0
- opentrons/hardware_control/backends/controller.py +400 -0
- opentrons/hardware_control/backends/errors.py +9 -0
- opentrons/hardware_control/backends/estop_state.py +164 -0
- opentrons/hardware_control/backends/flex_protocol.py +497 -0
- opentrons/hardware_control/backends/ot3controller.py +1930 -0
- opentrons/hardware_control/backends/ot3simulator.py +900 -0
- opentrons/hardware_control/backends/ot3utils.py +664 -0
- opentrons/hardware_control/backends/simulator.py +442 -0
- opentrons/hardware_control/backends/status_bar_state.py +240 -0
- opentrons/hardware_control/backends/subsystem_manager.py +431 -0
- opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
- opentrons/hardware_control/backends/types.py +14 -0
- opentrons/hardware_control/constants.py +6 -0
- opentrons/hardware_control/dev_types.py +125 -0
- opentrons/hardware_control/emulation/__init__.py +0 -0
- opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
- opentrons/hardware_control/emulation/app.py +56 -0
- opentrons/hardware_control/emulation/connection_handler.py +38 -0
- opentrons/hardware_control/emulation/heater_shaker.py +150 -0
- opentrons/hardware_control/emulation/magdeck.py +60 -0
- opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
- opentrons/hardware_control/emulation/module_server/client.py +78 -0
- opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
- opentrons/hardware_control/emulation/module_server/models.py +31 -0
- opentrons/hardware_control/emulation/module_server/server.py +110 -0
- opentrons/hardware_control/emulation/parser.py +74 -0
- opentrons/hardware_control/emulation/proxy.py +241 -0
- opentrons/hardware_control/emulation/run_emulator.py +68 -0
- opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
- opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
- opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
- opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
- opentrons/hardware_control/emulation/settings.py +119 -0
- opentrons/hardware_control/emulation/simulations.py +133 -0
- opentrons/hardware_control/emulation/smoothie.py +192 -0
- opentrons/hardware_control/emulation/tempdeck.py +69 -0
- opentrons/hardware_control/emulation/thermocycler.py +128 -0
- opentrons/hardware_control/emulation/types.py +10 -0
- opentrons/hardware_control/emulation/util.py +38 -0
- opentrons/hardware_control/errors.py +43 -0
- opentrons/hardware_control/execution_manager.py +164 -0
- opentrons/hardware_control/instruments/__init__.py +5 -0
- opentrons/hardware_control/instruments/instrument_abc.py +39 -0
- opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
- opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
- opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
- opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
- opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
- opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
- opentrons/hardware_control/module_control.py +332 -0
- opentrons/hardware_control/modules/__init__.py +69 -0
- opentrons/hardware_control/modules/absorbance_reader.py +373 -0
- opentrons/hardware_control/modules/errors.py +7 -0
- opentrons/hardware_control/modules/flex_stacker.py +948 -0
- opentrons/hardware_control/modules/heater_shaker.py +426 -0
- opentrons/hardware_control/modules/lid_temp_status.py +35 -0
- opentrons/hardware_control/modules/magdeck.py +233 -0
- opentrons/hardware_control/modules/mod_abc.py +245 -0
- opentrons/hardware_control/modules/module_calibration.py +93 -0
- opentrons/hardware_control/modules/plate_temp_status.py +61 -0
- opentrons/hardware_control/modules/tempdeck.py +299 -0
- opentrons/hardware_control/modules/thermocycler.py +731 -0
- opentrons/hardware_control/modules/types.py +417 -0
- opentrons/hardware_control/modules/update.py +255 -0
- opentrons/hardware_control/modules/utils.py +73 -0
- opentrons/hardware_control/motion_utilities.py +318 -0
- opentrons/hardware_control/nozzle_manager.py +422 -0
- opentrons/hardware_control/ot3_calibration.py +1171 -0
- opentrons/hardware_control/ot3api.py +3227 -0
- opentrons/hardware_control/pause_manager.py +31 -0
- opentrons/hardware_control/poller.py +112 -0
- opentrons/hardware_control/protocols/__init__.py +106 -0
- opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
- opentrons/hardware_control/protocols/calibratable.py +45 -0
- opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
- opentrons/hardware_control/protocols/configurable.py +48 -0
- opentrons/hardware_control/protocols/event_sourcer.py +18 -0
- opentrons/hardware_control/protocols/execution_controllable.py +33 -0
- opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
- opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
- opentrons/hardware_control/protocols/gripper_controller.py +55 -0
- opentrons/hardware_control/protocols/hardware_manager.py +51 -0
- opentrons/hardware_control/protocols/identifiable.py +16 -0
- opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
- opentrons/hardware_control/protocols/liquid_handler.py +266 -0
- opentrons/hardware_control/protocols/module_provider.py +16 -0
- opentrons/hardware_control/protocols/motion_controller.py +243 -0
- opentrons/hardware_control/protocols/position_estimator.py +45 -0
- opentrons/hardware_control/protocols/simulatable.py +10 -0
- opentrons/hardware_control/protocols/stoppable.py +9 -0
- opentrons/hardware_control/protocols/types.py +27 -0
- opentrons/hardware_control/robot_calibration.py +224 -0
- opentrons/hardware_control/scripts/README.md +28 -0
- opentrons/hardware_control/scripts/__init__.py +1 -0
- opentrons/hardware_control/scripts/gripper_control.py +208 -0
- opentrons/hardware_control/scripts/ot3gripper +7 -0
- opentrons/hardware_control/scripts/ot3repl +7 -0
- opentrons/hardware_control/scripts/repl.py +187 -0
- opentrons/hardware_control/scripts/tc_control.py +97 -0
- opentrons/hardware_control/simulator_setup.py +260 -0
- opentrons/hardware_control/thread_manager.py +431 -0
- opentrons/hardware_control/threaded_async_lock.py +97 -0
- opentrons/hardware_control/types.py +792 -0
- opentrons/hardware_control/util.py +234 -0
- opentrons/legacy_broker.py +53 -0
- opentrons/legacy_commands/__init__.py +1 -0
- opentrons/legacy_commands/commands.py +483 -0
- opentrons/legacy_commands/helpers.py +153 -0
- opentrons/legacy_commands/module_commands.py +215 -0
- opentrons/legacy_commands/protocol_commands.py +54 -0
- opentrons/legacy_commands/publisher.py +155 -0
- opentrons/legacy_commands/robot_commands.py +51 -0
- opentrons/legacy_commands/types.py +1115 -0
- opentrons/motion_planning/__init__.py +32 -0
- opentrons/motion_planning/adjacent_slots_getters.py +168 -0
- opentrons/motion_planning/deck_conflict.py +396 -0
- opentrons/motion_planning/errors.py +35 -0
- opentrons/motion_planning/types.py +42 -0
- opentrons/motion_planning/waypoints.py +218 -0
- opentrons/ordered_set.py +138 -0
- opentrons/protocol_api/__init__.py +105 -0
- opentrons/protocol_api/_liquid.py +157 -0
- opentrons/protocol_api/_liquid_properties.py +814 -0
- opentrons/protocol_api/_nozzle_layout.py +31 -0
- opentrons/protocol_api/_parameter_context.py +300 -0
- opentrons/protocol_api/_parameters.py +31 -0
- opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
- opentrons/protocol_api/_types.py +43 -0
- opentrons/protocol_api/config.py +23 -0
- opentrons/protocol_api/core/__init__.py +23 -0
- opentrons/protocol_api/core/common.py +33 -0
- opentrons/protocol_api/core/core_map.py +74 -0
- opentrons/protocol_api/core/engine/__init__.py +22 -0
- opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
- opentrons/protocol_api/core/engine/deck_conflict.py +348 -0
- opentrons/protocol_api/core/engine/exceptions.py +19 -0
- opentrons/protocol_api/core/engine/instrument.py +2391 -0
- opentrons/protocol_api/core/engine/labware.py +238 -0
- opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
- opentrons/protocol_api/core/engine/module_core.py +1025 -0
- opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
- opentrons/protocol_api/core/engine/point_calculations.py +64 -0
- opentrons/protocol_api/core/engine/protocol.py +1153 -0
- opentrons/protocol_api/core/engine/robot.py +139 -0
- opentrons/protocol_api/core/engine/stringify.py +74 -0
- opentrons/protocol_api/core/engine/transfer_components_executor.py +990 -0
- opentrons/protocol_api/core/engine/well.py +241 -0
- opentrons/protocol_api/core/instrument.py +459 -0
- opentrons/protocol_api/core/labware.py +151 -0
- opentrons/protocol_api/core/legacy/__init__.py +11 -0
- opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
- opentrons/protocol_api/core/legacy/deck.py +369 -0
- opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
- opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
- opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
- opentrons/protocol_api/core/legacy/load_info.py +67 -0
- opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
- opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
- opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
- opentrons/protocol_api/core/module.py +484 -0
- opentrons/protocol_api/core/protocol.py +311 -0
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/core/well.py +116 -0
- opentrons/protocol_api/core/well_grid.py +45 -0
- opentrons/protocol_api/create_protocol_context.py +177 -0
- opentrons/protocol_api/deck.py +223 -0
- opentrons/protocol_api/disposal_locations.py +244 -0
- opentrons/protocol_api/instrument_context.py +3212 -0
- opentrons/protocol_api/labware.py +1579 -0
- opentrons/protocol_api/module_contexts.py +1425 -0
- opentrons/protocol_api/module_validation_and_errors.py +61 -0
- opentrons/protocol_api/protocol_context.py +1688 -0
- opentrons/protocol_api/robot_context.py +303 -0
- opentrons/protocol_api/validation.py +761 -0
- opentrons/protocol_engine/__init__.py +155 -0
- opentrons/protocol_engine/actions/__init__.py +65 -0
- opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
- opentrons/protocol_engine/actions/action_handler.py +13 -0
- opentrons/protocol_engine/actions/actions.py +302 -0
- opentrons/protocol_engine/actions/get_state_update.py +38 -0
- opentrons/protocol_engine/clients/__init__.py +5 -0
- opentrons/protocol_engine/clients/sync_client.py +174 -0
- opentrons/protocol_engine/clients/transports.py +197 -0
- opentrons/protocol_engine/commands/__init__.py +757 -0
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
- opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
- opentrons/protocol_engine/commands/aspirate.py +244 -0
- opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
- opentrons/protocol_engine/commands/blow_out.py +146 -0
- opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
- opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
- opentrons/protocol_engine/commands/command.py +308 -0
- opentrons/protocol_engine/commands/command_unions.py +974 -0
- opentrons/protocol_engine/commands/comment.py +57 -0
- opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
- opentrons/protocol_engine/commands/custom.py +67 -0
- opentrons/protocol_engine/commands/dispense.py +194 -0
- opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
- opentrons/protocol_engine/commands/drop_tip.py +232 -0
- opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
- opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
- opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
- opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
- opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +326 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
- opentrons/protocol_engine/commands/get_next_tip.py +134 -0
- opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
- opentrons/protocol_engine/commands/hash_command_params.py +38 -0
- opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
- opentrons/protocol_engine/commands/home.py +100 -0
- opentrons/protocol_engine/commands/identify_module.py +86 -0
- opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
- opentrons/protocol_engine/commands/liquid_probe.py +464 -0
- opentrons/protocol_engine/commands/load_labware.py +210 -0
- opentrons/protocol_engine/commands/load_lid.py +154 -0
- opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
- opentrons/protocol_engine/commands/load_liquid.py +95 -0
- opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
- opentrons/protocol_engine/commands/load_module.py +223 -0
- opentrons/protocol_engine/commands/load_pipette.py +167 -0
- opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
- opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
- opentrons/protocol_engine/commands/move_labware.py +546 -0
- opentrons/protocol_engine/commands/move_relative.py +102 -0
- opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
- opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
- opentrons/protocol_engine/commands/move_to_well.py +119 -0
- opentrons/protocol_engine/commands/movement_common.py +338 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
- opentrons/protocol_engine/commands/pipetting_common.py +443 -0
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
- opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
- opentrons/protocol_engine/commands/reload_labware.py +90 -0
- opentrons/protocol_engine/commands/retract_axis.py +75 -0
- opentrons/protocol_engine/commands/robot/__init__.py +70 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
- opentrons/protocol_engine/commands/robot/common.py +18 -0
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
- opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
- opentrons/protocol_engine/commands/robot/move_to.py +94 -0
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
- opentrons/protocol_engine/commands/save_position.py +109 -0
- opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
- opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
- opentrons/protocol_engine/commands/set_status_bar.py +89 -0
- opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
- opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
- opentrons/protocol_engine/commands/touch_tip.py +189 -0
- opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
- opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
- opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
- opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
- opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
- opentrons/protocol_engine/create_protocol_engine.py +193 -0
- opentrons/protocol_engine/engine_support.py +28 -0
- opentrons/protocol_engine/error_recovery_policy.py +81 -0
- opentrons/protocol_engine/errors/__init__.py +191 -0
- opentrons/protocol_engine/errors/error_occurrence.py +182 -0
- opentrons/protocol_engine/errors/exceptions.py +1308 -0
- opentrons/protocol_engine/execution/__init__.py +50 -0
- opentrons/protocol_engine/execution/command_executor.py +216 -0
- opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
- opentrons/protocol_engine/execution/door_watcher.py +119 -0
- opentrons/protocol_engine/execution/equipment.py +819 -0
- opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
- opentrons/protocol_engine/execution/gantry_mover.py +686 -0
- opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
- opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
- opentrons/protocol_engine/execution/labware_movement.py +297 -0
- opentrons/protocol_engine/execution/movement.py +349 -0
- opentrons/protocol_engine/execution/pipetting.py +607 -0
- opentrons/protocol_engine/execution/queue_worker.py +86 -0
- opentrons/protocol_engine/execution/rail_lights.py +25 -0
- opentrons/protocol_engine/execution/run_control.py +33 -0
- opentrons/protocol_engine/execution/status_bar.py +34 -0
- opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
- opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
- opentrons/protocol_engine/execution/tip_handler.py +550 -0
- opentrons/protocol_engine/labware_offset_standardization.py +194 -0
- opentrons/protocol_engine/notes/__init__.py +17 -0
- opentrons/protocol_engine/notes/notes.py +59 -0
- opentrons/protocol_engine/plugins.py +104 -0
- opentrons/protocol_engine/protocol_engine.py +683 -0
- opentrons/protocol_engine/resources/__init__.py +26 -0
- opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
- opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
- opentrons/protocol_engine/resources/file_provider.py +161 -0
- opentrons/protocol_engine/resources/fixture_validation.py +58 -0
- opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
- opentrons/protocol_engine/resources/labware_validation.py +73 -0
- opentrons/protocol_engine/resources/model_utils.py +32 -0
- opentrons/protocol_engine/resources/module_data_provider.py +44 -0
- opentrons/protocol_engine/resources/ot3_validation.py +21 -0
- opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
- opentrons/protocol_engine/slot_standardization.py +128 -0
- opentrons/protocol_engine/state/__init__.py +1 -0
- opentrons/protocol_engine/state/_abstract_store.py +27 -0
- opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
- opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
- opentrons/protocol_engine/state/_move_types.py +83 -0
- opentrons/protocol_engine/state/_well_math.py +193 -0
- opentrons/protocol_engine/state/addressable_areas.py +699 -0
- opentrons/protocol_engine/state/command_history.py +309 -0
- opentrons/protocol_engine/state/commands.py +1158 -0
- opentrons/protocol_engine/state/config.py +39 -0
- opentrons/protocol_engine/state/files.py +57 -0
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/geometry.py +2359 -0
- opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
- opentrons/protocol_engine/state/labware.py +1459 -0
- opentrons/protocol_engine/state/liquid_classes.py +82 -0
- opentrons/protocol_engine/state/liquids.py +73 -0
- opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
- opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
- opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
- opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
- opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
- opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
- opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
- opentrons/protocol_engine/state/modules.py +1500 -0
- opentrons/protocol_engine/state/motion.py +373 -0
- opentrons/protocol_engine/state/pipettes.py +905 -0
- opentrons/protocol_engine/state/state.py +421 -0
- opentrons/protocol_engine/state/state_summary.py +36 -0
- opentrons/protocol_engine/state/tips.py +420 -0
- opentrons/protocol_engine/state/update_types.py +904 -0
- opentrons/protocol_engine/state/wells.py +290 -0
- opentrons/protocol_engine/types/__init__.py +308 -0
- opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
- opentrons/protocol_engine/types/command_annotations.py +53 -0
- opentrons/protocol_engine/types/deck_configuration.py +81 -0
- opentrons/protocol_engine/types/execution.py +96 -0
- opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
- opentrons/protocol_engine/types/instrument.py +47 -0
- opentrons/protocol_engine/types/instrument_sensors.py +47 -0
- opentrons/protocol_engine/types/labware.py +131 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +111 -0
- opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
- opentrons/protocol_engine/types/liquid.py +40 -0
- opentrons/protocol_engine/types/liquid_class.py +59 -0
- opentrons/protocol_engine/types/liquid_handling.py +13 -0
- opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
- opentrons/protocol_engine/types/location.py +194 -0
- opentrons/protocol_engine/types/module.py +303 -0
- opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
- opentrons/protocol_engine/types/run_time_parameters.py +133 -0
- opentrons/protocol_engine/types/tip.py +18 -0
- opentrons/protocol_engine/types/util.py +21 -0
- opentrons/protocol_engine/types/well_position.py +124 -0
- opentrons/protocol_reader/__init__.py +37 -0
- opentrons/protocol_reader/extract_labware_definitions.py +66 -0
- opentrons/protocol_reader/file_format_validator.py +152 -0
- opentrons/protocol_reader/file_hasher.py +27 -0
- opentrons/protocol_reader/file_identifier.py +284 -0
- opentrons/protocol_reader/file_reader_writer.py +90 -0
- opentrons/protocol_reader/input_file.py +16 -0
- opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
- opentrons/protocol_reader/protocol_reader.py +188 -0
- opentrons/protocol_reader/protocol_source.py +124 -0
- opentrons/protocol_reader/role_analyzer.py +86 -0
- opentrons/protocol_runner/__init__.py +26 -0
- opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
- opentrons/protocol_runner/json_file_reader.py +55 -0
- opentrons/protocol_runner/json_translator.py +314 -0
- opentrons/protocol_runner/legacy_command_mapper.py +848 -0
- opentrons/protocol_runner/legacy_context_plugin.py +116 -0
- opentrons/protocol_runner/protocol_runner.py +530 -0
- opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
- opentrons/protocol_runner/run_orchestrator.py +496 -0
- opentrons/protocol_runner/task_queue.py +95 -0
- opentrons/protocols/__init__.py +6 -0
- opentrons/protocols/advanced_control/__init__.py +0 -0
- opentrons/protocols/advanced_control/common.py +38 -0
- opentrons/protocols/advanced_control/mix.py +60 -0
- opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
- opentrons/protocols/advanced_control/transfers/common.py +180 -0
- opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
- opentrons/protocols/api_support/__init__.py +0 -0
- opentrons/protocols/api_support/constants.py +8 -0
- opentrons/protocols/api_support/deck_type.py +110 -0
- opentrons/protocols/api_support/definitions.py +18 -0
- opentrons/protocols/api_support/instrument.py +151 -0
- opentrons/protocols/api_support/labware_like.py +233 -0
- opentrons/protocols/api_support/tip_tracker.py +175 -0
- opentrons/protocols/api_support/types.py +32 -0
- opentrons/protocols/api_support/util.py +403 -0
- opentrons/protocols/bundle.py +89 -0
- opentrons/protocols/duration/__init__.py +4 -0
- opentrons/protocols/duration/errors.py +5 -0
- opentrons/protocols/duration/estimator.py +628 -0
- opentrons/protocols/execution/__init__.py +0 -0
- opentrons/protocols/execution/dev_types.py +181 -0
- opentrons/protocols/execution/errors.py +40 -0
- opentrons/protocols/execution/execute.py +84 -0
- opentrons/protocols/execution/execute_json_v3.py +275 -0
- opentrons/protocols/execution/execute_json_v4.py +359 -0
- opentrons/protocols/execution/execute_json_v5.py +28 -0
- opentrons/protocols/execution/execute_python.py +169 -0
- opentrons/protocols/execution/json_dispatchers.py +87 -0
- opentrons/protocols/execution/types.py +7 -0
- opentrons/protocols/geometry/__init__.py +0 -0
- opentrons/protocols/geometry/planning.py +297 -0
- opentrons/protocols/labware.py +312 -0
- opentrons/protocols/models/__init__.py +0 -0
- opentrons/protocols/models/json_protocol.py +679 -0
- opentrons/protocols/parameters/__init__.py +0 -0
- opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
- opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
- opentrons/protocols/parameters/exceptions.py +34 -0
- opentrons/protocols/parameters/parameter_definition.py +272 -0
- opentrons/protocols/parameters/types.py +17 -0
- opentrons/protocols/parameters/validation.py +267 -0
- opentrons/protocols/parse.py +671 -0
- opentrons/protocols/types.py +159 -0
- opentrons/py.typed +0 -0
- opentrons/resources/scripts/lpc21isp +0 -0
- opentrons/resources/smoothie-edge-8414642.hex +23010 -0
- opentrons/simulate.py +1065 -0
- opentrons/system/__init__.py +6 -0
- opentrons/system/camera.py +51 -0
- opentrons/system/log_control.py +59 -0
- opentrons/system/nmcli.py +856 -0
- opentrons/system/resin.py +24 -0
- opentrons/system/smoothie_update.py +15 -0
- opentrons/system/wifi.py +204 -0
- opentrons/tools/__init__.py +0 -0
- opentrons/tools/args_handler.py +22 -0
- opentrons/tools/write_pipette_memory.py +157 -0
- opentrons/types.py +618 -0
- opentrons/util/__init__.py +1 -0
- opentrons/util/async_helpers.py +166 -0
- opentrons/util/broker.py +84 -0
- opentrons/util/change_notifier.py +47 -0
- opentrons/util/entrypoint_util.py +278 -0
- opentrons/util/get_union_elements.py +26 -0
- opentrons/util/helpers.py +6 -0
- opentrons/util/linal.py +178 -0
- opentrons/util/logging_config.py +265 -0
- opentrons/util/logging_queue_handler.py +61 -0
- opentrons/util/performance_helpers.py +157 -0
- opentrons-8.6.0a1.dist-info/METADATA +37 -0
- opentrons-8.6.0a1.dist-info/RECORD +600 -0
- opentrons-8.6.0a1.dist-info/WHEEL +4 -0
- opentrons-8.6.0a1.dist-info/entry_points.txt +3 -0
- opentrons-8.6.0a1.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
"""Tip pickup and drop procedures."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional, Dict, Tuple
|
|
4
|
+
from typing_extensions import Protocol as TypingProtocol
|
|
5
|
+
|
|
6
|
+
from opentrons.hardware_control import HardwareControlAPI
|
|
7
|
+
from opentrons.hardware_control.types import (
|
|
8
|
+
FailedTipStateCheck,
|
|
9
|
+
InstrumentProbeType,
|
|
10
|
+
TipScrapeType,
|
|
11
|
+
)
|
|
12
|
+
from opentrons.protocol_engine.errors.exceptions import PickUpTipTipNotAttachedError
|
|
13
|
+
from opentrons.types import Mount, NozzleConfigurationType
|
|
14
|
+
|
|
15
|
+
from opentrons_shared_data.errors.exceptions import (
|
|
16
|
+
CommandPreconditionViolated,
|
|
17
|
+
CommandParameterLimitViolated,
|
|
18
|
+
PythonException,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from ..resources import LabwareDataProvider, ensure_ot3_hardware
|
|
22
|
+
from ..state.state import StateView
|
|
23
|
+
from ..types import TipGeometry, TipPresenceStatus
|
|
24
|
+
from ..errors import (
|
|
25
|
+
HardwareNotSupportedError,
|
|
26
|
+
TipNotAttachedError,
|
|
27
|
+
TipAttachedError,
|
|
28
|
+
ProtocolEngineError,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
PRIMARY_NOZZLE_TO_ENDING_NOZZLE_MAP = {
|
|
32
|
+
"A1": {"COLUMN": "H1", "ROW": "A12"},
|
|
33
|
+
"H1": {"COLUMN": "A1", "ROW": "H12"},
|
|
34
|
+
"A12": {"COLUMN": "H12", "ROW": "A1"},
|
|
35
|
+
"H12": {"COLUMN": "A12", "ROW": "H1"},
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
PRIMARY_NOZZLE_TO_BACK_LEFT_NOZZLE_MAP = {
|
|
39
|
+
"A1": {"COLUMN": "A1", "ROW": "A1"},
|
|
40
|
+
"H1": {"COLUMN": "A1", "ROW": "H1"},
|
|
41
|
+
"A12": {"COLUMN": "A12", "ROW": "A1"},
|
|
42
|
+
"H12": {"COLUMN": "A12", "ROW": "H1"},
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TipHandler(TypingProtocol):
|
|
47
|
+
"""Pick up and drop tips."""
|
|
48
|
+
|
|
49
|
+
async def available_for_nozzle_layout(
|
|
50
|
+
self,
|
|
51
|
+
pipette_id: str,
|
|
52
|
+
style: str,
|
|
53
|
+
primary_nozzle: Optional[str] = None,
|
|
54
|
+
front_right_nozzle: Optional[str] = None,
|
|
55
|
+
back_left_nozzle: Optional[str] = None,
|
|
56
|
+
) -> Dict[str, str]:
|
|
57
|
+
"""Check nozzle layout is compatible with the pipette.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
A dict of nozzles used to configure the pipette.
|
|
61
|
+
"""
|
|
62
|
+
...
|
|
63
|
+
|
|
64
|
+
async def pick_up_tip(
|
|
65
|
+
self,
|
|
66
|
+
pipette_id: str,
|
|
67
|
+
labware_id: str,
|
|
68
|
+
well_name: str,
|
|
69
|
+
do_not_ignore_tip_presence: bool = True,
|
|
70
|
+
) -> TipGeometry:
|
|
71
|
+
"""Pick up the named tip.
|
|
72
|
+
|
|
73
|
+
Pipette should be in place over the named tip prior to calling this method.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Tip geometry of the picked up tip.
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
PickUpTipTipNotAttachedError
|
|
80
|
+
"""
|
|
81
|
+
...
|
|
82
|
+
|
|
83
|
+
async def drop_tip(
|
|
84
|
+
self,
|
|
85
|
+
pipette_id: str,
|
|
86
|
+
home_after: Optional[bool],
|
|
87
|
+
do_not_ignore_tip_presence: bool = True,
|
|
88
|
+
ignore_plunger: bool = False,
|
|
89
|
+
scrape_type: TipScrapeType = TipScrapeType.NONE,
|
|
90
|
+
) -> None:
|
|
91
|
+
"""Drop the attached tip into the current location.
|
|
92
|
+
|
|
93
|
+
Pipette should be in place over the destination prior to calling this method.
|
|
94
|
+
|
|
95
|
+
Raises:
|
|
96
|
+
TipAttachedError
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
def cache_tip(self, pipette_id: str, tip: TipGeometry) -> None:
|
|
100
|
+
"""Tell the Hardware API that a tip is attached."""
|
|
101
|
+
|
|
102
|
+
def remove_tip(self, pipette_id: str) -> None:
|
|
103
|
+
"""Tell the hardware API that no tip is attached."""
|
|
104
|
+
|
|
105
|
+
async def get_tip_presence(self, pipette_id: str) -> TipPresenceStatus:
|
|
106
|
+
"""Get tip presence status on the pipette."""
|
|
107
|
+
|
|
108
|
+
async def verify_tip_presence(
|
|
109
|
+
self,
|
|
110
|
+
pipette_id: str,
|
|
111
|
+
expected: TipPresenceStatus,
|
|
112
|
+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
|
|
113
|
+
) -> None:
|
|
114
|
+
"""Use sensors to verify that a tip is or is not physically attached.
|
|
115
|
+
|
|
116
|
+
Raises:
|
|
117
|
+
TipNotAttachedError or TipAttachedError, as appropriate, if the physical
|
|
118
|
+
status doesn't match what was expected.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
async def _available_for_nozzle_layout( # noqa: C901
|
|
123
|
+
channels: int,
|
|
124
|
+
style: str,
|
|
125
|
+
primary_nozzle: Optional[str],
|
|
126
|
+
front_right_nozzle: Optional[str],
|
|
127
|
+
back_left_nozzle: Optional[str],
|
|
128
|
+
) -> Dict[str, str]:
|
|
129
|
+
"""Check nozzle layout is compatible with the pipette.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
A dict of nozzles used to configure the pipette.
|
|
133
|
+
"""
|
|
134
|
+
if channels == 1:
|
|
135
|
+
raise CommandPreconditionViolated(
|
|
136
|
+
message=f"Cannot configure nozzle layout with a {channels} channel pipette."
|
|
137
|
+
)
|
|
138
|
+
if style == "ALL":
|
|
139
|
+
return {}
|
|
140
|
+
if style == "ROW" and channels == 8:
|
|
141
|
+
raise CommandParameterLimitViolated(
|
|
142
|
+
command_name="configure_nozzle_layout",
|
|
143
|
+
parameter_name="RowNozzleLayout",
|
|
144
|
+
limit_statement="RowNozzleLayout is incompatible with {channels} channel pipettes.",
|
|
145
|
+
actual_value=str(primary_nozzle),
|
|
146
|
+
)
|
|
147
|
+
if style == "PARTIAL_COLUM" and channels == 96:
|
|
148
|
+
raise CommandParameterLimitViolated(
|
|
149
|
+
command_name="configure_nozzle_layout",
|
|
150
|
+
parameter_name="PartialColumnNozzleLayout",
|
|
151
|
+
limit_statement="PartialColumnNozzleLayout is incompatible with {channels} channel pipettes.",
|
|
152
|
+
actual_value=str(primary_nozzle),
|
|
153
|
+
)
|
|
154
|
+
if not primary_nozzle:
|
|
155
|
+
return {"primary_nozzle": "A1"}
|
|
156
|
+
if style == "SINGLE":
|
|
157
|
+
return {"primary_nozzle": primary_nozzle}
|
|
158
|
+
if style == "QUADRANT" and front_right_nozzle and not back_left_nozzle:
|
|
159
|
+
return {
|
|
160
|
+
"primary_nozzle": primary_nozzle,
|
|
161
|
+
"front_right_nozzle": front_right_nozzle,
|
|
162
|
+
"back_left_nozzle": primary_nozzle,
|
|
163
|
+
}
|
|
164
|
+
if style == "QUADRANT" and back_left_nozzle and not front_right_nozzle:
|
|
165
|
+
return {
|
|
166
|
+
"primary_nozzle": primary_nozzle,
|
|
167
|
+
"front_right_nozzle": primary_nozzle,
|
|
168
|
+
"back_left_nozzle": back_left_nozzle,
|
|
169
|
+
}
|
|
170
|
+
if not front_right_nozzle and back_left_nozzle:
|
|
171
|
+
return {
|
|
172
|
+
"primary_nozzle": primary_nozzle,
|
|
173
|
+
"front_right_nozzle": PRIMARY_NOZZLE_TO_ENDING_NOZZLE_MAP[primary_nozzle][
|
|
174
|
+
style
|
|
175
|
+
],
|
|
176
|
+
"back_left_nozzle": back_left_nozzle,
|
|
177
|
+
}
|
|
178
|
+
if front_right_nozzle and not back_left_nozzle:
|
|
179
|
+
return {
|
|
180
|
+
"primary_nozzle": primary_nozzle,
|
|
181
|
+
"front_right_nozzle": front_right_nozzle,
|
|
182
|
+
"back_left_nozzle": PRIMARY_NOZZLE_TO_BACK_LEFT_NOZZLE_MAP[primary_nozzle][
|
|
183
|
+
style
|
|
184
|
+
],
|
|
185
|
+
}
|
|
186
|
+
if front_right_nozzle and back_left_nozzle:
|
|
187
|
+
return {
|
|
188
|
+
"primary_nozzle": primary_nozzle,
|
|
189
|
+
"front_right_nozzle": front_right_nozzle,
|
|
190
|
+
"back_left_nozzle": back_left_nozzle,
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
"primary_nozzle": primary_nozzle,
|
|
195
|
+
"front_right_nozzle": PRIMARY_NOZZLE_TO_ENDING_NOZZLE_MAP[primary_nozzle][
|
|
196
|
+
style
|
|
197
|
+
],
|
|
198
|
+
"back_left_nozzle": PRIMARY_NOZZLE_TO_BACK_LEFT_NOZZLE_MAP[primary_nozzle][
|
|
199
|
+
style
|
|
200
|
+
],
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def tip_on_left_side_96(back_left_nozzle: str) -> bool:
|
|
205
|
+
"""Return if there is a tip on the left edge of the 96 channel."""
|
|
206
|
+
left_most_column = int(back_left_nozzle[1:])
|
|
207
|
+
return left_most_column == 1
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def tip_on_right_side_96(front_right_nozzle: str) -> bool:
|
|
211
|
+
"""Return if there is a tip on the left edge of the 96 channel."""
|
|
212
|
+
right_most_column = int(front_right_nozzle[1:])
|
|
213
|
+
return right_most_column == 12
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class HardwareTipHandler(TipHandler):
|
|
217
|
+
"""Pick up and drop tips, using the Hardware API."""
|
|
218
|
+
|
|
219
|
+
def __init__(
|
|
220
|
+
self,
|
|
221
|
+
state_view: StateView,
|
|
222
|
+
hardware_api: HardwareControlAPI,
|
|
223
|
+
labware_data_provider: Optional[LabwareDataProvider] = None,
|
|
224
|
+
) -> None:
|
|
225
|
+
self._hardware_api = hardware_api
|
|
226
|
+
self._labware_data_provider = labware_data_provider or LabwareDataProvider()
|
|
227
|
+
self._state_view = state_view
|
|
228
|
+
|
|
229
|
+
# WARNING: ErrorRecoveryHardwareStateSynchronizer can currently construct several
|
|
230
|
+
# instances of this class per run, in addition to the main instance used
|
|
231
|
+
# for command execution. We're therefore depending on this class being
|
|
232
|
+
# stateless, so consider that before adding additional attributes here.
|
|
233
|
+
|
|
234
|
+
async def available_for_nozzle_layout(
|
|
235
|
+
self,
|
|
236
|
+
pipette_id: str,
|
|
237
|
+
style: str,
|
|
238
|
+
primary_nozzle: Optional[str] = None,
|
|
239
|
+
front_right_nozzle: Optional[str] = None,
|
|
240
|
+
back_left_nozzle: Optional[str] = None,
|
|
241
|
+
) -> Dict[str, str]:
|
|
242
|
+
"""See documentation on abstract base class."""
|
|
243
|
+
if self._state_view.pipettes.get_attached_tip(pipette_id):
|
|
244
|
+
raise CommandPreconditionViolated(
|
|
245
|
+
message=f"Cannot configure nozzle layout of {str(self)} while it has tips attached."
|
|
246
|
+
)
|
|
247
|
+
channels = self._state_view.pipettes.get_channels(pipette_id)
|
|
248
|
+
return await _available_for_nozzle_layout(
|
|
249
|
+
channels, style, primary_nozzle, front_right_nozzle, back_left_nozzle
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
def get_tip_presence_config(
|
|
253
|
+
self, pipette_id: str
|
|
254
|
+
) -> Tuple[bool, Optional[InstrumentProbeType]]:
|
|
255
|
+
"""Return the supported settings for tip presence on a given pipette depending on it's current nozzle map."""
|
|
256
|
+
follow_singular_sensor = None
|
|
257
|
+
|
|
258
|
+
unsupported_layout_types_96 = [NozzleConfigurationType.SINGLE]
|
|
259
|
+
# NOTE: (09-20-2024) Current on multi-channel pipettes, utilizing less than 4 nozzles risks false positives on the tip presence sensor
|
|
260
|
+
supported_partial_nozzle_minimum = 4
|
|
261
|
+
|
|
262
|
+
nozzle_configuration = self._state_view.pipettes.get_nozzle_configuration(
|
|
263
|
+
pipette_id=pipette_id
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
match self._state_view.pipettes.get_channels(pipette_id):
|
|
267
|
+
case 1:
|
|
268
|
+
tip_presence_supported = True
|
|
269
|
+
case 8:
|
|
270
|
+
tip_presence_supported = (
|
|
271
|
+
nozzle_configuration.tip_count >= supported_partial_nozzle_minimum
|
|
272
|
+
)
|
|
273
|
+
case 96:
|
|
274
|
+
tip_presence_supported = (
|
|
275
|
+
nozzle_configuration.configuration
|
|
276
|
+
not in unsupported_layout_types_96
|
|
277
|
+
and nozzle_configuration.tip_count
|
|
278
|
+
>= supported_partial_nozzle_minimum
|
|
279
|
+
)
|
|
280
|
+
if (
|
|
281
|
+
nozzle_configuration.configuration != NozzleConfigurationType.FULL
|
|
282
|
+
and tip_presence_supported
|
|
283
|
+
):
|
|
284
|
+
use_left = tip_on_left_side_96(nozzle_configuration.back_left)
|
|
285
|
+
use_right = tip_on_right_side_96(nozzle_configuration.front_right)
|
|
286
|
+
if not (use_left and use_right):
|
|
287
|
+
if use_left:
|
|
288
|
+
follow_singular_sensor = InstrumentProbeType.PRIMARY
|
|
289
|
+
else:
|
|
290
|
+
follow_singular_sensor = InstrumentProbeType.SECONDARY
|
|
291
|
+
case _:
|
|
292
|
+
raise ValueError("Unknown pipette type.")
|
|
293
|
+
|
|
294
|
+
return (tip_presence_supported, follow_singular_sensor)
|
|
295
|
+
|
|
296
|
+
async def pick_up_tip(
|
|
297
|
+
self,
|
|
298
|
+
pipette_id: str,
|
|
299
|
+
labware_id: str,
|
|
300
|
+
well_name: str,
|
|
301
|
+
do_not_ignore_tip_presence: bool = True,
|
|
302
|
+
) -> TipGeometry:
|
|
303
|
+
"""See documentation on abstract base class."""
|
|
304
|
+
hw_mount = self._get_hw_mount(pipette_id)
|
|
305
|
+
|
|
306
|
+
nominal_tip_geometry = self._state_view.geometry.get_nominal_tip_geometry(
|
|
307
|
+
pipette_id=pipette_id, labware_id=labware_id, well_name=well_name
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
actual_tip_length = await self._labware_data_provider.get_calibrated_tip_length(
|
|
311
|
+
pipette_serial=self._state_view.pipettes.get_serial_number(pipette_id),
|
|
312
|
+
labware_definition=self._state_view.labware.get_definition(labware_id),
|
|
313
|
+
nominal_fallback=nominal_tip_geometry.length,
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
tip_geometry = TipGeometry(
|
|
317
|
+
length=actual_tip_length,
|
|
318
|
+
diameter=nominal_tip_geometry.diameter,
|
|
319
|
+
volume=nominal_tip_geometry.volume,
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
await self._hardware_api.tip_pickup_moves(
|
|
323
|
+
mount=hw_mount, presses=None, increment=None
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
tip_presence_supported, follow_singular_sensor = self.get_tip_presence_config(
|
|
327
|
+
pipette_id
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
if do_not_ignore_tip_presence and tip_presence_supported:
|
|
331
|
+
try:
|
|
332
|
+
await self.verify_tip_presence(
|
|
333
|
+
pipette_id,
|
|
334
|
+
TipPresenceStatus.PRESENT,
|
|
335
|
+
follow_singular_sensor=follow_singular_sensor,
|
|
336
|
+
)
|
|
337
|
+
except TipNotAttachedError as e:
|
|
338
|
+
raise PickUpTipTipNotAttachedError(tip_geometry=tip_geometry) from e
|
|
339
|
+
|
|
340
|
+
self.cache_tip(pipette_id, tip_geometry)
|
|
341
|
+
|
|
342
|
+
await self._hardware_api.prepare_for_aspirate(hw_mount)
|
|
343
|
+
|
|
344
|
+
return tip_geometry
|
|
345
|
+
|
|
346
|
+
async def drop_tip(
|
|
347
|
+
self,
|
|
348
|
+
pipette_id: str,
|
|
349
|
+
home_after: Optional[bool],
|
|
350
|
+
do_not_ignore_tip_presence: bool = True,
|
|
351
|
+
ignore_plunger: bool = False,
|
|
352
|
+
scrape_type: TipScrapeType = TipScrapeType.NONE,
|
|
353
|
+
) -> None:
|
|
354
|
+
"""See documentation on abstract base class."""
|
|
355
|
+
hw_mount = self._get_hw_mount(pipette_id)
|
|
356
|
+
|
|
357
|
+
# Let the hardware controller handle defaulting home_after since its behavior
|
|
358
|
+
# differs between machines
|
|
359
|
+
kwargs = {}
|
|
360
|
+
if home_after is not None:
|
|
361
|
+
kwargs["home_after"] = home_after
|
|
362
|
+
|
|
363
|
+
await self._hardware_api.tip_drop_moves(
|
|
364
|
+
mount=hw_mount,
|
|
365
|
+
ignore_plunger=ignore_plunger,
|
|
366
|
+
scrape_type=scrape_type,
|
|
367
|
+
**kwargs,
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
if do_not_ignore_tip_presence:
|
|
371
|
+
# Allow TipNotAttachedError to propagate.
|
|
372
|
+
await self.verify_tip_presence(pipette_id, TipPresenceStatus.ABSENT)
|
|
373
|
+
|
|
374
|
+
self.remove_tip(pipette_id)
|
|
375
|
+
|
|
376
|
+
def cache_tip(self, pipette_id: str, tip: TipGeometry) -> None:
|
|
377
|
+
"""See documentation on abstract base class."""
|
|
378
|
+
hw_mount = self._get_hw_mount(pipette_id)
|
|
379
|
+
|
|
380
|
+
self._hardware_api.cache_tip(mount=hw_mount, tip_length=tip.length)
|
|
381
|
+
|
|
382
|
+
self._hardware_api.set_current_tiprack_diameter(
|
|
383
|
+
mount=hw_mount,
|
|
384
|
+
tiprack_diameter=tip.diameter,
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
self._hardware_api.set_working_volume(
|
|
388
|
+
mount=hw_mount,
|
|
389
|
+
tip_volume=tip.volume,
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
def remove_tip(self, pipette_id: str) -> None:
|
|
393
|
+
"""See documentation on abstract base class."""
|
|
394
|
+
hw_mount = self._get_hw_mount(pipette_id)
|
|
395
|
+
self._hardware_api.remove_tip(hw_mount)
|
|
396
|
+
self._hardware_api.set_current_tiprack_diameter(hw_mount, 0)
|
|
397
|
+
|
|
398
|
+
async def get_tip_presence(self, pipette_id: str) -> TipPresenceStatus:
|
|
399
|
+
"""See documentation on abstract base class."""
|
|
400
|
+
try:
|
|
401
|
+
ot3api = ensure_ot3_hardware(hardware_api=self._hardware_api)
|
|
402
|
+
|
|
403
|
+
hw_mount = self._get_hw_mount(pipette_id)
|
|
404
|
+
|
|
405
|
+
status = await ot3api.get_tip_presence_status(hw_mount)
|
|
406
|
+
return TipPresenceStatus.from_hw_state(status)
|
|
407
|
+
except HardwareNotSupportedError:
|
|
408
|
+
# Tip presence sensing is not supported on the OT2
|
|
409
|
+
return TipPresenceStatus.UNKNOWN
|
|
410
|
+
|
|
411
|
+
async def verify_tip_presence(
|
|
412
|
+
self,
|
|
413
|
+
pipette_id: str,
|
|
414
|
+
expected: TipPresenceStatus,
|
|
415
|
+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
|
|
416
|
+
) -> None:
|
|
417
|
+
"""See documentation on abstract base class."""
|
|
418
|
+
try:
|
|
419
|
+
ot3api = ensure_ot3_hardware(hardware_api=self._hardware_api)
|
|
420
|
+
hw_mount = self._get_hw_mount(pipette_id)
|
|
421
|
+
await ot3api.verify_tip_presence(
|
|
422
|
+
hw_mount, expected.to_hw_state(), follow_singular_sensor
|
|
423
|
+
)
|
|
424
|
+
except HardwareNotSupportedError:
|
|
425
|
+
# Tip presence sensing is not supported on the OT2
|
|
426
|
+
pass
|
|
427
|
+
except FailedTipStateCheck as e:
|
|
428
|
+
if expected == TipPresenceStatus.ABSENT:
|
|
429
|
+
raise TipAttachedError(wrapping=[PythonException(e)])
|
|
430
|
+
elif expected == TipPresenceStatus.PRESENT:
|
|
431
|
+
raise TipNotAttachedError(wrapping=[PythonException(e)])
|
|
432
|
+
else:
|
|
433
|
+
raise ProtocolEngineError(
|
|
434
|
+
message="Unknown tip status in tip status check",
|
|
435
|
+
wrapping=[PythonException(e)],
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
def _get_hw_mount(self, pipette_id: str) -> Mount:
|
|
439
|
+
return self._state_view.pipettes.get_mount(pipette_id).to_hw_mount()
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
class VirtualTipHandler(TipHandler):
|
|
443
|
+
"""Pick up and drop tips, using a virtual pipette."""
|
|
444
|
+
|
|
445
|
+
def __init__(self, state_view: StateView) -> None:
|
|
446
|
+
self._state_view = state_view
|
|
447
|
+
|
|
448
|
+
async def pick_up_tip(
|
|
449
|
+
self,
|
|
450
|
+
pipette_id: str,
|
|
451
|
+
labware_id: str,
|
|
452
|
+
well_name: str,
|
|
453
|
+
do_not_ignore_tip_presence: bool = True,
|
|
454
|
+
) -> TipGeometry:
|
|
455
|
+
"""Pick up a tip at the current location using a virtual pipette.
|
|
456
|
+
|
|
457
|
+
- Fetch nominal tip geometry
|
|
458
|
+
- Check that there's no tip currently attached
|
|
459
|
+
"""
|
|
460
|
+
nominal_tip_geometry = self._state_view.geometry.get_nominal_tip_geometry(
|
|
461
|
+
pipette_id=pipette_id,
|
|
462
|
+
labware_id=labware_id,
|
|
463
|
+
well_name=well_name,
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
self._state_view.pipettes.validate_tip_state(
|
|
467
|
+
pipette_id=pipette_id,
|
|
468
|
+
expected_has_tip=False,
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
return nominal_tip_geometry
|
|
472
|
+
|
|
473
|
+
async def available_for_nozzle_layout(
|
|
474
|
+
self,
|
|
475
|
+
pipette_id: str,
|
|
476
|
+
style: str,
|
|
477
|
+
primary_nozzle: Optional[str] = None,
|
|
478
|
+
front_right_nozzle: Optional[str] = None,
|
|
479
|
+
back_left_nozzle: Optional[str] = None,
|
|
480
|
+
) -> Dict[str, str]:
|
|
481
|
+
"""See documentation on abstract base class."""
|
|
482
|
+
if self._state_view.pipettes.get_attached_tip(pipette_id):
|
|
483
|
+
raise CommandPreconditionViolated(
|
|
484
|
+
message=f"Cannot configure nozzle layout of {str(self)} while it has tips attached."
|
|
485
|
+
)
|
|
486
|
+
channels = self._state_view.pipettes.get_channels(pipette_id)
|
|
487
|
+
return await _available_for_nozzle_layout(
|
|
488
|
+
channels, style, primary_nozzle, front_right_nozzle, back_left_nozzle
|
|
489
|
+
)
|
|
490
|
+
|
|
491
|
+
async def drop_tip(
|
|
492
|
+
self,
|
|
493
|
+
pipette_id: str,
|
|
494
|
+
home_after: Optional[bool],
|
|
495
|
+
do_not_ignore_tip_presence: bool = True,
|
|
496
|
+
ignore_plunger: bool = False,
|
|
497
|
+
scrape_type: TipScrapeType = TipScrapeType.NONE,
|
|
498
|
+
) -> None:
|
|
499
|
+
"""Pick up a tip at the current location using a virtual pipette.
|
|
500
|
+
|
|
501
|
+
- Check that there's no tip currently attached
|
|
502
|
+
"""
|
|
503
|
+
self._state_view.pipettes.validate_tip_state(
|
|
504
|
+
pipette_id=pipette_id,
|
|
505
|
+
expected_has_tip=True,
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
def cache_tip(self, pipette_id: str, tip: TipGeometry) -> None:
|
|
509
|
+
"""See documentation on abstract base class.
|
|
510
|
+
|
|
511
|
+
This should not be called when using virtual pipettes.
|
|
512
|
+
"""
|
|
513
|
+
assert False, "TipHandler.cache_tip should not be used with virtual pipettes"
|
|
514
|
+
|
|
515
|
+
def remove_tip(self, pipette_id: str) -> None:
|
|
516
|
+
"""See documentation on abstract base class.
|
|
517
|
+
|
|
518
|
+
This should not be called when using virtual pipettes.
|
|
519
|
+
"""
|
|
520
|
+
assert False, "TipHandler.remove_tip should not be used with virtual pipettes"
|
|
521
|
+
|
|
522
|
+
async def verify_tip_presence(
|
|
523
|
+
self,
|
|
524
|
+
pipette_id: str,
|
|
525
|
+
expected: TipPresenceStatus,
|
|
526
|
+
follow_singular_sensor: Optional[InstrumentProbeType] = None,
|
|
527
|
+
) -> None:
|
|
528
|
+
"""Verify tip presence.
|
|
529
|
+
|
|
530
|
+
This should not be called when using virtual pipettes.
|
|
531
|
+
"""
|
|
532
|
+
|
|
533
|
+
async def get_tip_presence(self, pipette_id: str) -> TipPresenceStatus:
|
|
534
|
+
"""Get tip presence.
|
|
535
|
+
|
|
536
|
+
This is a check to the physical machine's sensors and should not be
|
|
537
|
+
called on a virtual pipette.
|
|
538
|
+
"""
|
|
539
|
+
raise RuntimeError("Do not call VirtualTipHandler.get_tip_presence")
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
def create_tip_handler(
|
|
543
|
+
state_view: StateView, hardware_api: HardwareControlAPI
|
|
544
|
+
) -> TipHandler:
|
|
545
|
+
"""Create a tip handler."""
|
|
546
|
+
return (
|
|
547
|
+
HardwareTipHandler(state_view=state_view, hardware_api=hardware_api)
|
|
548
|
+
if state_view.config.use_virtual_pipettes is False
|
|
549
|
+
else VirtualTipHandler(state_view=state_view)
|
|
550
|
+
)
|