-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5061 from Opentrons/6d901d-fix
fix(protocols/6d901): pick up less than 8 with multi-channel for 7.2+
- Loading branch information
Showing
5 changed files
with
20 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"content": "from opentrons import protocol_api\nfrom opentrons.protocol_api.labware import OutOfTipsError\nfrom opentrons.types import Mount\n\n\nmetadata = {\n 'protocolName':\n ('Cherrypicking with multi-channel pipette substituting for a single '\n 'channel pipette'),\n 'author': 'Nick & Eskil <[email protected]>',\n 'source': 'Custom Protocol Request',\n 'apiLevel': '2.12'\n}\n\n\ndef run(ctx: protocol_api.ProtocolContext):\n\n [transfer_csv,\n lw_source_plate,\n lw_source_plate_open,\n lw_dest_plate,\n lw_dest_plate_open,\n res_type,\n pipette_type,\n pipette_mount,\n tip_type,\n tip_reuse,\n starting_tiprack_slot,\n starting_tip_well] = get_values( # noqa: F821\n \"transfer_csv\",\n \"lw_source_plate\",\n \"lw_source_plate_open\",\n \"lw_dest_plate\",\n \"lw_dest_plate_open\",\n \"res_type\",\n \"pipette_type\",\n \"pipette_mount\",\n \"tip_type\",\n \"tip_reuse\",\n \"starting_tiprack_slot\",\n \"starting_tip_well\")\n\n tiprack_map = {\n 'p20_multi_gen2': {\n 'standard': 'opentrons_96_tiprack_20ul',\n 'filter': 'opentrons_96_filtertiprack_20ul'\n },\n 'p300_multi_gen2': {\n 'standard': 'opentrons_96_tiprack_300ul',\n 'filter': 'opentrons_96_filtertiprack_200ul'\n }\n }\n\n # Parse csv\n # Format: Source Well, Source Aspiration Height Above Bottom (in mm),\n # Dest Well, Vol (in ul)\n transfer_info = [[val.strip().lower() for val in line.split(',')]\n for line in transfer_csv.splitlines()\n if line.split(',')[0].strip()][1:]\n\n if lw_source_plate_open.strip():\n lw_source_plate_name = lw_source_plate_open\n else:\n lw_source_plate_name = lw_source_plate\n if lw_dest_plate_open.strip():\n lw_dest_plate_name = lw_dest_plate_open\n else:\n lw_dest_plate_name = lw_dest_plate\n\n # Load labware\n # Plate to cherrypick from\n source_plate = ctx.load_labware(lw_source_plate_name, '7')\n dest_plate = ctx.load_labware(lw_dest_plate_name, '8')\n # This reservoir is unused, but present\n if res_type != \"none\":\n ctx.load_labware(res_type, '9')\n\n # Load tipracks\n tip_name = tiprack_map[pipette_type][tip_type]\n tiprack_slots = ['4', '5', '10', '11']\n tipracks = [ctx.load_labware(tip_name, slot)\n for slot in tiprack_slots]\n\n # load pipette\n pip = ctx.load_instrument(pipette_type, pipette_mount, tip_racks=tipracks)\n\n if not ctx.is_simulating():\n pick_up_current = 0.1 # 100 mA for single tip\n # Uncomment the next two lines if using Opentrons Robot Software version 7.1.x. # noqa: E501\n # Comment them if NOT using 7.1.x\n\n ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item( # noqa: E501\n {'pick_up_current': {8: pick_up_current}})\n\n # Uncomment the next two lines if using Opentrons Robot Software version 7.2.x # noqa: E501\n # Comment them if NOT using 7.2.x\n\n # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item(\n # {'pick_up_current': pick_up_current})\n\n # Tip_map has the columns reversed, pipette always picks up the\n # bottom-most tip in a given column until the column is depleted, and then\n # moves to the next column (from left to right).\n tip_map = []\n for rack in tipracks:\n tip_map.append(\n [[col for col in reversed(column)] for column in rack.columns()])\n # Flag at the end of each rack that is true if there are tips left\n for rack in tip_map:\n rack.append(True)\n # Flag used tipracks based on the protocol input parameter.\n # Check that the input parameter is an existing tiprack slot\n if starting_tiprack_slot not in tiprack_slots:\n raise Exception(\n f\"The Starting Tiprack Slot ({starting_tiprack_slot}) is invalid \"\n f\"The valid tiprack slots are {tiprack_slots}\"\n )\n start_rack_index = tiprack_slots.index(starting_tiprack_slot)\n for i in range(start_rack_index):\n tip_map[i][-1] = False\n\n # Flag used tips in the first available tiprack\n for column in tip_map[start_rack_index]:\n is_break = False\n for well in column:\n if well.well_name != starting_tip_well:\n well.has_tip = False\n else:\n is_break = True\n break\n if is_break:\n break\n\n def pick_up(pipette):\n \"\"\"`pick_up()` will pause the ctx when all tip boxes are out of\n tips, prompting the user to replace all tip racks. Once tipracks are\n reset, the ctx will start picking up tips from the first tip\n box as defined in the slot order when assigning the labware definition\n for that tip box. `pick_up()` will track tips for both pipettes if\n applicable.\n\n :param pipette: The pipette desired to pick up tip\n as definited earlier in the ctx (e.g. p300, m20).\n \"\"\"\n for i, rack in enumerate(tip_map):\n # Check the flag to see if the rack is empty, then we don't loop\n # through that rack so that the algorithm executes faster.\n if rack[-1] is False:\n if i == len(tip_map) - 1: # All tips are used, time to reset\n ctx.pause(\"Replace empty tip racks\")\n # print(\"Replace empty tip racks\")\n pipette.reset_tipracks()\n for rack in tip_map:\n rack[-1] = True\n # Raise an exception so that we can retry the pick up\n raise OutOfTipsError(\n \"Tipracks were out of tips and were reset\")\n else:\n continue\n for column in rack[:-1]: # skip [-1] index because it's the flag\n for well in column:\n if well.has_tip:\n pipette.pick_up_tip(well)\n if well.well_name == 'A12': # last tip in the rack\n rack[-1] = False\n return\n\n def parse_well(well):\n letter = well[0]\n number = well[1:]\n return letter.upper() + str(int(number))\n\n # import pdb; pdb.set_trace()\n if tip_reuse == 'always':\n try:\n pick_up(pip)\n except OutOfTipsError:\n # Try again after tipracks are reset\n pick_up(pip)\n for line in transfer_info:\n s_well, h, d_well, vol = line[:4]\n source_locn = \\\n source_plate.wells_by_name()[parse_well(s_well)].bottom(float(h))\n dest_locn = \\\n dest_plate.wells_by_name()[parse_well(d_well)]\n if tip_reuse == 'never':\n try:\n pick_up(pip)\n except OutOfTipsError:\n # Try again after tipracks are reset\n pick_up(pip)\n # pip.transfer(float(vol), source_locn, dest_locn, new_tip='never')\n pip.aspirate(float(vol), source_locn)\n pip.dispense(float(vol), dest_locn)\n if tip_reuse == 'never':\n pip.drop_tip()\n if pip.has_tip:\n pip.drop_tip()\n", | ||
"content": "from opentrons import protocol_api\nfrom opentrons.protocol_api.labware import OutOfTipsError\nfrom opentrons.types import Mount\n\n\nmetadata = {\n 'protocolName':\n ('Cherrypicking with multi-channel pipette substituting for a single '\n 'channel pipette'),\n 'author': 'Nick & Eskil <[email protected]>',\n 'source': 'Custom Protocol Request',\n 'apiLevel': '2.12'\n}\n\n\ndef run(ctx: protocol_api.ProtocolContext):\n\n [transfer_csv,\n lw_source_plate,\n lw_source_plate_open,\n lw_dest_plate,\n lw_dest_plate_open,\n res_type,\n pipette_type,\n pipette_mount,\n tip_type,\n tip_reuse,\n starting_tiprack_slot,\n starting_tip_well] = get_values( # noqa: F821\n \"transfer_csv\",\n \"lw_source_plate\",\n \"lw_source_plate_open\",\n \"lw_dest_plate\",\n \"lw_dest_plate_open\",\n \"res_type\",\n \"pipette_type\",\n \"pipette_mount\",\n \"tip_type\",\n \"tip_reuse\",\n \"starting_tiprack_slot\",\n \"starting_tip_well\")\n\n tiprack_map = {\n 'p20_multi_gen2': {\n 'standard': 'opentrons_96_tiprack_20ul',\n 'filter': 'opentrons_96_filtertiprack_20ul'\n },\n 'p300_multi_gen2': {\n 'standard': 'opentrons_96_tiprack_300ul',\n 'filter': 'opentrons_96_filtertiprack_200ul'\n }\n }\n\n # Parse csv\n # Format: Source Well, Source Aspiration Height Above Bottom (in mm),\n # Dest Well, Vol (in ul)\n transfer_info = [[val.strip().lower() for val in line.split(',')]\n for line in transfer_csv.splitlines()\n if line.split(',')[0].strip()][1:]\n\n if lw_source_plate_open.strip():\n lw_source_plate_name = lw_source_plate_open\n else:\n lw_source_plate_name = lw_source_plate\n if lw_dest_plate_open.strip():\n lw_dest_plate_name = lw_dest_plate_open\n else:\n lw_dest_plate_name = lw_dest_plate\n\n # Load labware\n # Plate to cherrypick from\n source_plate = ctx.load_labware(lw_source_plate_name, '7')\n dest_plate = ctx.load_labware(lw_dest_plate_name, '8')\n # This reservoir is unused, but present\n if res_type != \"none\":\n ctx.load_labware(res_type, '9')\n\n # Load tipracks\n tip_name = tiprack_map[pipette_type][tip_type]\n tiprack_slots = ['4', '5', '10', '11']\n tipracks = [ctx.load_labware(tip_name, slot)\n for slot in tiprack_slots]\n\n # load pipette\n pip = ctx.load_instrument(pipette_type, pipette_mount, tip_racks=tipracks)\n\n if not ctx.is_simulating():\n pick_up_current = 0.1 # 100 mA for single tip\n # Uncomment the next two lines if using Opentrons Robot Software version 7.1.x. # noqa: E501\n # Comment them if NOT using 7.1.x\n\n # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item( # noqa: E501\n # {'pick_up_current': {8: pick_up_current}})\n\n # Uncomment the next two lines if using Opentrons Robot Software version 7.2.x # noqa: E501\n # Comment them if NOT using 7.2.x\n\n ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item( # noqa: E501\n {'pick_up_current': pick_up_current})\n\n # Tip_map has the columns reversed, pipette always picks up the\n # bottom-most tip in a given column until the column is depleted, and then\n # moves to the next column (from left to right).\n tip_map = []\n for rack in tipracks:\n tip_map.append(\n [[col for col in reversed(column)] for column in rack.columns()])\n # Flag at the end of each rack that is true if there are tips left\n for rack in tip_map:\n rack.append(True)\n # Flag used tipracks based on the protocol input parameter.\n # Check that the input parameter is an existing tiprack slot\n if starting_tiprack_slot not in tiprack_slots:\n raise Exception(\n f\"The Starting Tiprack Slot ({starting_tiprack_slot}) is invalid \"\n f\"The valid tiprack slots are {tiprack_slots}\"\n )\n start_rack_index = tiprack_slots.index(starting_tiprack_slot)\n for i in range(start_rack_index):\n tip_map[i][-1] = False\n\n # Flag used tips in the first available tiprack\n for column in tip_map[start_rack_index]:\n is_break = False\n for well in column:\n if well.well_name != starting_tip_well:\n well.has_tip = False\n else:\n is_break = True\n break\n if is_break:\n break\n\n def pick_up(pipette):\n \"\"\"`pick_up()` will pause the ctx when all tip boxes are out of\n tips, prompting the user to replace all tip racks. Once tipracks are\n reset, the ctx will start picking up tips from the first tip\n box as defined in the slot order when assigning the labware definition\n for that tip box. `pick_up()` will track tips for both pipettes if\n applicable.\n\n :param pipette: The pipette desired to pick up tip\n as definited earlier in the ctx (e.g. p300, m20).\n \"\"\"\n for i, rack in enumerate(tip_map):\n # Check the flag to see if the rack is empty, then we don't loop\n # through that rack so that the algorithm executes faster.\n if rack[-1] is False:\n if i == len(tip_map) - 1: # All tips are used, time to reset\n ctx.pause(\"Replace empty tip racks\")\n # print(\"Replace empty tip racks\")\n pipette.reset_tipracks()\n for rack in tip_map:\n rack[-1] = True\n # Raise an exception so that we can retry the pick up\n raise OutOfTipsError(\n \"Tipracks were out of tips and were reset\")\n else:\n continue\n for column in rack[:-1]: # skip [-1] index because it's the flag\n for well in column:\n if well.has_tip:\n pipette.pick_up_tip(well)\n if well.well_name == 'A12': # last tip in the rack\n rack[-1] = False\n return\n\n def parse_well(well):\n letter = well[0]\n number = well[1:]\n return letter.upper() + str(int(number))\n\n # import pdb; pdb.set_trace()\n if tip_reuse == 'always':\n try:\n pick_up(pip)\n except OutOfTipsError:\n # Try again after tipracks are reset\n pick_up(pip)\n for line in transfer_info:\n s_well, h, d_well, vol = line[:4]\n source_locn = \\\n source_plate.wells_by_name()[parse_well(s_well)].bottom(float(h))\n dest_locn = \\\n dest_plate.wells_by_name()[parse_well(d_well)]\n if tip_reuse == 'never':\n try:\n pick_up(pip)\n except OutOfTipsError:\n # Try again after tipracks are reset\n pick_up(pip)\n # pip.transfer(float(vol), source_locn, dest_locn, new_tip='never')\n pip.aspirate(float(vol), source_locn)\n pip.dispense(float(vol), dest_locn)\n if tip_reuse == 'never':\n pip.drop_tip()\n if pip.has_tip:\n pip.drop_tip()\n", | ||
"custom_labware_defs": [ | ||
{ | ||
"brand": { | ||
|
Oops, something went wrong.