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,151 @@
|
|
|
1
|
+
"""The interface that implements InstrumentContext."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from typing import Any, Generic, List, NamedTuple, Optional, TypeVar, Dict
|
|
7
|
+
|
|
8
|
+
from opentrons_shared_data.labware.types import (
|
|
9
|
+
LabwareUri,
|
|
10
|
+
LabwareParameters2,
|
|
11
|
+
LabwareParameters3,
|
|
12
|
+
LabwareDefinition as LabwareDefinitionDict,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from opentrons.types import DeckSlotName, Point, NozzleMapInterface
|
|
16
|
+
from .._liquid import Liquid
|
|
17
|
+
|
|
18
|
+
from .well import WellCoreType
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
_LabwareParametersDict = LabwareParameters2 | LabwareParameters3
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class LabwareLoadParams(NamedTuple):
|
|
25
|
+
"""Unique load parameters of a labware."""
|
|
26
|
+
|
|
27
|
+
namespace: str
|
|
28
|
+
load_name: str
|
|
29
|
+
version: int
|
|
30
|
+
|
|
31
|
+
def as_uri(self) -> LabwareUri:
|
|
32
|
+
"""Get the labware's definition URI from the load parameters."""
|
|
33
|
+
return LabwareUri(f"{self.namespace}/{self.load_name}/{self.version}")
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def from_uri(cls, uri: LabwareUri) -> LabwareLoadParams:
|
|
37
|
+
namespace, load_name, version_str = uri.split("/")
|
|
38
|
+
return cls(namespace, load_name, int(version_str))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AbstractLabware(ABC, Generic[WellCoreType]):
|
|
42
|
+
"""Labware implementation core interface."""
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
@abstractmethod
|
|
46
|
+
def load_name(self) -> str:
|
|
47
|
+
"""Get the labware's load name."""
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
@abstractmethod
|
|
51
|
+
def highest_z(self) -> float:
|
|
52
|
+
"""Get the Z coordinate of the labware's highest point"""
|
|
53
|
+
|
|
54
|
+
@abstractmethod
|
|
55
|
+
def get_uri(self) -> str:
|
|
56
|
+
"""Get the URI string string of the labware's definition.
|
|
57
|
+
|
|
58
|
+
The URI is unique for a given namespace, load name, and definition version.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
@abstractmethod
|
|
62
|
+
def get_load_params(self) -> LabwareLoadParams:
|
|
63
|
+
...
|
|
64
|
+
|
|
65
|
+
@abstractmethod
|
|
66
|
+
def get_display_name(self) -> str:
|
|
67
|
+
"""Get a display name for the labware, falling back to the definition."""
|
|
68
|
+
|
|
69
|
+
@abstractmethod
|
|
70
|
+
def get_user_display_name(self) -> Optional[str]:
|
|
71
|
+
"""Get the user-specified display name of the labware, if set."""
|
|
72
|
+
|
|
73
|
+
@abstractmethod
|
|
74
|
+
def get_name(self) -> str:
|
|
75
|
+
...
|
|
76
|
+
|
|
77
|
+
@abstractmethod
|
|
78
|
+
def get_definition(self) -> LabwareDefinitionDict:
|
|
79
|
+
"""Get the labware's definition as a plain dictionary."""
|
|
80
|
+
|
|
81
|
+
@abstractmethod
|
|
82
|
+
def get_parameters(self) -> _LabwareParametersDict:
|
|
83
|
+
"""Get the labware's definition's `parameters` field as a plain dictionary."""
|
|
84
|
+
|
|
85
|
+
@abstractmethod
|
|
86
|
+
def get_quirks(self) -> List[str]:
|
|
87
|
+
...
|
|
88
|
+
|
|
89
|
+
@abstractmethod
|
|
90
|
+
def set_calibration(self, delta: Point) -> None:
|
|
91
|
+
...
|
|
92
|
+
|
|
93
|
+
@abstractmethod
|
|
94
|
+
def get_calibrated_offset(self) -> Point:
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
@abstractmethod
|
|
98
|
+
def is_tip_rack(self) -> bool:
|
|
99
|
+
"""Whether the labware is a tip rack."""
|
|
100
|
+
|
|
101
|
+
@abstractmethod
|
|
102
|
+
def is_adapter(self) -> bool:
|
|
103
|
+
"""Whether the labware is an adapter."""
|
|
104
|
+
|
|
105
|
+
@abstractmethod
|
|
106
|
+
def is_lid(self) -> bool:
|
|
107
|
+
"""Whether the labware is a lid."""
|
|
108
|
+
|
|
109
|
+
@abstractmethod
|
|
110
|
+
def is_fixed_trash(self) -> bool:
|
|
111
|
+
"""Whether the labware is a fixed trash."""
|
|
112
|
+
|
|
113
|
+
@abstractmethod
|
|
114
|
+
def get_tip_length(self) -> float:
|
|
115
|
+
...
|
|
116
|
+
|
|
117
|
+
@abstractmethod
|
|
118
|
+
def reset_tips(self) -> None:
|
|
119
|
+
...
|
|
120
|
+
|
|
121
|
+
@abstractmethod
|
|
122
|
+
def get_next_tip(
|
|
123
|
+
self,
|
|
124
|
+
num_tips: int,
|
|
125
|
+
starting_tip: Optional[WellCoreType],
|
|
126
|
+
nozzle_map: Optional[NozzleMapInterface],
|
|
127
|
+
) -> Optional[str]:
|
|
128
|
+
"""Get the name of the next available tip(s) in the rack, if available."""
|
|
129
|
+
|
|
130
|
+
@abstractmethod
|
|
131
|
+
def get_well_columns(self) -> List[List[str]]:
|
|
132
|
+
"""Get the all well names, organized by column, from the labware's definition."""
|
|
133
|
+
|
|
134
|
+
@abstractmethod
|
|
135
|
+
def get_well_core(self, well_name: str) -> WellCoreType:
|
|
136
|
+
"""Get a well core interface to a given well in this labware."""
|
|
137
|
+
|
|
138
|
+
@abstractmethod
|
|
139
|
+
def get_deck_slot(self) -> Optional[DeckSlotName]:
|
|
140
|
+
"""Get the deck slot the labware or its parent is in, if any."""
|
|
141
|
+
|
|
142
|
+
@abstractmethod
|
|
143
|
+
def load_liquid(self, volumes: Dict[str, float], liquid: Liquid) -> None:
|
|
144
|
+
"""Load liquid into wells of the labware."""
|
|
145
|
+
|
|
146
|
+
@abstractmethod
|
|
147
|
+
def load_empty(self, wells: List[str]) -> None:
|
|
148
|
+
"""Mark wells of the labware as empty."""
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
LabwareCoreType = TypeVar("LabwareCoreType", bound=AbstractLabware[Any])
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""The Protocol API v2 context implementation package."""
|
|
2
|
+
# TODO(mc, 2022-08.22): uncomment when import cycles can be resolved
|
|
3
|
+
# from .legacy_protocol_core import LegacyProtocolCore
|
|
4
|
+
# from .legacy_instrument_core import LegacyInstrumentCore
|
|
5
|
+
# from .legacy_labware_core.py import LegacyLabwareCore
|
|
6
|
+
|
|
7
|
+
# __all__ = [
|
|
8
|
+
# "LegacyProtocolCore",
|
|
9
|
+
# "LegacyInstrumentCore",
|
|
10
|
+
# "LegacyLabwareCore",
|
|
11
|
+
# ]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from opentrons.types import Location, Point
|
|
2
|
+
from opentrons_shared_data.labware.types import LabwareDefinition2
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LabwareGeometry:
|
|
6
|
+
"""Convenience interface for accessing geometry properties of a labware."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, definition: LabwareDefinition2, parent: Location):
|
|
9
|
+
"""Constructor"""
|
|
10
|
+
self._parent = parent
|
|
11
|
+
offset = definition["cornerOffsetFromSlot"]
|
|
12
|
+
self._offset = Point(offset["x"], offset["y"], offset["z"]) + parent.point
|
|
13
|
+
|
|
14
|
+
dimensions = definition["dimensions"]
|
|
15
|
+
self._x_dimension = dimensions["xDimension"]
|
|
16
|
+
self._y_dimension = dimensions["yDimension"]
|
|
17
|
+
self._z_dimension = dimensions["zDimension"]
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def parent(self) -> Location:
|
|
21
|
+
return self._parent
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def offset(self) -> Point:
|
|
25
|
+
return self._offset
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def x_dimension(self) -> float:
|
|
29
|
+
return self._x_dimension
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def y_dimension(self) -> float:
|
|
33
|
+
return self._y_dimension
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def z_dimension(self) -> float:
|
|
37
|
+
return self._z_dimension
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
# NOTE(mc, 2022-12-05): this module is deprecated;
|
|
2
|
+
# do not add to it unless necessary and do not use in new code
|
|
3
|
+
import functools
|
|
4
|
+
import logging
|
|
5
|
+
from collections import UserDict
|
|
6
|
+
from typing import Dict, Optional, List, Union, Mapping
|
|
7
|
+
from typing_extensions import Protocol, Final
|
|
8
|
+
|
|
9
|
+
from opentrons_shared_data.deck import load as load_deck
|
|
10
|
+
|
|
11
|
+
from opentrons_shared_data.deck.types import SlotDefV3
|
|
12
|
+
from opentrons_shared_data.labware.types import LabwareUri
|
|
13
|
+
|
|
14
|
+
from opentrons.hardware_control.modules.types import ModuleType
|
|
15
|
+
from opentrons.motion_planning import deck_conflict
|
|
16
|
+
from opentrons.protocols.api_support.labware_like import LabwareLike
|
|
17
|
+
from opentrons.types import (
|
|
18
|
+
DeckLocation,
|
|
19
|
+
Location,
|
|
20
|
+
Mount,
|
|
21
|
+
Point,
|
|
22
|
+
DeckSlotName,
|
|
23
|
+
StagingSlotName,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
from opentrons.protocol_api.core.labware import AbstractLabware
|
|
27
|
+
from opentrons.protocol_api.deck import CalibrationPosition
|
|
28
|
+
from opentrons.protocol_api.labware import load as load_lw, Labware
|
|
29
|
+
|
|
30
|
+
from .legacy_labware_core import LegacyLabwareCore
|
|
31
|
+
from .module_geometry import ModuleGeometry, HeaterShakerGeometry, ThermocyclerGeometry
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
_log = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Amount of slots in a single deck row
|
|
38
|
+
ROW_LENGTH = 3
|
|
39
|
+
FIXED_TRASH_ID = "fixedTrash"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
DEFAULT_LEGACY_DECK_DEFINITION_VERSION: Final = 3
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class DeckItem(Protocol):
|
|
46
|
+
@property
|
|
47
|
+
def highest_z(self) -> float:
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def load_name(self) -> str:
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class Deck(UserDict): # type: ignore[type-arg]
|
|
56
|
+
data: Dict[int, Optional[DeckItem]]
|
|
57
|
+
|
|
58
|
+
def __init__(self, deck_type: str) -> None:
|
|
59
|
+
super().__init__()
|
|
60
|
+
self._definition = load_deck(
|
|
61
|
+
name=deck_type, version=DEFAULT_LEGACY_DECK_DEFINITION_VERSION
|
|
62
|
+
)
|
|
63
|
+
self._positions = {}
|
|
64
|
+
for slot in self._definition["locations"]["orderedSlots"]:
|
|
65
|
+
self.data[int(slot["id"])] = None
|
|
66
|
+
self._positions[int(slot["id"])] = Point(*slot["position"])
|
|
67
|
+
self._highest_z = 0.0
|
|
68
|
+
self._load_fixtures()
|
|
69
|
+
self._thermocycler_present = False
|
|
70
|
+
|
|
71
|
+
def _load_fixtures(self) -> None:
|
|
72
|
+
for f in self._definition["locations"]["fixtures"]:
|
|
73
|
+
slot_name = self._check_name(f["slot"]) # type: ignore
|
|
74
|
+
# TODO(mc, 2022-06-15): this loads the fixed trash as an instance of
|
|
75
|
+
# `opentrons.protocol_api.labware.Labware`
|
|
76
|
+
# However, all other labware will be added to the `Deck` as instances of
|
|
77
|
+
# `opentrons.protocol_api.core.labware.AbstractLabware`
|
|
78
|
+
# And modules will be added as instances of
|
|
79
|
+
# `opentrons.protocols.geometry.module_geometry.ModuleGeometry`
|
|
80
|
+
# This mix of public and private interfaces as members of a public
|
|
81
|
+
# `Deck` interface is confusing and should be resolved.
|
|
82
|
+
# If `Deck` is public, all items in a `Deck` should be
|
|
83
|
+
# instances of other public APIs.
|
|
84
|
+
loaded_f = load_lw(
|
|
85
|
+
f["labware"], self.position_for(slot_name) # type: ignore
|
|
86
|
+
)
|
|
87
|
+
self.__setitem__(slot_name, loaded_f)
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
@functools.lru_cache(20)
|
|
91
|
+
def _assure_int(key: object) -> int:
|
|
92
|
+
if isinstance(key, str):
|
|
93
|
+
return int(key)
|
|
94
|
+
elif isinstance(key, int):
|
|
95
|
+
return key
|
|
96
|
+
else:
|
|
97
|
+
raise TypeError(type(key))
|
|
98
|
+
|
|
99
|
+
def _check_name(self, key: object) -> int:
|
|
100
|
+
should_raise = False
|
|
101
|
+
try:
|
|
102
|
+
key_int = Deck._assure_int(key)
|
|
103
|
+
except Exception:
|
|
104
|
+
_log.exception("Bad slot name: {}".format(key))
|
|
105
|
+
should_raise = True
|
|
106
|
+
should_raise = should_raise or key_int not in self.data
|
|
107
|
+
if should_raise:
|
|
108
|
+
raise ValueError("Unknown slot: {}".format(key))
|
|
109
|
+
else:
|
|
110
|
+
return key_int
|
|
111
|
+
|
|
112
|
+
@staticmethod
|
|
113
|
+
def _map_to_conflict_checker_item(item: DeckItem) -> deck_conflict.DeckItem:
|
|
114
|
+
name_for_errors = item.load_name
|
|
115
|
+
|
|
116
|
+
# We have to account for both Labware and AbstractLabware because this class
|
|
117
|
+
# inappropriately contains both internal and customer-facing types.
|
|
118
|
+
# See todo comment in self._load_fixtures().
|
|
119
|
+
if isinstance(item, Labware):
|
|
120
|
+
is_fixed_trash = "fixedTrash" in item.quirks
|
|
121
|
+
return deck_conflict.Labware(
|
|
122
|
+
highest_z=item.highest_z,
|
|
123
|
+
name_for_errors=name_for_errors,
|
|
124
|
+
# TODO(mm, 2023-02-16): Refactor item.uri to return LabwareUri.
|
|
125
|
+
uri=LabwareUri(item.uri),
|
|
126
|
+
is_fixed_trash=is_fixed_trash,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
elif isinstance(item, AbstractLabware):
|
|
130
|
+
is_fixed_trash = "fixedTrash" in item.get_quirks()
|
|
131
|
+
return deck_conflict.Labware(
|
|
132
|
+
highest_z=item.highest_z,
|
|
133
|
+
name_for_errors=name_for_errors,
|
|
134
|
+
# TODO(mm, 2023-02-16): Refactor item.uri to return LabwareUri.
|
|
135
|
+
uri=LabwareUri(item.get_uri()),
|
|
136
|
+
is_fixed_trash=is_fixed_trash,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
elif isinstance(item, HeaterShakerGeometry):
|
|
140
|
+
return deck_conflict.HeaterShakerModule(
|
|
141
|
+
highest_z_including_labware=item.highest_z,
|
|
142
|
+
name_for_errors=name_for_errors,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
elif isinstance(item, ThermocyclerGeometry):
|
|
146
|
+
return deck_conflict.ThermocyclerModule(
|
|
147
|
+
highest_z_including_labware=item.highest_z,
|
|
148
|
+
name_for_errors=name_for_errors,
|
|
149
|
+
is_semi_configuration=item.is_semi_configuration,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
elif isinstance(item, ModuleGeometry):
|
|
153
|
+
return deck_conflict.OtherModule(
|
|
154
|
+
highest_z_including_labware=item.highest_z,
|
|
155
|
+
name_for_errors=name_for_errors,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
else:
|
|
159
|
+
assert False, f"Deck item {item} has an unknown type."
|
|
160
|
+
|
|
161
|
+
def __getitem__(self, key: DeckLocation) -> Optional[DeckItem]:
|
|
162
|
+
return self.data[self._check_name(key)]
|
|
163
|
+
|
|
164
|
+
def __delitem__(self, key: DeckLocation) -> None:
|
|
165
|
+
checked_key = self._check_name(key)
|
|
166
|
+
old = self.data[checked_key]
|
|
167
|
+
self.data[checked_key] = None
|
|
168
|
+
if old:
|
|
169
|
+
self.recalculate_high_z()
|
|
170
|
+
# Update the thermocycler present member
|
|
171
|
+
self._thermocycler_present = any(
|
|
172
|
+
isinstance(item, ThermocyclerGeometry) for item in self.data.values()
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
def __setitem__(self, key: DeckLocation, val: DeckItem) -> None:
|
|
176
|
+
slot_key_int = self._check_name(key)
|
|
177
|
+
existing_items: Mapping[
|
|
178
|
+
Union[DeckSlotName, StagingSlotName], deck_conflict.DeckItem
|
|
179
|
+
] = {
|
|
180
|
+
DeckSlotName.from_primitive(slot): self._map_to_conflict_checker_item(item)
|
|
181
|
+
for slot, item in self.data.items()
|
|
182
|
+
if item is not None
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# will raise DeckConflictError if items conflict
|
|
186
|
+
deck_conflict.check(
|
|
187
|
+
existing_items=existing_items,
|
|
188
|
+
new_location=DeckSlotName.from_primitive(slot_key_int),
|
|
189
|
+
new_item=self._map_to_conflict_checker_item(val),
|
|
190
|
+
robot_type=self._definition["robot"]["model"],
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
self.data[slot_key_int] = val
|
|
194
|
+
self.recalculate_high_z()
|
|
195
|
+
self._thermocycler_present = any(
|
|
196
|
+
isinstance(item, ThermocyclerGeometry) for item in self.data.values()
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
def __contains__(self, key: object) -> bool:
|
|
200
|
+
try:
|
|
201
|
+
key_int = self._check_name(key)
|
|
202
|
+
except ValueError:
|
|
203
|
+
return False
|
|
204
|
+
return key_int in self.data
|
|
205
|
+
|
|
206
|
+
def is_edge_move_unsafe(self, mount: Mount, target: "Labware") -> bool:
|
|
207
|
+
"""
|
|
208
|
+
Check if slot next to target labware contains a module. Only relevant
|
|
209
|
+
depending on the mount you are using and the column you are moving
|
|
210
|
+
to inside of the labware.
|
|
211
|
+
"""
|
|
212
|
+
slot = LabwareLike(target).first_parent()
|
|
213
|
+
if not slot:
|
|
214
|
+
return False
|
|
215
|
+
if mount is Mount.RIGHT:
|
|
216
|
+
other_labware = self.left_of(slot)
|
|
217
|
+
else:
|
|
218
|
+
other_labware = self.right_of(slot)
|
|
219
|
+
|
|
220
|
+
return isinstance(other_labware, ModuleGeometry)
|
|
221
|
+
|
|
222
|
+
def right_of(self, slot: str) -> Optional[DeckItem]:
|
|
223
|
+
if int(slot) % ROW_LENGTH == 0:
|
|
224
|
+
# We know we're at the right-most edge
|
|
225
|
+
# of the given row
|
|
226
|
+
return None
|
|
227
|
+
else:
|
|
228
|
+
idx = int(slot) + 1
|
|
229
|
+
return self[str(idx)]
|
|
230
|
+
|
|
231
|
+
def left_of(self, slot: str) -> Optional[DeckItem]:
|
|
232
|
+
if int(slot) - 1 % ROW_LENGTH == 0:
|
|
233
|
+
# We know we're at the left-most edge
|
|
234
|
+
# of the given row
|
|
235
|
+
return None
|
|
236
|
+
idx = int(slot) - 1
|
|
237
|
+
if idx < 1:
|
|
238
|
+
return None
|
|
239
|
+
return self[str(idx)]
|
|
240
|
+
|
|
241
|
+
def position_for(self, key: DeckLocation) -> Location:
|
|
242
|
+
key_int = self._check_name(key)
|
|
243
|
+
return Location(self._positions[key_int], str(key))
|
|
244
|
+
|
|
245
|
+
def recalculate_high_z(self) -> None:
|
|
246
|
+
self._highest_z = 0.0
|
|
247
|
+
for item in [lw for lw in self.data.values() if lw]:
|
|
248
|
+
self._highest_z = max(item.highest_z, self._highest_z)
|
|
249
|
+
|
|
250
|
+
def get_slot_definition(self, slot_name: str) -> SlotDefV3:
|
|
251
|
+
slots = self._definition["locations"]["orderedSlots"]
|
|
252
|
+
slot_def = next((slot for slot in slots if slot["id"] == slot_name), None)
|
|
253
|
+
if not slot_def:
|
|
254
|
+
slot_ids = [slot["id"] for slot in slots]
|
|
255
|
+
raise ValueError(
|
|
256
|
+
f"slot {slot_name} could not be found,"
|
|
257
|
+
f"valid deck slots are: {slot_ids}"
|
|
258
|
+
)
|
|
259
|
+
return slot_def
|
|
260
|
+
|
|
261
|
+
def get_slot_center(self, slot_name: str) -> Point:
|
|
262
|
+
defn = self.get_slot_definition(slot_name)
|
|
263
|
+
return Point(
|
|
264
|
+
defn["position"][0] + defn["boundingBox"]["xDimension"] / 2,
|
|
265
|
+
defn["position"][1] + defn["boundingBox"]["yDimension"] / 2,
|
|
266
|
+
defn["position"][2] + defn["boundingBox"]["zDimension"] / 2,
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
def resolve_module_location(
|
|
270
|
+
self, module_type: ModuleType, location: Optional[DeckLocation]
|
|
271
|
+
) -> DeckLocation:
|
|
272
|
+
dn_from_type = {
|
|
273
|
+
ModuleType.MAGNETIC: "Magnetic Module",
|
|
274
|
+
ModuleType.THERMOCYCLER: "Thermocycler",
|
|
275
|
+
ModuleType.TEMPERATURE: "Temperature Module",
|
|
276
|
+
ModuleType.HEATER_SHAKER: "Heater-Shaker",
|
|
277
|
+
}
|
|
278
|
+
if isinstance(location, str) or isinstance(location, int):
|
|
279
|
+
slot_def = self.get_slot_definition(str(location))
|
|
280
|
+
compatible_modules = slot_def["compatibleModuleTypes"]
|
|
281
|
+
if module_type.value in compatible_modules:
|
|
282
|
+
return location
|
|
283
|
+
elif (
|
|
284
|
+
self._definition["robot"]["model"] == "OT-3 Standard"
|
|
285
|
+
and ModuleType.to_module_fixture_id(module_type) == slot_def["id"]
|
|
286
|
+
):
|
|
287
|
+
return location
|
|
288
|
+
else:
|
|
289
|
+
raise ValueError(
|
|
290
|
+
f"A {dn_from_type[module_type]} cannot be loaded"
|
|
291
|
+
f" into slot {location}"
|
|
292
|
+
)
|
|
293
|
+
else:
|
|
294
|
+
valid_slots = [
|
|
295
|
+
slot["id"]
|
|
296
|
+
for slot in self.slots
|
|
297
|
+
if module_type.value in slot["compatibleModuleTypes"]
|
|
298
|
+
]
|
|
299
|
+
if len(valid_slots) == 1:
|
|
300
|
+
return valid_slots[0]
|
|
301
|
+
elif not valid_slots:
|
|
302
|
+
raise ValueError(
|
|
303
|
+
"A {dn_from_type[module_type]} cannot be used with this deck"
|
|
304
|
+
)
|
|
305
|
+
else:
|
|
306
|
+
raise ValueError(
|
|
307
|
+
f"{dn_from_type[module_type]}s do not have default"
|
|
308
|
+
" location, you must specify a slot"
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
@property
|
|
312
|
+
def highest_z(self) -> float:
|
|
313
|
+
"""Return the tallest known point on the deck."""
|
|
314
|
+
return self._highest_z
|
|
315
|
+
|
|
316
|
+
@property
|
|
317
|
+
def slots(self) -> List[SlotDefV3]:
|
|
318
|
+
"""Return the definition of the loaded robot deck."""
|
|
319
|
+
return self._definition["locations"]["orderedSlots"]
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def calibration_positions(self) -> List[CalibrationPosition]:
|
|
323
|
+
raw_positions = self._definition["locations"]["calibrationPoints"]
|
|
324
|
+
return [
|
|
325
|
+
CalibrationPosition(
|
|
326
|
+
id=raw_position["id"],
|
|
327
|
+
displayName=raw_position["displayName"],
|
|
328
|
+
position=(
|
|
329
|
+
raw_position["position"][0],
|
|
330
|
+
raw_position["position"][1],
|
|
331
|
+
raw_position["position"][2],
|
|
332
|
+
),
|
|
333
|
+
)
|
|
334
|
+
for raw_position in raw_positions
|
|
335
|
+
]
|
|
336
|
+
|
|
337
|
+
def get_calibration_position(self, id: str) -> CalibrationPosition:
|
|
338
|
+
calibration_position = next(
|
|
339
|
+
(pos for pos in self.calibration_positions if pos.id == id), None
|
|
340
|
+
)
|
|
341
|
+
if not calibration_position:
|
|
342
|
+
pos_ids = [pos.id for pos in self.calibration_positions]
|
|
343
|
+
raise ValueError(
|
|
344
|
+
f"calibration position {id} "
|
|
345
|
+
"could not be found, "
|
|
346
|
+
f"valid calibration position ids are: {pos_ids}"
|
|
347
|
+
)
|
|
348
|
+
return calibration_position
|
|
349
|
+
|
|
350
|
+
def get_fixed_trash(self) -> Optional[Union[Labware, LegacyLabwareCore]]:
|
|
351
|
+
fixtures = self._definition["locations"]["fixtures"]
|
|
352
|
+
ft = next((f for f in fixtures if f["id"] == FIXED_TRASH_ID), None)
|
|
353
|
+
|
|
354
|
+
# NOTE(mc, 2022-12-06): type ignore below because this `Deck` is typed
|
|
355
|
+
# as contiaining `DeckItem` values, but the contents of slot 12
|
|
356
|
+
# will always be limited to either a `Labware` or `LegacyLabwareCore` object
|
|
357
|
+
return self.data[self._check_name(ft.get("slot"))] if ft else None # type: ignore[return-value]
|
|
358
|
+
|
|
359
|
+
def get_non_fixture_slots(self) -> List[int]:
|
|
360
|
+
fixtures = self._definition["locations"]["fixtures"]
|
|
361
|
+
fixture_slots = {
|
|
362
|
+
self._check_name(f.get("slot")) for f in fixtures if f.get("slot")
|
|
363
|
+
}
|
|
364
|
+
return [s for s in self.data.keys() if s not in fixture_slots]
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def thermocycler_present(self) -> bool:
|
|
368
|
+
"""Is a thermocycler present on the deck."""
|
|
369
|
+
return self._thermocycler_present
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from opentrons.hardware_control.modules import ModuleModel as HardwareModuleModel
|
|
6
|
+
from opentrons.protocol_engine import (
|
|
7
|
+
ProtocolEngine,
|
|
8
|
+
LegacyLabwareOffsetLocation,
|
|
9
|
+
ModuleModel,
|
|
10
|
+
)
|
|
11
|
+
from opentrons.types import DeckSlotName, Point
|
|
12
|
+
|
|
13
|
+
from ..labware import LabwareLoadParams
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class ProvidedLabwareOffset:
|
|
18
|
+
"""A labware offset provided externally.
|
|
19
|
+
|
|
20
|
+
Parameters:
|
|
21
|
+
delta: The positional adjustment that should apply to all movements
|
|
22
|
+
to this labware. Measured in deck coordinates, from the nominal
|
|
23
|
+
position to the adjusted position.
|
|
24
|
+
offset_id: An ID referencing the relevant external offset resource.
|
|
25
|
+
`None` means no matching offset.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
delta: Point
|
|
29
|
+
offset_id: Optional[str]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class AbstractLabwareOffsetProvider(ABC):
|
|
33
|
+
@abstractmethod
|
|
34
|
+
def find(
|
|
35
|
+
self,
|
|
36
|
+
load_params: LabwareLoadParams,
|
|
37
|
+
requested_module_model: Optional[HardwareModuleModel],
|
|
38
|
+
deck_slot: DeckSlotName,
|
|
39
|
+
) -> ProvidedLabwareOffset:
|
|
40
|
+
"""Return the offset that should apply to a newly loaded labware.
|
|
41
|
+
|
|
42
|
+
An APIv2 protocol's `ProtocolContext` should call this once for each labware,
|
|
43
|
+
as it loads it.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
labware_definition_uri: The labware's definition URI.
|
|
47
|
+
requested_module_model: If the labware is atop a module,
|
|
48
|
+
the model of that module.
|
|
49
|
+
To ensure stability between simulation and execution,
|
|
50
|
+
this is the model that the protocol requested,
|
|
51
|
+
not the model that was actually found via the hardware API.
|
|
52
|
+
(They can be different because of module compatibility.)
|
|
53
|
+
deck_slot: The deck slot that the labware occupies. Or, if the labware is
|
|
54
|
+
atop a module, the deck slot that the module occupies.
|
|
55
|
+
"""
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class NullLabwareOffsetProvider(AbstractLabwareOffsetProvider):
|
|
60
|
+
"""Always provides (0, 0, 0)."""
|
|
61
|
+
|
|
62
|
+
def find(
|
|
63
|
+
self,
|
|
64
|
+
load_params: LabwareLoadParams,
|
|
65
|
+
requested_module_model: Optional[HardwareModuleModel],
|
|
66
|
+
deck_slot: DeckSlotName,
|
|
67
|
+
) -> ProvidedLabwareOffset:
|
|
68
|
+
return ProvidedLabwareOffset(delta=Point(0, 0, 0), offset_id=None)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class LabwareOffsetProvider(AbstractLabwareOffsetProvider):
|
|
72
|
+
"""Provides a `ProtocolEngine`'s labware offsets."""
|
|
73
|
+
|
|
74
|
+
def __init__(self, engine: ProtocolEngine) -> None:
|
|
75
|
+
"""Initialize an offset provider with access to ProtocolEngine state."""
|
|
76
|
+
self._labware_view = engine.state_view.labware
|
|
77
|
+
|
|
78
|
+
def find(
|
|
79
|
+
self,
|
|
80
|
+
load_params: LabwareLoadParams,
|
|
81
|
+
requested_module_model: Optional[HardwareModuleModel],
|
|
82
|
+
deck_slot: DeckSlotName,
|
|
83
|
+
) -> ProvidedLabwareOffset:
|
|
84
|
+
"""Look up an offset in ProtocolEngine state and return it, if one exists.
|
|
85
|
+
|
|
86
|
+
See the parent class for param details.
|
|
87
|
+
"""
|
|
88
|
+
offset = self._labware_view.find_applicable_labware_offset_by_legacy_location(
|
|
89
|
+
definition_uri=load_params.as_uri(),
|
|
90
|
+
location=LegacyLabwareOffsetLocation(
|
|
91
|
+
slotName=deck_slot,
|
|
92
|
+
moduleModel=(
|
|
93
|
+
None
|
|
94
|
+
if requested_module_model is None
|
|
95
|
+
else ModuleModel(requested_module_model.value)
|
|
96
|
+
),
|
|
97
|
+
),
|
|
98
|
+
)
|
|
99
|
+
if offset is None:
|
|
100
|
+
return ProvidedLabwareOffset(
|
|
101
|
+
delta=Point(x=0, y=0, z=0),
|
|
102
|
+
offset_id=None,
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
return ProvidedLabwareOffset(
|
|
106
|
+
delta=Point(x=offset.vector.x, y=offset.vector.y, z=offset.vector.z),
|
|
107
|
+
offset_id=offset.id,
|
|
108
|
+
)
|