Skip to content

Commit

Permalink
Merge pull request #4865 from Opentrons/79e9a1
Browse files Browse the repository at this point in the history
79e9a1
  • Loading branch information
ncdiehl11 authored Aug 28, 2023
2 parents 355fd4c + 92a3ae5 commit ac9ae91
Show file tree
Hide file tree
Showing 7 changed files with 530 additions and 5 deletions.
11 changes: 6 additions & 5 deletions data/data/fields.csv
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ clearance_water,2
clearance_water_tube,1
col_meoh,1
col_mq,1
col_start,1
col_start,2
cold,3
cols,1
column_count,2
Expand Down Expand Up @@ -910,7 +910,7 @@ num_samp_plate2,1
num_samp_plate3,1
num_samp_plate4,1
num_sample_columns,1
num_samples,179
num_samples,180
num_samples_1,1
num_samples_2,1
num_samples_3,1
Expand Down Expand Up @@ -1615,7 +1615,7 @@ vol_a_to_b,1
vol_aliqout,1
vol_aliquot,1
vol_ampure_beads,1
vol_beads,1
vol_beads,2
vol_bulb,1
vol_c_to_d,1
vol_cd154,1
Expand All @@ -1631,7 +1631,7 @@ vol_dispense,1
vol_dispensed,1
vol_dna,5
vol_dna_buff,1
vol_elution,1
vol_elution,2
vol_elution_buffer,1
vol_elution_final,1
vol_etoh,1
Expand All @@ -1640,6 +1640,7 @@ vol_final_plate,1
vol_h2o,2
vol_h_lysate,1
vol_ic,1
vol_initial,1
vol_lys_buffer,1
vol_media_tubes,1
vol_meoh,1
Expand Down Expand Up @@ -1669,7 +1670,7 @@ vol_transfer,1
vol_tube1,1
vol_tube2,1
vol_tube3,1
vol_wash,1
vol_wash,2
vol_water,3
vol_xp1,1
volume,5
Expand Down
31 changes: 31 additions & 0 deletions protoBuilds/79e9a1-cleanup/README.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"author": "Opentrons",
"categories": {
"NGS Library Prep": [
"Cleanup"
]
},
"description": "This protocol is equipped to perform any of 4x cleanups for the Paragon NGS prep protocol.",
"internal": "0b83b7",
"labware": "\nNEST 0.2 mL 96-Well PCR Plate, Full Skirt\nNEST 12 Well Reservoir 15 mL #360102\nOpentrons 96 Filter Tip Rack 200 \u00b5L\nOpentrons 96 Filter Tip Rack 20 \u00b5L\n",
"markdown": {
"author": "[Opentrons](https://opentrons.com/)\n\n\n",
"categories": "* NGS Library Prep\n\t* Cleanup\n\n\n",
"description": "This protocol is equipped to perform any of 4x cleanups for the Paragon NGS prep protocol.\n\n\n",
"internal": "0b83b7\n",
"labware": "* [NEST 0.2 mL 96-Well PCR Plate, Full Skirt](https://shop.opentrons.com/nest-0-2-ml-96-well-pcr-plate-full-skirt/)\n* [NEST 12 Well Reservoir 15 mL #360102](https://shop.opentrons.com/nest-12-well-reservoirs-15-ml/)\n* [Opentrons 96 Filter Tip Rack 200 \u00b5L](https://shop.opentrons.com/opentrons-200ul-filter-tips/)\n* [Opentrons 96 Filter Tip Rack 20 \u00b5L](https://shop.opentrons.com/opentrons-20ul-filter-tips/)\n\n\n",
"modules": "* [Opentrons Temperature Module (GEN2)](https://shop.opentrons.com/temperature-module-gen2/)\n* [Opentrons Magnetic Module (GEN2)](https://shop.opentrons.com/magnetic-module-gen2/)\n\n\n",
"notes": "If you have any questions about this protocol, please contact the Protocol Development Team by filling out the [Troubleshooting Survey](https://protocol-troubleshooting.paperform.co/).\n\n\n",
"pipettes": "* [Opentrons P300 8 Channel Electronic Pipette (GEN2)](https://shop.opentrons.com/8-channel-electronic-pipette/)\n* [Opentrons P20 8 Channel Electronic Pipette (GEN2)](https://shop.opentrons.com/8-channel-electronic-pipette/)\n\n\n",
"process": "1. Input your protocol parameters above.\n2. Download your protocol and unzip if needed.\n3. Upload your custom labware to the [OT App](https://opentrons.com/ot-app) by navigating to `More` > `Custom Labware` > `Add Labware`, and selecting your labware files (.json extensions) if needed.\n4. Upload your protocol file (.py extension) to the [OT App](https://opentrons.com/ot-app) in the `Protocol` tab.\n5. Set up your deck according to the deck map.\n6. Calibrate your labware, tiprack and pipette using the OT App. For calibration tips, check out our [support articles](https://support.opentrons.com/en/collections/1559720-guide-for-getting-started-with-the-ot-2).\n7. Hit \"Run\".\n\n\n",
"title": "Paragon Cleanup"
},
"modules": [
"Opentrons Temperature Module (GEN2)",
"Opentrons Magnetic Module (GEN2)"
],
"notes": "If you have any questions about this protocol, please contact the Protocol Development Team by filling out the Troubleshooting Survey.",
"pipettes": "\nOpentrons P300 8 Channel Electronic Pipette (GEN2)\nOpentrons P20 8 Channel Electronic Pipette (GEN2)\n",
"process": "\nInput your protocol parameters above.\nDownload your protocol and unzip if needed.\nUpload your custom labware to the OT App by navigating to More > Custom Labware > Add Labware, and selecting your labware files (.json extensions) if needed.\nUpload your protocol file (.py extension) to the OT App in the Protocol tab.\nSet up your deck according to the deck map.\nCalibrate your labware, tiprack and pipette using the OT App. For calibration tips, check out our support articles.\nHit \"Run\".\n",
"title": "Paragon Cleanup"
}
117 changes: 117 additions & 0 deletions protoBuilds/79e9a1-cleanup/cleanup.ot2.apiv2.py.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{
"content": "from opentrons import protocol_api\nfrom opentrons.types import Point\nimport math\n\nmetadata = {\n 'protocolName': 'NGS Cleanup',\n 'author': 'Opentrons <[email protected]>',\n 'apiLevel': '2.14'\n}\n\nTEST_MODE_BEADS = False\nTEST_MODE_BIND_INCUBATE = False\nTEST_MODE_TEMP = False\nTEST_MODE_DROP = False\n\n\ndef run(ctx):\n\n [num_samples, col_start, vol_initial, vol_beads, vol_wash,\n vol_elution] = get_values( # noqa: F821\n 'num_samples', 'col_start', 'vol_initial', 'vol_beads', 'vol_wash',\n 'vol_elution')\n\n if TEST_MODE_BEADS:\n mixreps = 1\n else:\n mixreps = 10\n time_settling_minutes_wash = 0.75\n time_settling_minutes_elution = 5\n time_airdry_minutes = 10.0\n z_offset = 3.0\n radial_offset_fraction = 0.3 # fraction of radius\n\n # modules\n magdeck = ctx.load_module('magnetic module gen2', '4')\n magdeck.disengage()\n\n # labware\n elution_plate = ctx.load_labware(\n 'nest_96_wellplate_100ul_pcr_full_skirt', '1', 'elution plate')\n mag_plate = magdeck.load_labware(\n 'nest_96_wellplate_100ul_pcr_full_skirt', 'TAG1 plate')\n reservoir = ctx.load_labware('nest_12_reservoir_15ml', '2',\n 'reagent reservoir')\n tips200 = [\n ctx.load_labware('opentrons_96_filtertiprack_200ul', slot)\n for slot in ['3', '6', '9', '5', '8']]\n\n # load P300M pipette\n m300 = ctx.load_instrument(\n 'p300_multi_gen2', 'left', tip_racks=tips200)\n\n # reagents and variables\n num_cols = math.ceil(num_samples/8)\n mag_samples = mag_plate.rows()[0][col_start-1:col_start-1+num_cols]\n elution_samples = elution_plate.rows()[0][col_start-1:col_start-1+num_cols]\n beads = reservoir.rows()[0][0]\n etoh = reservoir.rows()[0][1:1+(math.ceil(num_cols/6))]\n elution_buffer = [reservoir.rows()[0][3]]\n liquid_trash = [ctx.loaded_labwares[12].wells()[0].top()]*num_cols\n\n # define liquids\n try:\n beads_liq = ctx.define_liquid(\n name='Beads', description='ampure beads', display_color='#B925FF')\n etoh_liq = ctx.define_liquid(\n name='Wash buffer', description='wash buffer',\n display_color='#FFD600')\n elution_buffer_liq = ctx.define_liquid(\n name='TE Buffer', description='low TE buffer for elution',\n display_color='#9DFFD8')\n beads.load_liquid(\n liquid=beads_liq, volume=vol_beads*num_samples+2000)\n [well.load_liquid(\n liquid=etoh_liq, volume=vol_wash*num_samples/len(etoh)+2000)\n for well in etoh]\n [well.load_liquid(\n liquid=elution_buffer_liq, volume=vol_elution*num_samples+2000)\n for well in elution_buffer]\n except AttributeError:\n pass\n\n ref_well = mag_plate.wells()[0]\n if ref_well.width:\n radius = ref_well.width/2\n else:\n radius = ref_well.diameter/2\n\n def wick(pip, well, side=1):\n pip.move_to(well.bottom().move(Point(x=side*radius*0.7, z=3)))\n\n def slow_withdraw(pip, well, seconds=2.0):\n pip.default_speed = 25\n if seconds > 0:\n ctx.delay(seconds=seconds)\n pip.move_to(well.top())\n pip.default_speed\n\n def pick_up(pip, spot=None):\n if spot:\n pip.pick_up_tip(spot)\n else:\n try:\n pip.pick_up_tip()\n except protocol_api.labware.OutOfTipsError:\n ctx.pause(\"\\n\\n\\n\\nReplace 200ul filtertipracks before \\\nresuming.\\n\\n\\n\\n\")\n pip.reset_tipracks()\n pip.pick_up_tip()\n\n parked_tips = {m300: []}\n\n def remove_supernatant(vol,\n pip=None,\n z_asp=0.2,\n park=True,\n destinations=liquid_trash):\n nonlocal parked_tips\n if not pip:\n pip = m300\n vol_airgap = pip.tip_racks[0].wells()[0].max_volume - vol \\\n if pip.tip_racks[0].wells()[0].max_volume - vol < 20.0 \\\n else 20.0\n for i, (s, d) in enumerate(zip(mag_samples, destinations)):\n if not pip.has_tip:\n if park:\n pick_up(pip, parked_tips[pip][i])\n else:\n pick_up(pip)\n pip.move_to(s.top())\n pip.default_speed /= 16\n side = 0\n if vol_airgap > 0:\n pip.aspirate(vol_airgap, s.top())\n pip.aspirate(vol, s.bottom().move(Point(x=side, z=z_asp)))\n pip.move_to(s.top())\n pip.default_speed *= 16\n pip.dispense(vol, d)\n if TEST_MODE_DROP:\n pip.return_tip()\n else:\n pip.drop_tip()\n parked_tips[pip] = []\n\n def resuspend(pip, location, vol, reps=mixreps,\n samples=mag_samples, x_mix_fraction=radial_offset_fraction,\n z_mix=z_offset, dispense_height_rel=2.0):\n\n pip.flow_rate.aspirate *= 4\n pip.flow_rate.dispense *= 4\n side_x = 1 if samples.index(location) % 2 == 0 else -1\n pip.move_to(location.center())\n for r_ind in range(reps):\n bead_loc = location.bottom().move(\n Point(x=side_x*radius*radial_offset_fraction,\n z=z_mix))\n pip.aspirate(vol, bead_loc)\n pip.dispense(vol, bead_loc.move(Point(z=dispense_height_rel)))\n pip.flow_rate.aspirate /= 4\n pip.flow_rate.dispense /= 4\n\n def wash(pip, vol, reagent, time_incubation=0,\n time_settling=0, premix=False,\n do_discard_supernatant=True, do_resuspend=False,\n vol_supernatant=0, park=True, z_resuspension=z_offset,\n supernatant_destinations=liquid_trash):\n nonlocal parked_tips\n\n vol_airgap = pip.min_volume\n columns_per_channel = 12//len(reagent)\n num_transfers = math.ceil(\n vol/(pip.tip_racks[0].wells()[0].max_volume-vol_airgap))\n vol_per_transfer = round(vol/num_transfers, 2)\n\n if magdeck.status == 'engaged':\n magdeck.disengage()\n\n last_source = None\n\n for i, well in enumerate(mag_samples):\n source = reagent[i//columns_per_channel]\n pick_up(pip)\n if park:\n parked_tips[pip].append(pip._last_tip_picked_up_from)\n if premix and last_source != source:\n pip.flow_rate.aspirate *= 4\n pip.flow_rate.dispense *= 4\n for _ in range(5):\n pip.aspirate(200, source.bottom(0.5))\n pip.dispense(200, source.bottom(5))\n pip.flow_rate.aspirate /= 4\n pip.flow_rate.dispense /= 4\n last_source = source\n for _ in range(num_transfers):\n pip.aspirate(vol_per_transfer, source)\n slow_withdraw(pip, source)\n pip.aspirate(vol_airgap, source.top())\n pip.dispense(pip.current_volume, well.top())\n if do_resuspend:\n resuspend(pip, well, vol*0.8)\n else:\n if mixreps > 0:\n pip.flow_rate.aspirate *= 4\n pip.flow_rate.dispense *= 4\n pip.mix(mixreps, vol*0.8, well.bottom(2))\n pip.flow_rate.aspirate /= 4\n pip.flow_rate.dispense /= 4\n pip.air_gap(20)\n if park or TEST_MODE_DROP:\n pip.return_tip()\n else:\n pip.drop_tip()\n\n if not TEST_MODE_BIND_INCUBATE:\n ctx.delay(minutes=time_incubation,\n msg=f'Incubating off MagDeck for \\\n{time_incubation} minutes.')\n if do_discard_supernatant:\n magdeck.engage()\n if not TEST_MODE_BEADS:\n ctx.delay(minutes=time_settling, msg=f'Incubating on \\\nMagDeck for {time_settling} minutes.')\n\n remove_supernatant(\n vol_supernatant,\n pip=pip,\n destinations=supernatant_destinations)\n magdeck.disengage()\n\n pick_up(m300)\n # premix beads and transfer to plate\n for _ in range(mixreps):\n m300.aspirate(200, beads.bottom(1))\n m300.dispense(200, beads.bottom(10))\n for d in mag_samples:\n if not m300.has_tip:\n pick_up(m300)\n m300.aspirate(vol_beads, beads.bottom(0.5))\n slow_withdraw(m300, beads)\n m300.dispense(m300.current_volume, d.bottom(2))\n m300.mix(mixreps, (vol_beads+vol_initial)*0.8, d.bottom(2))\n slow_withdraw(m300, d)\n # m300.return_tip()\n # parked_tips[m300].append(m300._last_tip_picked_up_from)\n m300.drop_tip()\n\n # remove initial supernatant\n magdeck.engage()\n ctx.delay(minutes=3)\n remove_supernatant(vol_initial+vol_beads, park=False)\n\n # wash\n wash(m300, vol_wash, etoh, time_incubation=0,\n time_settling=time_settling_minutes_wash,\n premix=False, do_discard_supernatant=True, do_resuspend=True,\n vol_supernatant=vol_wash)\n wash(m300, vol_wash, etoh, time_incubation=0,\n time_settling=time_settling_minutes_wash,\n premix=False, do_discard_supernatant=True, do_resuspend=True,\n vol_supernatant=vol_wash)\n\n # air dry\n ctx.delay(minutes=time_airdry_minutes, msg='Air Drying')\n\n # transfer final elution\n wash(m300, vol_elution, elution_buffer, time_incubation=5.0,\n do_resuspend=True,\n time_settling=time_settling_minutes_elution, vol_supernatant=10.0,\n do_discard_supernatant=True, supernatant_destinations=elution_samples)\n",
"custom_labware_defs": [],
"fields": [
{
"default": 16,
"label": "number of samples (1-96)",
"name": "num_samples",
"type": "int"
},
{
"default": 1,
"label": "sample starting column (1-12)",
"name": "col_start",
"type": "int"
},
{
"default": 45.0,
"label": "volume of initial sample (in ul)",
"name": "vol_initial",
"type": "float"
},
{
"default": 60,
"label": "volume of beads (in ul)",
"name": "vol_beads",
"type": "float"
},
{
"default": 150.0,
"label": "volume of wash (in ul)",
"name": "vol_wash",
"type": "float"
},
{
"default": 42.0,
"label": "volume of elution (in ul)",
"name": "vol_elution",
"type": "float"
}
],
"instruments": [
{
"mount": "left",
"name": "p300_multi_gen2"
}
],
"labware": [
{
"name": "elution plate on 1",
"share": false,
"slot": "1",
"type": "nest_96_wellplate_100ul_pcr_full_skirt"
},
{
"name": "reagent reservoir on 2",
"share": false,
"slot": "2",
"type": "nest_12_reservoir_15ml"
},
{
"name": "Opentrons 96 Filter Tip Rack 200 \u00b5L on 3",
"share": false,
"slot": "3",
"type": "opentrons_96_filtertiprack_200ul"
},
{
"name": "TAG1 plate on Magnetic Module GEN2 on 4",
"share": false,
"slot": "4",
"type": "nest_96_wellplate_100ul_pcr_full_skirt"
},
{
"name": "Opentrons 96 Filter Tip Rack 200 \u00b5L on 5",
"share": false,
"slot": "5",
"type": "opentrons_96_filtertiprack_200ul"
},
{
"name": "Opentrons 96 Filter Tip Rack 200 \u00b5L on 6",
"share": false,
"slot": "6",
"type": "opentrons_96_filtertiprack_200ul"
},
{
"name": "Opentrons 96 Filter Tip Rack 200 \u00b5L on 8",
"share": false,
"slot": "8",
"type": "opentrons_96_filtertiprack_200ul"
},
{
"name": "Opentrons 96 Filter Tip Rack 200 \u00b5L on 9",
"share": false,
"slot": "9",
"type": "opentrons_96_filtertiprack_200ul"
},
{
"name": "Opentrons Fixed Trash on 12",
"share": false,
"slot": "12",
"type": "opentrons_1_trash_1100ml_fixed"
}
],
"metadata": {
"apiLevel": "2.14",
"author": "Opentrons <[email protected]>",
"protocolName": "NGS Cleanup"
},
"modules": [
{
"name": "MagneticModuleContext at Magnetic Module GEN2 on 4 lw TAG1 plate on Magnetic Module GEN2 on 4",
"share": false,
"slot": "4",
"type": "magdeck"
}
]
}
20 changes: 20 additions & 0 deletions protoBuilds/79e9a1-cleanup/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"files": {
"OT 1 protocol": [],
"OT 2 protocol": [
"cleanup.ot2.apiv2.py"
],
"description": [
"README.md"
]
},
"flags": {
"embedded-app": false,
"feature": false,
"hide-from-search": false,
"skip-tests": false
},
"path": "protocols/79e9a1-cleanup",
"slug": "79e9a1-cleanup",
"status": "ok"
}
Loading

0 comments on commit ac9ae91

Please sign in to comment.