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,422 @@
|
|
|
1
|
+
from typing import Dict, List, Optional, Any, Sequence, Iterator, Tuple, cast
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from collections import OrderedDict
|
|
4
|
+
from itertools import chain
|
|
5
|
+
|
|
6
|
+
from opentrons.hardware_control.types import CriticalPoint
|
|
7
|
+
from opentrons.types import (
|
|
8
|
+
Point,
|
|
9
|
+
NozzleConfigurationType,
|
|
10
|
+
)
|
|
11
|
+
from opentrons_shared_data.pipette.pipette_definition import (
|
|
12
|
+
PipetteGeometryDefinition,
|
|
13
|
+
PipetteRowDefinition,
|
|
14
|
+
ValidNozzleMaps,
|
|
15
|
+
)
|
|
16
|
+
from opentrons_shared_data.errors import ErrorCodes, GeneralError, PythonException
|
|
17
|
+
|
|
18
|
+
MAXIMUM_NOZZLE_COUNT = 24
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _nozzle_names_by_row(rows: List[PipetteRowDefinition]) -> Iterator[str]:
|
|
22
|
+
for row in rows:
|
|
23
|
+
for nozzle in row.ordered_nozzles:
|
|
24
|
+
yield nozzle
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _row_or_col_index_for_nozzle(
|
|
28
|
+
row_or_col: "OrderedDict[str, List[str]]", nozzle: str
|
|
29
|
+
) -> int:
|
|
30
|
+
for index, row_or_col_contents in enumerate(row_or_col.values()):
|
|
31
|
+
if nozzle in row_or_col_contents:
|
|
32
|
+
return index
|
|
33
|
+
raise KeyError(nozzle)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _row_col_indices_for_nozzle(
|
|
37
|
+
rows: "OrderedDict[str, List[str]]",
|
|
38
|
+
cols: "OrderedDict[str, List[str]]",
|
|
39
|
+
nozzle: str,
|
|
40
|
+
) -> Tuple[int, int]:
|
|
41
|
+
return _row_or_col_index_for_nozzle(rows, nozzle), _row_or_col_index_for_nozzle(
|
|
42
|
+
cols, nozzle
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class NozzleMap:
|
|
48
|
+
"""
|
|
49
|
+
A NozzleMap instance represents a specific configuration of active nozzles on a pipette.
|
|
50
|
+
|
|
51
|
+
It exposes properties of the configuration like the configuration's front-right, front-left,
|
|
52
|
+
back-left and starting nozzles as well as a map of all the nozzles active in the configuration.
|
|
53
|
+
|
|
54
|
+
Because NozzleMaps represent configurations directly, the properties of the NozzleMap may not
|
|
55
|
+
match the properties of the physical pipette. For instance, a NozzleMap for a single channel
|
|
56
|
+
configuration of an 8-channel pipette - say, A1 only - will have its front left, front right,
|
|
57
|
+
and active channels all be A1, while the physical configuration would have the front right
|
|
58
|
+
channel be H1.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
starting_nozzle: str
|
|
62
|
+
#: The nozzle that automated operations that count nozzles should start at
|
|
63
|
+
# these are really ordered dicts but you can't say that even in quotes because pydantic needs to
|
|
64
|
+
# evaluate them to generate serdes code so please only use ordered dicts here
|
|
65
|
+
map_store: Dict[str, Point]
|
|
66
|
+
#: A map of all of the nozzles active in this configuration
|
|
67
|
+
valid_map_key: str
|
|
68
|
+
#: A key indicating which valid nozzle map from the pipette definition represents this configuration
|
|
69
|
+
rows: Dict[str, List[str]]
|
|
70
|
+
#: A map of all the rows active in this configuration
|
|
71
|
+
columns: Dict[str, List[str]]
|
|
72
|
+
#: A map of all the columns active in this configuration
|
|
73
|
+
configuration: NozzleConfigurationType
|
|
74
|
+
#: The kind of configuration this is
|
|
75
|
+
|
|
76
|
+
full_instrument_map_store: Dict[str, Point]
|
|
77
|
+
#: A map of all of the nozzles of an instrument
|
|
78
|
+
full_instrument_rows: Dict[str, List[str]]
|
|
79
|
+
#: A map of all the rows of an instrument
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def determine_nozzle_configuration(
|
|
83
|
+
cls,
|
|
84
|
+
physical_rows: "OrderedDict[str, List[str]]",
|
|
85
|
+
current_rows: "OrderedDict[str, List[str]]",
|
|
86
|
+
physical_cols: "OrderedDict[str, List[str]]",
|
|
87
|
+
current_cols: "OrderedDict[str, List[str]]",
|
|
88
|
+
) -> "NozzleConfigurationType":
|
|
89
|
+
"""
|
|
90
|
+
Determine the nozzle configuration based on the starting and
|
|
91
|
+
ending nozzle.
|
|
92
|
+
"""
|
|
93
|
+
if physical_rows == current_rows and physical_cols == current_cols:
|
|
94
|
+
return NozzleConfigurationType.FULL
|
|
95
|
+
if len(current_rows) == 1 and len(current_cols) == 1:
|
|
96
|
+
return NozzleConfigurationType.SINGLE
|
|
97
|
+
if len(current_rows) == 1:
|
|
98
|
+
return NozzleConfigurationType.ROW
|
|
99
|
+
if len(current_cols) == 1:
|
|
100
|
+
return NozzleConfigurationType.COLUMN
|
|
101
|
+
return NozzleConfigurationType.SUBRECT
|
|
102
|
+
|
|
103
|
+
def __str__(self) -> str:
|
|
104
|
+
return f"back_left_nozzle: {self.back_left} front_right_nozzle: {self.front_right} configuration: {self.configuration}"
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def back_left(self) -> str:
|
|
108
|
+
"""The backest, leftest (i.e. back if it's a column, left if it's a row) nozzle of the configuration.
|
|
109
|
+
|
|
110
|
+
Note: This is the value relevant for this particular configuration, and it may not represent the back left nozzle
|
|
111
|
+
of the underlying physical pipette. For instance, the back-left nozzle of a configuration representing nozzles
|
|
112
|
+
D7 to H12 of a 96-channel pipette is D7, which is not the back-left nozzle of the physical pipette (A1).
|
|
113
|
+
"""
|
|
114
|
+
return next(iter(self.rows.values()))[0]
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def front_right(self) -> str:
|
|
118
|
+
"""The frontest, rightest (i.e. front if it's a column, right if it's a row) nozzle of the configuration.
|
|
119
|
+
|
|
120
|
+
Note: This is the value relevant for this configuration, not the physical pipette. See the note on back_left.
|
|
121
|
+
"""
|
|
122
|
+
return next(reversed(list(self.rows.values())))[-1]
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def full_instrument_back_left(self) -> str:
|
|
126
|
+
"""The backest, leftest (i.e. back if it's a column, left if it's a row) nozzle of the full instrument.
|
|
127
|
+
|
|
128
|
+
Note: This value represents the back left nozzle of the underlying physical pipette. For instance,
|
|
129
|
+
the back-left nozzle of a 96-Channel pipette is A1.
|
|
130
|
+
"""
|
|
131
|
+
return next(iter(self.full_instrument_rows.values()))[0]
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def full_instrument_front_right(self) -> str:
|
|
135
|
+
"""The frontest, rightest (i.e. front if it's a column, right if it's a row) nozzle of the full instrument.
|
|
136
|
+
|
|
137
|
+
Note: This value represents the front right nozzle of the physical pipette. See the note on full_instrument_back_left.
|
|
138
|
+
"""
|
|
139
|
+
return next(reversed(list(self.full_instrument_rows.values())))[-1]
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def starting_nozzle_offset(self) -> Point:
|
|
143
|
+
"""The position of the starting nozzle."""
|
|
144
|
+
return self.map_store[self.starting_nozzle]
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def xy_center_offset(self) -> Point:
|
|
148
|
+
"""The position of the geometrical center of all nozzles in the configuration.
|
|
149
|
+
|
|
150
|
+
Note: This is the value relevant for this configuration, not the physical pipette. See the note on back_left.
|
|
151
|
+
"""
|
|
152
|
+
difference = self.map_store[self.front_right] - self.map_store[self.back_left]
|
|
153
|
+
return self.map_store[self.back_left] + Point(
|
|
154
|
+
difference[0] / 2, difference[1] / 2, 0
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def instrument_xy_center_offset(self) -> Point:
|
|
159
|
+
"""The position of the geometrical center of all nozzles for the entire instrument.
|
|
160
|
+
|
|
161
|
+
Note: This the value reflects the center of the maximum number of nozzles of the physical pipette.
|
|
162
|
+
This would be the same as a full configuration.
|
|
163
|
+
"""
|
|
164
|
+
difference = (
|
|
165
|
+
self.full_instrument_map_store[self.full_instrument_front_right]
|
|
166
|
+
- self.full_instrument_map_store[self.full_instrument_back_left]
|
|
167
|
+
)
|
|
168
|
+
return self.full_instrument_map_store[self.full_instrument_back_left] + Point(
|
|
169
|
+
difference[0] / 2, difference[1] / 2, 0
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def y_center_offset(self) -> Point:
|
|
174
|
+
"""The position in the center of the primary column of the map."""
|
|
175
|
+
front_left = next(reversed(list(self.rows.values())))[0]
|
|
176
|
+
difference = self.map_store[front_left] - self.map_store[self.back_left]
|
|
177
|
+
return self.map_store[self.back_left] + Point(0, difference[1] / 2, 0)
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def front_nozzle_offset(self) -> Point:
|
|
181
|
+
"""The offset for the front_left nozzle."""
|
|
182
|
+
# front left-most nozzle of the 96 channel in a given configuration
|
|
183
|
+
# and front nozzle of the 8 channel
|
|
184
|
+
front_left = next(iter(self.columns.values()))[-1]
|
|
185
|
+
return self.map_store[front_left]
|
|
186
|
+
|
|
187
|
+
@property
|
|
188
|
+
def front_right_nozzle_offset(self) -> Point:
|
|
189
|
+
"""The offset for the front_right nozzle."""
|
|
190
|
+
# Front-right-most nozzle of the 96 channel in a given configuration
|
|
191
|
+
# and Front-most nozzle of the 8-channel
|
|
192
|
+
return self.map_store[self.front_right]
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def back_left_nozzle_offset(self) -> Point:
|
|
196
|
+
"""The offset for the back_left nozzle."""
|
|
197
|
+
# Back-left-most nozzle of the 96-channel in a given configuration
|
|
198
|
+
# and back-most nozzle of the 8-channel
|
|
199
|
+
return self.map_store[self.back_left]
|
|
200
|
+
|
|
201
|
+
@property
|
|
202
|
+
def tip_count(self) -> int:
|
|
203
|
+
"""The total number of active nozzles in the configuration, and thus the number of tips that will be picked up."""
|
|
204
|
+
return len(self.map_store)
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def physical_nozzle_count(self) -> int:
|
|
208
|
+
"""The number of physical nozzles, regardless of configuration."""
|
|
209
|
+
return len(self.full_instrument_map_store)
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def active_nozzles(self) -> list[str]:
|
|
213
|
+
"""An unstructured list of all nozzles active in the configuration."""
|
|
214
|
+
return list(self.map_store.keys())
|
|
215
|
+
|
|
216
|
+
@classmethod
|
|
217
|
+
def build( # noqa: C901
|
|
218
|
+
cls,
|
|
219
|
+
physical_nozzles: "OrderedDict[str, Point]",
|
|
220
|
+
physical_rows: "OrderedDict[str, List[str]]",
|
|
221
|
+
physical_columns: "OrderedDict[str, List[str]]",
|
|
222
|
+
starting_nozzle: str,
|
|
223
|
+
back_left_nozzle: str,
|
|
224
|
+
front_right_nozzle: str,
|
|
225
|
+
valid_nozzle_maps: ValidNozzleMaps,
|
|
226
|
+
) -> "NozzleMap":
|
|
227
|
+
try:
|
|
228
|
+
back_left_row_index, back_left_column_index = _row_col_indices_for_nozzle(
|
|
229
|
+
physical_rows, physical_columns, back_left_nozzle
|
|
230
|
+
)
|
|
231
|
+
except KeyError as e:
|
|
232
|
+
raise IncompatibleNozzleConfiguration(
|
|
233
|
+
message=f"No entry for back left nozzle {e} in pipette",
|
|
234
|
+
wrapping=[PythonException(e)],
|
|
235
|
+
) from e
|
|
236
|
+
try:
|
|
237
|
+
(
|
|
238
|
+
front_right_row_index,
|
|
239
|
+
front_right_column_index,
|
|
240
|
+
) = _row_col_indices_for_nozzle(
|
|
241
|
+
physical_rows, physical_columns, front_right_nozzle
|
|
242
|
+
)
|
|
243
|
+
except KeyError as e:
|
|
244
|
+
raise IncompatibleNozzleConfiguration(
|
|
245
|
+
message=f"No entry for front right nozzle {e} in pipette",
|
|
246
|
+
wrapping=[PythonException(e)],
|
|
247
|
+
) from e
|
|
248
|
+
|
|
249
|
+
correct_rows_with_all_columns = list(physical_rows.items())[
|
|
250
|
+
back_left_row_index : front_right_row_index + 1
|
|
251
|
+
]
|
|
252
|
+
correct_rows = [
|
|
253
|
+
(
|
|
254
|
+
row_name,
|
|
255
|
+
row_entries[back_left_column_index : front_right_column_index + 1],
|
|
256
|
+
)
|
|
257
|
+
for row_name, row_entries in correct_rows_with_all_columns
|
|
258
|
+
]
|
|
259
|
+
rows = OrderedDict(correct_rows)
|
|
260
|
+
correct_columns_with_all_rows = list(physical_columns.items())[
|
|
261
|
+
back_left_column_index : front_right_column_index + 1
|
|
262
|
+
]
|
|
263
|
+
correct_columns = [
|
|
264
|
+
(col_name, col_entries[back_left_row_index : front_right_row_index + 1])
|
|
265
|
+
for col_name, col_entries in correct_columns_with_all_rows
|
|
266
|
+
]
|
|
267
|
+
columns = OrderedDict(correct_columns)
|
|
268
|
+
|
|
269
|
+
map_store = OrderedDict(
|
|
270
|
+
(nozzle, physical_nozzles[nozzle]) for nozzle in chain(*rows.values())
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
if (
|
|
274
|
+
cls.determine_nozzle_configuration(
|
|
275
|
+
physical_rows, rows, physical_columns, columns
|
|
276
|
+
)
|
|
277
|
+
!= NozzleConfigurationType.FULL
|
|
278
|
+
):
|
|
279
|
+
if len(rows) * len(columns) > MAXIMUM_NOZZLE_COUNT:
|
|
280
|
+
raise IncompatibleNozzleConfiguration(
|
|
281
|
+
f"Partial Nozzle Layouts may not be configured to contain more than {MAXIMUM_NOZZLE_COUNT} channels."
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
validated_map_key = None
|
|
285
|
+
for map_key in valid_nozzle_maps.maps.keys():
|
|
286
|
+
if valid_nozzle_maps.maps[map_key] == list(map_store.keys()):
|
|
287
|
+
validated_map_key = map_key
|
|
288
|
+
break
|
|
289
|
+
|
|
290
|
+
if validated_map_key is None:
|
|
291
|
+
raise IncompatibleNozzleConfiguration(
|
|
292
|
+
"Attempted Nozzle Configuration does not match any approved map layout for the current pipette."
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
return cls(
|
|
296
|
+
starting_nozzle=starting_nozzle,
|
|
297
|
+
map_store=map_store,
|
|
298
|
+
valid_map_key=validated_map_key,
|
|
299
|
+
rows=rows,
|
|
300
|
+
full_instrument_map_store=physical_nozzles,
|
|
301
|
+
full_instrument_rows=physical_rows,
|
|
302
|
+
columns=columns,
|
|
303
|
+
configuration=cls.determine_nozzle_configuration(
|
|
304
|
+
physical_rows, rows, physical_columns, columns
|
|
305
|
+
),
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
class IncompatibleNozzleConfiguration(GeneralError):
|
|
310
|
+
"""Error raised if nozzle configuration is incompatible with the currently loaded pipette."""
|
|
311
|
+
|
|
312
|
+
def __init__(
|
|
313
|
+
self,
|
|
314
|
+
message: Optional[str] = None,
|
|
315
|
+
detail: Optional[Dict[str, Any]] = None,
|
|
316
|
+
wrapping: Optional[Sequence[GeneralError]] = None,
|
|
317
|
+
) -> None:
|
|
318
|
+
"""Build a IncompatibleNozzleConfiguration error."""
|
|
319
|
+
super().__init__(
|
|
320
|
+
code=ErrorCodes.API_MISCONFIGURATION,
|
|
321
|
+
message=message,
|
|
322
|
+
detail=detail,
|
|
323
|
+
wrapping=wrapping,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
class NozzleConfigurationManager:
|
|
328
|
+
def __init__(
|
|
329
|
+
self, nozzle_map: NozzleMap, valid_nozzle_maps: ValidNozzleMaps
|
|
330
|
+
) -> None:
|
|
331
|
+
self._physical_nozzle_map = nozzle_map
|
|
332
|
+
self._current_nozzle_configuration = nozzle_map
|
|
333
|
+
self._valid_nozzle_maps = valid_nozzle_maps
|
|
334
|
+
|
|
335
|
+
@classmethod
|
|
336
|
+
def build_from_config(
|
|
337
|
+
cls,
|
|
338
|
+
pipette_geometry: PipetteGeometryDefinition,
|
|
339
|
+
valid_nozzle_maps: ValidNozzleMaps,
|
|
340
|
+
) -> "NozzleConfigurationManager":
|
|
341
|
+
sorted_nozzle_map = OrderedDict(
|
|
342
|
+
(
|
|
343
|
+
(k, Point(*pipette_geometry.nozzle_map[k]))
|
|
344
|
+
for k in _nozzle_names_by_row(pipette_geometry.ordered_rows)
|
|
345
|
+
)
|
|
346
|
+
)
|
|
347
|
+
sorted_rows = OrderedDict(
|
|
348
|
+
(entry.key, entry.ordered_nozzles)
|
|
349
|
+
for entry in pipette_geometry.ordered_rows
|
|
350
|
+
)
|
|
351
|
+
sorted_cols = OrderedDict(
|
|
352
|
+
(entry.key, entry.ordered_nozzles)
|
|
353
|
+
for entry in pipette_geometry.ordered_columns
|
|
354
|
+
)
|
|
355
|
+
back_left = next(iter(sorted_rows.values()))[0]
|
|
356
|
+
front_right = next(reversed(list(sorted_rows.values())))[-1]
|
|
357
|
+
starting_nozzle_config = NozzleMap.build(
|
|
358
|
+
physical_nozzles=sorted_nozzle_map,
|
|
359
|
+
physical_rows=sorted_rows,
|
|
360
|
+
physical_columns=sorted_cols,
|
|
361
|
+
starting_nozzle=back_left,
|
|
362
|
+
back_left_nozzle=back_left,
|
|
363
|
+
front_right_nozzle=front_right,
|
|
364
|
+
valid_nozzle_maps=valid_nozzle_maps,
|
|
365
|
+
)
|
|
366
|
+
return cls(starting_nozzle_config, valid_nozzle_maps)
|
|
367
|
+
|
|
368
|
+
@property
|
|
369
|
+
def starting_nozzle_offset(self) -> Point:
|
|
370
|
+
return self._current_nozzle_configuration.starting_nozzle_offset
|
|
371
|
+
|
|
372
|
+
@property
|
|
373
|
+
def current_configuration(self) -> NozzleMap:
|
|
374
|
+
return self._current_nozzle_configuration
|
|
375
|
+
|
|
376
|
+
def reset_to_default_configuration(self) -> None:
|
|
377
|
+
self._current_nozzle_configuration = self._physical_nozzle_map
|
|
378
|
+
|
|
379
|
+
def update_nozzle_configuration(
|
|
380
|
+
self,
|
|
381
|
+
back_left_nozzle: str,
|
|
382
|
+
front_right_nozzle: str,
|
|
383
|
+
starting_nozzle: Optional[str] = None,
|
|
384
|
+
) -> None:
|
|
385
|
+
self._current_nozzle_configuration = NozzleMap.build(
|
|
386
|
+
# these casts are because of pydantic in the protocol engine (see above)
|
|
387
|
+
physical_nozzles=cast(
|
|
388
|
+
"OrderedDict[str, Point]", self._physical_nozzle_map.map_store
|
|
389
|
+
),
|
|
390
|
+
physical_rows=cast(
|
|
391
|
+
"OrderedDict[str, List[str]]", self._physical_nozzle_map.rows
|
|
392
|
+
),
|
|
393
|
+
physical_columns=cast(
|
|
394
|
+
"OrderedDict[str, List[str]]", self._physical_nozzle_map.columns
|
|
395
|
+
),
|
|
396
|
+
starting_nozzle=starting_nozzle or back_left_nozzle,
|
|
397
|
+
back_left_nozzle=back_left_nozzle,
|
|
398
|
+
front_right_nozzle=front_right_nozzle,
|
|
399
|
+
valid_nozzle_maps=self._valid_nozzle_maps,
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
def get_tip_count(self) -> int:
|
|
403
|
+
return self._current_nozzle_configuration.tip_count
|
|
404
|
+
|
|
405
|
+
def critical_point_with_tip_length(
|
|
406
|
+
self,
|
|
407
|
+
cp_override: Optional[CriticalPoint],
|
|
408
|
+
tip_length: float = 0.0,
|
|
409
|
+
) -> Point:
|
|
410
|
+
if cp_override == CriticalPoint.INSTRUMENT_XY_CENTER:
|
|
411
|
+
current_nozzle = (
|
|
412
|
+
self._current_nozzle_configuration.instrument_xy_center_offset
|
|
413
|
+
)
|
|
414
|
+
elif cp_override == CriticalPoint.XY_CENTER:
|
|
415
|
+
current_nozzle = self._current_nozzle_configuration.xy_center_offset
|
|
416
|
+
elif cp_override == CriticalPoint.Y_CENTER:
|
|
417
|
+
current_nozzle = self._current_nozzle_configuration.y_center_offset
|
|
418
|
+
elif cp_override == CriticalPoint.FRONT_NOZZLE:
|
|
419
|
+
current_nozzle = self._current_nozzle_configuration.front_nozzle_offset
|
|
420
|
+
else:
|
|
421
|
+
current_nozzle = self.starting_nozzle_offset
|
|
422
|
+
return current_nozzle - Point(0, 0, tip_length)
|