From e394a31484d4015d51a9cf5872193e64ed16c6c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cramifarawi=E2=80=9D?= <“rami.farawi@opentrons.com”> Date: Tue, 19 Mar 2024 10:52:24 -0400 Subject: [PATCH 1/3] fix --- data/data/fields.csv | 15 +++++++-------- protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json | 2 +- protoBuilds/6d901d/6d901d.ot2.apiv2.py.json | 2 +- protocols/6d901d-2/6d901d-2.ot2.apiv2.py | 8 ++++---- protocols/6d901d/6d901d.ot2.apiv2.py | 12 ++++++------ 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/data/data/fields.csv b/data/data/fields.csv index 297dfae2c..ff09040cd 100644 --- a/data/data/fields.csv +++ b/data/data/fields.csv @@ -575,7 +575,7 @@ init_vol,3 init_vol_50,1 init_vol_bca,1 init_vol_bsa,1 -init_vol_buff,2 +init_vol_buff,1 init_vol_buff1,1 init_vol_buff2,1 init_vol_buff3,1 @@ -586,7 +586,7 @@ init_vol_standard,1 init_vols_csv,1 initial_denaturation_cycles,1 initial_vol,1 -input_csv,23 +input_csv,22 input_file,10 input_file2,6 input_labware,1 @@ -643,7 +643,6 @@ labware_collect_plate,1 labware_cultureplate,1 labware_deep_well,1 labware_dest,2 -labware_dna_plate,1 labware_dna_sample_plate,1 labware_elisa_plate,3 labware_firstrna,1 @@ -655,7 +654,7 @@ labware_p300_tips,1 labware_parent,2 labware_patient_samples,1 labware_pcr,1 -labware_pcr_plate,11 +labware_pcr_plate,10 labware_plate,1 labware_plates,9 labware_pool,1 @@ -991,7 +990,7 @@ p1kmnt,1 p1n,1 p1num,1 p20_blowout_height,1 -p20_mount,137 +p20_mount,136 p20_multi_mount,3 p20_rate,2 p20_reservoir_height,1 @@ -1008,7 +1007,7 @@ p2num,1 p300_gen,1 p300_mixing_height,1 p300_mnt,3 -p300_mount,160 +p300_mount,159 p300_mount_1,1 p300_multi_mount,7 p300_rate,1 @@ -1450,7 +1449,7 @@ te_well,2 temp,2 temp_gen,1 temp_lysate,1 -temp_mod,3 +temp_mod,2 temp_mod_lname,2 temp_mod_on,2 temp_mod_s1_lname,1 @@ -1471,7 +1470,7 @@ tempblock,1 tempdeck_gen,1 tempdeck_name,1 tempdeck_slot,1 -temperature,13 +temperature,12 temperature1,1 temperature2,1 tempgen,1 diff --git a/protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json b/protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json index fd3b265be..8cd276540 100644 --- a/protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json +++ b/protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json @@ -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 ',\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 ',\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", "custom_labware_defs": [ { "brand": { diff --git a/protoBuilds/6d901d/6d901d.ot2.apiv2.py.json b/protoBuilds/6d901d/6d901d.ot2.apiv2.py.json index e67fb0c9d..dea49b256 100644 --- a/protoBuilds/6d901d/6d901d.ot2.apiv2.py.json +++ b/protoBuilds/6d901d/6d901d.ot2.apiv2.py.json @@ -1,5 +1,5 @@ { - "content": "from opentrons import protocol_api\nfrom opentrons.types import Mount\n\nmetadata = {\n 'protocolName': 'Normalization with a multi-channel pipette \\\n used as a single-channel pipette',\n 'author': 'Opentrons ',\n 'source': 'Protocol Library',\n 'apiLevel': '2.12'\n }\n\n\ndef transpose_matrix(m):\n return [[r[i] for r in reversed(m)] for i in range(len(m[0]))]\n\n\ndef flatten_matrix(m):\n \"\"\" Converts a matrix to a 1D array, e.g. [[1,2],[3,4]] -> [1,2,3,4]\n \"\"\"\n return [cell for row in m for cell in row]\n\n\ndef well_csv_to_list(csv_string):\n \"\"\"\n Takes a csv string and flattens to a list, re-ordering to match\n Opentrons well order convention (A1, B1, C1, ..., A2, B2, B2, ...)\n \"\"\"\n data = [\n line.split(',')\n for line in reversed(csv_string.split('\\n')) if line.strip()\n if line\n ]\n if len(data[0]) > len(data):\n # row length > column length ==> \"landscape\", so transpose\n return flatten_matrix(transpose_matrix(data))\n # \"portrait\"\n return flatten_matrix(data)\n\n\ndef run(ctx: protocol_api.ProtocolContext):\n [volumes_csv,\n p300_mount,\n p20_mount,\n plate_type,\n res_type,\n filter_tip,\n tip_reuse] = get_values( # noqa: F821\n \"volumes_csv\",\n \"p300_mount\",\n \"p20_mount\",\n \"plate_type\",\n \"res_type\",\n \"filter_tip\",\n \"tip_reuse\")\n\n # create labware\n source_plate = ctx.load_labware(plate_type, '7')\n # There could be a destination plate in slot 8 for cherry picking\n # Load something tall so the pipette doesn't hit it\n ctx.load_labware('usascientific_96_wellplate_2.4ml_deep', '8')\n reservoir = ctx.load_labware(res_type, '9')\n source = reservoir.wells()[0]\n if filter_tip:\n tips300 = ctx.load_labware('opentrons_96_filtertiprack_200ul', '10')\n tips20 = ctx.load_labware('opentrons_96_filtertiprack_20ul', '11')\n else:\n tips300 = ctx.load_labware('opentrons_96_tiprack_300ul', '10')\n tips20 = ctx.load_labware('opentrons_96_tiprack_20ul', '11')\n\n m300 = ctx.load_instrument('p300_multi_gen2', p300_mount)\n m20 = ctx.load_instrument('p20_multi_gen2', p20_mount)\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 for pipette in [m20, m300]:\n ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.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 # for pipette in [m20, m300]:\n # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.mount)).update_config_item(\n # {'pick_up_current': pick_up_current})\n\n tip300ctr = 95\n tip20ctr = 95\n\n def pick_up(pip):\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 nonlocal tip300ctr\n nonlocal tip20ctr\n\n if pip == m300:\n if tip300ctr < 0:\n ctx.home()\n ctx.pause('Please replace tips for P300 in slot 10.')\n tip300ctr = 95\n m300.pick_up_tip(tips300.wells()[tip300ctr])\n tip300ctr -= 1\n else:\n if tip20ctr < 0:\n ctx.home()\n ctx.pause('Please replace tips for P20 in slot 11.')\n tip20ctr = 95\n m20.pick_up_tip(tips20.wells()[tip20ctr])\n tip20ctr -= 1\n\n # create volumes list\n volumes = [float(cell) for cell in well_csv_to_list(volumes_csv)]\n\n is_warning = False\n\n for vol in volumes:\n if vol < 1:\n ctx.comment(\n 'WARNING: volume {} is below pipette\\'s minimum volume.'\n .format(vol))\n is_warning = True\n\n if is_warning:\n ctx.comment(\"\\n\")\n ctx.pause(\n \"One or more minimum volume warnings were detected \"\n \"Do you wish to continue?\\n\")\n\n for i, vol in enumerate(volumes):\n pipette = m20 if vol <= 20 else m300\n if not pipette.has_tip:\n pick_up(pipette)\n if vol != 0:\n pipette.aspirate(vol, source)\n pipette.dispense(vol, source_plate.wells()[i])\n if tip_reuse == 'never':\n pipette.drop_tip()\n", + "content": "from opentrons import protocol_api\nfrom opentrons.types import Mount\n\nmetadata = {\n 'protocolName': 'Normalization with a multi-channel pipette \\\n used as a single-channel pipette',\n 'author': 'Opentrons ',\n 'source': 'Protocol Library',\n 'apiLevel': '2.12'\n }\n\n\ndef transpose_matrix(m):\n return [[r[i] for r in reversed(m)] for i in range(len(m[0]))]\n\n\ndef flatten_matrix(m):\n \"\"\" Converts a matrix to a 1D array, e.g. [[1,2],[3,4]] -> [1,2,3,4]\n \"\"\"\n return [cell for row in m for cell in row]\n\n\ndef well_csv_to_list(csv_string):\n \"\"\"\n Takes a csv string and flattens to a list, re-ordering to match\n Opentrons well order convention (A1, B1, C1, ..., A2, B2, B2, ...)\n \"\"\"\n data = [\n line.split(',')\n for line in reversed(csv_string.split('\\n')) if line.strip()\n if line\n ]\n if len(data[0]) > len(data):\n # row length > column length ==> \"landscape\", so transpose\n return flatten_matrix(transpose_matrix(data))\n # \"portrait\"\n return flatten_matrix(data)\n\n\ndef run(ctx: protocol_api.ProtocolContext):\n [volumes_csv,\n p300_mount,\n p20_mount,\n plate_type,\n res_type,\n filter_tip,\n tip_reuse] = get_values( # noqa: F821\n \"volumes_csv\",\n \"p300_mount\",\n \"p20_mount\",\n \"plate_type\",\n \"res_type\",\n \"filter_tip\",\n \"tip_reuse\")\n\n # create labware\n source_plate = ctx.load_labware(plate_type, '7')\n # There could be a destination plate in slot 8 for cherry picking\n # Load something tall so the pipette doesn't hit it\n ctx.load_labware('usascientific_96_wellplate_2.4ml_deep', '8')\n reservoir = ctx.load_labware(res_type, '9')\n source = reservoir.wells()[0]\n if filter_tip:\n tips300 = ctx.load_labware('opentrons_96_filtertiprack_200ul', '10')\n tips20 = ctx.load_labware('opentrons_96_filtertiprack_20ul', '11')\n else:\n tips300 = ctx.load_labware('opentrons_96_tiprack_300ul', '10')\n tips20 = ctx.load_labware('opentrons_96_tiprack_20ul', '11')\n\n m300 = ctx.load_instrument('p300_multi_gen2', p300_mount)\n m20 = ctx.load_instrument('p20_multi_gen2', p20_mount)\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 # for pipette in [m20, m300]:\n # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.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 for pipette in [m20, m300]:\n ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.mount)).update_config_item(\n {'pick_up_current': pick_up_current})\n\n tip300ctr = 95\n tip20ctr = 95\n\n def pick_up(pip):\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 nonlocal tip300ctr\n nonlocal tip20ctr\n\n if pip == m300:\n if tip300ctr < 0:\n ctx.home()\n ctx.pause('Please replace tips for P300 in slot 10.')\n tip300ctr = 95\n m300.pick_up_tip(tips300.wells()[tip300ctr])\n tip300ctr -= 1\n else:\n if tip20ctr < 0:\n ctx.home()\n ctx.pause('Please replace tips for P20 in slot 11.')\n tip20ctr = 95\n m20.pick_up_tip(tips20.wells()[tip20ctr])\n tip20ctr -= 1\n\n # create volumes list\n volumes = [float(cell) for cell in well_csv_to_list(volumes_csv)]\n\n is_warning = False\n\n for vol in volumes:\n if vol < 1:\n ctx.comment(\n 'WARNING: volume {} is below pipette\\'s minimum volume.'\n .format(vol))\n is_warning = True\n\n if is_warning:\n ctx.comment(\"\\n\")\n ctx.pause(\n \"One or more minimum volume warnings were detected \"\n \"Do you wish to continue?\\n\")\n\n for i, vol in enumerate(volumes):\n pipette = m20 if vol <= 20 else m300\n if not pipette.has_tip:\n pick_up(pipette)\n if vol != 0:\n pipette.aspirate(vol, source)\n pipette.dispense(vol, source_plate.wells()[i])\n if tip_reuse == 'never':\n pipette.drop_tip()\n", "custom_labware_defs": [ { "brand": { diff --git a/protocols/6d901d-2/6d901d-2.ot2.apiv2.py b/protocols/6d901d-2/6d901d-2.ot2.apiv2.py index 6833d86ca..cae86c795 100644 --- a/protocols/6d901d-2/6d901d-2.ot2.apiv2.py +++ b/protocols/6d901d-2/6d901d-2.ot2.apiv2.py @@ -89,14 +89,14 @@ def run(ctx: protocol_api.ProtocolContext): # Uncomment the next two lines if using Opentrons Robot Software version 7.1.x. # noqa: E501 # Comment them if NOT using 7.1.x - ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item( # noqa: E501 - {'pick_up_current': {8: pick_up_current}}) + # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item( # noqa: E501 + # {'pick_up_current': {8: pick_up_current}}) # Uncomment the next two lines if using Opentrons Robot Software version 7.2.x # noqa: E501 # Comment them if NOT using 7.2.x - # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item( - # {'pick_up_current': pick_up_current}) + ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item( + {'pick_up_current': pick_up_current}) # Tip_map has the columns reversed, pipette always picks up the # bottom-most tip in a given column until the column is depleted, and then diff --git a/protocols/6d901d/6d901d.ot2.apiv2.py b/protocols/6d901d/6d901d.ot2.apiv2.py index a2fc2507b..973869a3e 100644 --- a/protocols/6d901d/6d901d.ot2.apiv2.py +++ b/protocols/6d901d/6d901d.ot2.apiv2.py @@ -74,15 +74,15 @@ def run(ctx: protocol_api.ProtocolContext): pick_up_current = 0.1 # 100 mA for single tip # Uncomment the next two lines if using Opentrons Robot Software version 7.1.x. # noqa:E501 # Comment them if NOT using 7.1.x - for pipette in [m20, m300]: - ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.mount)).update_config_item( # noqa:E501 - {'pick_up_current': {8: pick_up_current}}) + # for pipette in [m20, m300]: + # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.mount)).update_config_item( # noqa:E501 + # {'pick_up_current': {8: pick_up_current}}) # Uncomment the next two lines if using Opentrons Robot Software version 7.2.x # noqa:E501 # Comment them if NOT using 7.2.x - # for pipette in [m20, m300]: - # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.mount)).update_config_item( - # {'pick_up_current': pick_up_current}) + for pipette in [m20, m300]: + ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.mount)).update_config_item( + {'pick_up_current': pick_up_current}) tip300ctr = 95 tip20ctr = 95 From faaa754076a10f03aa089732696d08f4292e8d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cramifarawi=E2=80=9D?= <“rami.farawi@opentrons.com”> Date: Tue, 19 Mar 2024 11:20:21 -0400 Subject: [PATCH 2/3] fix --- protocols/6d901d-2/6d901d-2.ot2.apiv2.py | 2 +- protocols/6d901d/6d901d.ot2.apiv2.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/6d901d-2/6d901d-2.ot2.apiv2.py b/protocols/6d901d-2/6d901d-2.ot2.apiv2.py index cae86c795..7cc44f2bc 100644 --- a/protocols/6d901d-2/6d901d-2.ot2.apiv2.py +++ b/protocols/6d901d-2/6d901d-2.ot2.apiv2.py @@ -95,7 +95,7 @@ def run(ctx: protocol_api.ProtocolContext): # Uncomment the next two lines if using Opentrons Robot Software version 7.2.x # noqa: E501 # Comment them if NOT using 7.2.x - ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item( + ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pip.mount)).update_config_item( # noqa: E501 {'pick_up_current': pick_up_current}) # Tip_map has the columns reversed, pipette always picks up the diff --git a/protocols/6d901d/6d901d.ot2.apiv2.py b/protocols/6d901d/6d901d.ot2.apiv2.py index 973869a3e..f51c36bba 100644 --- a/protocols/6d901d/6d901d.ot2.apiv2.py +++ b/protocols/6d901d/6d901d.ot2.apiv2.py @@ -1,3 +1,4 @@ +# flake8: noqa from opentrons import protocol_api from opentrons.types import Mount @@ -13,7 +14,6 @@ def transpose_matrix(m): return [[r[i] for r in reversed(m)] for i in range(len(m[0]))] - def flatten_matrix(m): """ Converts a matrix to a 1D array, e.g. [[1,2],[3,4]] -> [1,2,3,4] """ From 2ff92badcd465cc3a43a51c6f546d0fd1bd45f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cramifarawi=E2=80=9D?= <“rami.farawi@opentrons.com”> Date: Tue, 19 Mar 2024 11:20:56 -0400 Subject: [PATCH 3/3] fix --- protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json | 2 +- protoBuilds/6d901d/6d901d.ot2.apiv2.py.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json b/protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json index 8cd276540..eedaeed64 100644 --- a/protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json +++ b/protoBuilds/6d901d-2/6d901d-2.ot2.apiv2.py.json @@ -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 ',\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 ',\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": { diff --git a/protoBuilds/6d901d/6d901d.ot2.apiv2.py.json b/protoBuilds/6d901d/6d901d.ot2.apiv2.py.json index dea49b256..dd91c7000 100644 --- a/protoBuilds/6d901d/6d901d.ot2.apiv2.py.json +++ b/protoBuilds/6d901d/6d901d.ot2.apiv2.py.json @@ -1,5 +1,5 @@ { - "content": "from opentrons import protocol_api\nfrom opentrons.types import Mount\n\nmetadata = {\n 'protocolName': 'Normalization with a multi-channel pipette \\\n used as a single-channel pipette',\n 'author': 'Opentrons ',\n 'source': 'Protocol Library',\n 'apiLevel': '2.12'\n }\n\n\ndef transpose_matrix(m):\n return [[r[i] for r in reversed(m)] for i in range(len(m[0]))]\n\n\ndef flatten_matrix(m):\n \"\"\" Converts a matrix to a 1D array, e.g. [[1,2],[3,4]] -> [1,2,3,4]\n \"\"\"\n return [cell for row in m for cell in row]\n\n\ndef well_csv_to_list(csv_string):\n \"\"\"\n Takes a csv string and flattens to a list, re-ordering to match\n Opentrons well order convention (A1, B1, C1, ..., A2, B2, B2, ...)\n \"\"\"\n data = [\n line.split(',')\n for line in reversed(csv_string.split('\\n')) if line.strip()\n if line\n ]\n if len(data[0]) > len(data):\n # row length > column length ==> \"landscape\", so transpose\n return flatten_matrix(transpose_matrix(data))\n # \"portrait\"\n return flatten_matrix(data)\n\n\ndef run(ctx: protocol_api.ProtocolContext):\n [volumes_csv,\n p300_mount,\n p20_mount,\n plate_type,\n res_type,\n filter_tip,\n tip_reuse] = get_values( # noqa: F821\n \"volumes_csv\",\n \"p300_mount\",\n \"p20_mount\",\n \"plate_type\",\n \"res_type\",\n \"filter_tip\",\n \"tip_reuse\")\n\n # create labware\n source_plate = ctx.load_labware(plate_type, '7')\n # There could be a destination plate in slot 8 for cherry picking\n # Load something tall so the pipette doesn't hit it\n ctx.load_labware('usascientific_96_wellplate_2.4ml_deep', '8')\n reservoir = ctx.load_labware(res_type, '9')\n source = reservoir.wells()[0]\n if filter_tip:\n tips300 = ctx.load_labware('opentrons_96_filtertiprack_200ul', '10')\n tips20 = ctx.load_labware('opentrons_96_filtertiprack_20ul', '11')\n else:\n tips300 = ctx.load_labware('opentrons_96_tiprack_300ul', '10')\n tips20 = ctx.load_labware('opentrons_96_tiprack_20ul', '11')\n\n m300 = ctx.load_instrument('p300_multi_gen2', p300_mount)\n m20 = ctx.load_instrument('p20_multi_gen2', p20_mount)\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 # for pipette in [m20, m300]:\n # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.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 for pipette in [m20, m300]:\n ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.mount)).update_config_item(\n {'pick_up_current': pick_up_current})\n\n tip300ctr = 95\n tip20ctr = 95\n\n def pick_up(pip):\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 nonlocal tip300ctr\n nonlocal tip20ctr\n\n if pip == m300:\n if tip300ctr < 0:\n ctx.home()\n ctx.pause('Please replace tips for P300 in slot 10.')\n tip300ctr = 95\n m300.pick_up_tip(tips300.wells()[tip300ctr])\n tip300ctr -= 1\n else:\n if tip20ctr < 0:\n ctx.home()\n ctx.pause('Please replace tips for P20 in slot 11.')\n tip20ctr = 95\n m20.pick_up_tip(tips20.wells()[tip20ctr])\n tip20ctr -= 1\n\n # create volumes list\n volumes = [float(cell) for cell in well_csv_to_list(volumes_csv)]\n\n is_warning = False\n\n for vol in volumes:\n if vol < 1:\n ctx.comment(\n 'WARNING: volume {} is below pipette\\'s minimum volume.'\n .format(vol))\n is_warning = True\n\n if is_warning:\n ctx.comment(\"\\n\")\n ctx.pause(\n \"One or more minimum volume warnings were detected \"\n \"Do you wish to continue?\\n\")\n\n for i, vol in enumerate(volumes):\n pipette = m20 if vol <= 20 else m300\n if not pipette.has_tip:\n pick_up(pipette)\n if vol != 0:\n pipette.aspirate(vol, source)\n pipette.dispense(vol, source_plate.wells()[i])\n if tip_reuse == 'never':\n pipette.drop_tip()\n", + "content": "# flake8: noqa\nfrom opentrons import protocol_api\nfrom opentrons.types import Mount\n\nmetadata = {\n 'protocolName': 'Normalization with a multi-channel pipette \\\n used as a single-channel pipette',\n 'author': 'Opentrons ',\n 'source': 'Protocol Library',\n 'apiLevel': '2.12'\n }\n\n\ndef transpose_matrix(m):\n return [[r[i] for r in reversed(m)] for i in range(len(m[0]))]\n\ndef flatten_matrix(m):\n \"\"\" Converts a matrix to a 1D array, e.g. [[1,2],[3,4]] -> [1,2,3,4]\n \"\"\"\n return [cell for row in m for cell in row]\n\n\ndef well_csv_to_list(csv_string):\n \"\"\"\n Takes a csv string and flattens to a list, re-ordering to match\n Opentrons well order convention (A1, B1, C1, ..., A2, B2, B2, ...)\n \"\"\"\n data = [\n line.split(',')\n for line in reversed(csv_string.split('\\n')) if line.strip()\n if line\n ]\n if len(data[0]) > len(data):\n # row length > column length ==> \"landscape\", so transpose\n return flatten_matrix(transpose_matrix(data))\n # \"portrait\"\n return flatten_matrix(data)\n\n\ndef run(ctx: protocol_api.ProtocolContext):\n [volumes_csv,\n p300_mount,\n p20_mount,\n plate_type,\n res_type,\n filter_tip,\n tip_reuse] = get_values( # noqa: F821\n \"volumes_csv\",\n \"p300_mount\",\n \"p20_mount\",\n \"plate_type\",\n \"res_type\",\n \"filter_tip\",\n \"tip_reuse\")\n\n # create labware\n source_plate = ctx.load_labware(plate_type, '7')\n # There could be a destination plate in slot 8 for cherry picking\n # Load something tall so the pipette doesn't hit it\n ctx.load_labware('usascientific_96_wellplate_2.4ml_deep', '8')\n reservoir = ctx.load_labware(res_type, '9')\n source = reservoir.wells()[0]\n if filter_tip:\n tips300 = ctx.load_labware('opentrons_96_filtertiprack_200ul', '10')\n tips20 = ctx.load_labware('opentrons_96_filtertiprack_20ul', '11')\n else:\n tips300 = ctx.load_labware('opentrons_96_tiprack_300ul', '10')\n tips20 = ctx.load_labware('opentrons_96_tiprack_20ul', '11')\n\n m300 = ctx.load_instrument('p300_multi_gen2', p300_mount)\n m20 = ctx.load_instrument('p20_multi_gen2', p20_mount)\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 # for pipette in [m20, m300]:\n # ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.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 for pipette in [m20, m300]:\n ctx._hw_manager.hardware.get_pipette(Mount.string_to_mount(pipette.mount)).update_config_item(\n {'pick_up_current': pick_up_current})\n\n tip300ctr = 95\n tip20ctr = 95\n\n def pick_up(pip):\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 nonlocal tip300ctr\n nonlocal tip20ctr\n\n if pip == m300:\n if tip300ctr < 0:\n ctx.home()\n ctx.pause('Please replace tips for P300 in slot 10.')\n tip300ctr = 95\n m300.pick_up_tip(tips300.wells()[tip300ctr])\n tip300ctr -= 1\n else:\n if tip20ctr < 0:\n ctx.home()\n ctx.pause('Please replace tips for P20 in slot 11.')\n tip20ctr = 95\n m20.pick_up_tip(tips20.wells()[tip20ctr])\n tip20ctr -= 1\n\n # create volumes list\n volumes = [float(cell) for cell in well_csv_to_list(volumes_csv)]\n\n is_warning = False\n\n for vol in volumes:\n if vol < 1:\n ctx.comment(\n 'WARNING: volume {} is below pipette\\'s minimum volume.'\n .format(vol))\n is_warning = True\n\n if is_warning:\n ctx.comment(\"\\n\")\n ctx.pause(\n \"One or more minimum volume warnings were detected \"\n \"Do you wish to continue?\\n\")\n\n for i, vol in enumerate(volumes):\n pipette = m20 if vol <= 20 else m300\n if not pipette.has_tip:\n pick_up(pipette)\n if vol != 0:\n pipette.aspirate(vol, source)\n pipette.dispense(vol, source_plate.wells()[i])\n if tip_reuse == 'never':\n pipette.drop_tip()\n", "custom_labware_defs": [ { "brand": {