diff --git a/data/data/fields.csv b/data/data/fields.csv index c8b18656c..427c48dda 100644 --- a/data/data/fields.csv +++ b/data/data/fields.csv @@ -338,6 +338,7 @@ diluent_csv,1 diluent_scheme,1 diluent_vol,1 dilution_factor,2 +dilution_plate,1 dilvol,1 disp_bottom_clearance,1 disp_delay,1 @@ -383,6 +384,7 @@ dna_well_plate_tmod,1 do_cool_samples,1 do_deactivate_tc,1 do_dnase_step,1 +do_flash,1 do_mm_resusp_pause,1 do_plate_mm,1 do_premix,1 @@ -469,6 +471,7 @@ final_air_gap,1 final_asp_speed,1 final_conc,1 final_extension_cycles,1 +final_plate,1 final_plate_slot4,1 final_temp,3 final_tubes,1 @@ -1176,6 +1179,7 @@ reagent,1 reagent1_loadname,1 reagent2_loadname,1 reagent_labware,3 +reagent_plate,1 reagent_scan,5 reagent_slot_scan,2 reagent_transfer_vol,2 @@ -1192,6 +1196,7 @@ res12_type,1 res1_type,1 res_dead_vol,1 res_type,20 +reservoir,1 reservoir12_lname,1 reservoir_fill_volume,1 reservoir_height,3 diff --git a/protoBuilds/0b97ae-protocol-3B/0b97ae-protocol-3B.ot2.apiv2.py.json b/protoBuilds/0b97ae-protocol-3B/0b97ae-protocol-3B.ot2.apiv2.py.json index a5512c033..211e44dd9 100644 --- a/protoBuilds/0b97ae-protocol-3B/0b97ae-protocol-3B.ot2.apiv2.py.json +++ b/protoBuilds/0b97ae-protocol-3B/0b97ae-protocol-3B.ot2.apiv2.py.json @@ -1,5 +1,5 @@ { - "content": "# flake8: noqa\n\n\n\"\"\"OPENTRONS.\"\"\"\nfrom opentrons import protocol_api\nimport math\nimport threading\nfrom time import sleep\nfrom opentrons import types\n\nmetadata = {\n 'protocolName': 'QIAseq FastSelect Extraction',\n 'author': 'Trevor ',\n 'source': 'Custom Protocol Request',\n 'apiLevel': '2.13' # CHECK IF YOUR API LEVEL HERE IS UP TO DATE\n # IN SECTION 5.2 OF THE APIV2 \"VERSIONING\"\n}\n\n# Definitions for deck light flashing\nclass CancellationToken:\n \"\"\"FLASH SETUP.\"\"\"\n\n def __init__(self):\n \"\"\"FLASH SETUP.\"\"\"\n self.is_continued = False\n\n def set_true(self):\n \"\"\"FLASH SETUP.\"\"\"\n self.is_continued = True\n\n def set_false(self):\n \"\"\"FLASH SETUP.\"\"\"\n self.is_continued = False\n\n\ndef turn_on_blinking_notification(hardware, pause):\n \"\"\"FLASH SETUP.\"\"\"\n while pause.is_continued:\n hardware.set_lights(rails=True)\n sleep(1)\n hardware.set_lights(rails=False)\n sleep(1)\n\n\ndef create_thread(ctx, cancel_token):\n \"\"\"FLASH SETUP.\"\"\"\n t1 = threading.Thread(target=turn_on_blinking_notification,\n args=(ctx._hw_manager.hardware, cancel_token))\n t1.start()\n return t1\n\n\ndef run(ctx: protocol_api.ProtocolContext):\n \"\"\"PROTOCOLS.\"\"\"\n [\n num_samples, vol_dna , flash, bead_timer] = get_values( # noqa: F821 (<--- DO NOT REMOVE!)\n \"num_samples\",\"vol_dna\",\"flash\",\"bead_timer\")\n num_samples = int(num_samples)\n\n 'Global variables'\n TEST_MODE = False\n bead_delay_time_1 = 2\n bead_delay_time = 5\n wash_delay_time = 10\n supernatant_headspeed_modulator = 10\n mag_height = 3.5\n air_dry_time = bead_timer\n ctx.max_speeds['Z'] = 125\n ctx.max_speeds['A'] = 125\n # Setup for flashing lights notification to empty trash\n cancellationToken = CancellationToken()\n\n # define all custom variables above here with descriptions:\n num_columns = math.ceil(num_samples/8)\n\n # load modules\n tempdeck_1 = ctx.load_module('temperature module gen2', '10')\n tempdeck_1.set_temperature(4)\n tempdeck_2 = ctx.load_module('temperature module gen2', '7')\n tempdeck_2.set_temperature(4)\n Mag_mod = ctx.load_module('magnetic module gen2', '4')\n Mag_mod.disengage()\n\n # load labware\n mag_plate = Mag_mod.load_labware('nest_96_wellplate_2ml_deep','Extraction Plate')\n final_plate = tempdeck_1.load_labware('opentrons_96_aluminumblock_biorad_wellplate_200ul', #noqa: E501\n 'Reagent Plate')\n Diluted_plate = tempdeck_2.load_labware('appliedbiosystemsenduraplate_96_aluminumblock_220ul', # noqa: E501\n 'Diluted RNA plate')\n water_res = ctx.load_labware('perkinelmer_12_reservoir_21000ul', 2,\n 'Water reservoir')\n Reagent_plate = ctx.load_labware('biorad_96_wellplate_200ul_pcr', '1')\n\n # load tipracks\n tips3 = [ctx.load_labware('opentrons_96_tiprack_300ul', slot)\n for slot in ['8', '9', '11']]\n tips = [ctx.load_labware('opentrons_96_filtertiprack_20ul', slot)\n for slot in ['3', '5', '6']]\n # load instrument\n\n p20 = ctx.load_instrument('p20_multi_gen2', 'left',\n tip_racks=tips)\n p300 = ctx.load_instrument('p300_multi_gen2', 'right',\n tip_racks=tips3)\n\n # reagents\n samples_start = Diluted_plate.rows()[0][:num_columns]\n samples_mag = mag_plate.rows()[0][:num_columns]\n etoh = water_res.rows()[0][2]\n etoh_1 = water_res.rows()[0][3]\n final_dest = final_plate.rows()[0][:num_columns]\n water_1 = water_res.rows()[0][0]\n bb = water_res.rows()[0][1]\n bb = water_res.rows()[0][1]\n Removal_Trash_1 = water_res.rows()[0][9]\n Removal_Trash_2 = water_res.rows()[0][10]\n Removal_Trash_3 = water_res.rows()[0][11]\n mm_1 = Reagent_plate.rows()[0][0]\n beads = Reagent_plate.rows()[0][0]\n\n def pick_up(pip):\n try:\n pip.pick_up_tip()\n except protocol_api.labware.OutOfTipsError:\n if flash:\n if not ctx._hw_manager.hardware.is_simulator:\n cancellationToken.set_true()\n thread = create_thread(ctx, cancellationToken)\n pip.home()\n ctx.pause('\\n\\n~~~~~~~~~~~~~~PLEASE REPLACE TIPRACKS~~~~~~~~~~~~~~~\\n') # noqa: E501\n ctx.home() # home before continuing with protocol\n if flash:\n cancellationToken.set_false() # stop light flashing after home\n thread.join()\n ctx.set_rail_lights(True)\n pip.reset_tipracks()\n pick_up(pip)\n\n tips_dropped = 0\n\n def drop_tip(pip, home=True):\n nonlocal tips_dropped\n pip.drop_tip(home_after=home)\n if pip == p300:\n tips_dropped += 8\n else:\n tips_dropped += 1\n if tips_dropped == 288:\n if flash:\n if not ctx._hw_manager.hardware.is_simulator:\n cancellationToken.set_true()\n thread = create_thread(ctx, cancellationToken)\n pip.home()\n ctx.pause('\\n\\n~~~~~~~~~~~~~~PLEASE EMPTY TRASH~~~~~~~~~~~~~~~\\n')\n ctx.home() # home before continuing with protocol\n if flash:\n cancellationToken.set_false() # stop light flashing after home\n thread.join()\n ctx.set_rail_lights(True)\n tips_dropped = 0\n\n def bead_mixing(well, pip, mvol, reps=10):\n \"\"\"bead_mixing.\"\"\"\n \"\"\"\n 'bead_mixing' will mix liquid that contains beads. This will be done by\n aspirating from the middle of the well & dispensing from the bottom to\n mix the beads with the other liquids as much as possible. Aspiration &\n dispensing will also be reversed to ensure proper mixing.\n param well: The current well that the mixing will occur in.\n param pip: The pipet that is currently attached/ being used.\n param mvol: The volume that is transferred before the mixing steps.\n param reps: The number of mix repetitions that should occur. Note~\n During each mix rep, there are 2 cycles of aspirating from bottom,\n dispensing at the top and 2 cycles of aspirating from middle,\n dispensing at the bottom\n \"\"\"\n vol = mvol * .9\n\n pip.move_to(well.center())\n for _ in range(reps):\n pip.aspirate(vol, well.bottom(1), rate=2)\n pip.dispense(vol, well.bottom(5), rate=2)\n\n # protocol\n ctx.comment('\\n~~~~~~~~~~~~~~ADDING SAMPLES TO MAG PLATE~~~~~~~~~~~~~~\\n')\n for s, d in zip(samples_start, samples_mag):\n pick_up(p20)\n p20.aspirate(vol_dna, s)\n p20.dispense(vol_dna, d)\n drop_tip(p20)\n\n ctx.comment('\\n~~~~~~~~~~~~~~ADDING BEADS TO SAMPLES~~~~~~~~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n pick_up(p20)\n if i % 3 == 0:\n bead_mixing(beads, p20, 15)\n p20.aspirate(19.5, beads, rate=0.5)\n ctx.delay(seconds=1)\n ctx.max_speeds['Z'] /= supernatant_headspeed_modulator\n ctx.max_speeds['A'] /= supernatant_headspeed_modulator\n p20.move_to(beads.top())\n ctx.max_speeds['Z'] *= supernatant_headspeed_modulator\n ctx.max_speeds['A'] *= supernatant_headspeed_modulator\n p20.dispense(19.5, dest, rate=0.5)\n bead_mixing(dest, p20, 15, reps=6)\n p20.blow_out(dest.bottom(20))\n p20.aspirate(1, dest.top())\n ctx.delay(seconds=10)\n p20.aspirate(1, dest.top())\n drop_tip(p20)\n\n ctx.pause('Remove Plate and Centrifuge, place back on deck at site 4, on the magnetic module')\n ctx.comment('\\n~~~~~~~~~~~~~~INCUBATING SAMPLES WITH BEADS~~~~~~~~~~~~~\\n')\n\n Mag_mod.engage(height_from_base=mag_height)\n ctx.comment('\\n~~~~~~~~~~~~~~SEPARATING BEADS~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(minutes=bead_delay_time_1)\n else:\n ctx.delay(minutes=bead_delay_time_1)\n\n ctx.comment('\\n~~~~~~~~~~~~~~REMOVING SUPERNATANT~~~~~~~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n side = -1 if i % 2 == 0 else 1\n pick_up(p20)\n for _ in range(2):\n\n p20.move_to(dest.top())\n ctx.max_speeds['Z'] /= supernatant_headspeed_modulator\n ctx.max_speeds['A'] /= supernatant_headspeed_modulator\n p20.aspirate(9.75, dest.bottom().move(types.Point(x=side,\n y=0, z=1)),\n rate=0.1)\n ctx.delay(seconds=1)\n p20.move_to(dest.top())\n p20.aspirate(1.5, dest.top())\n ctx.max_speeds['Z'] *= supernatant_headspeed_modulator\n ctx.max_speeds['A'] *= supernatant_headspeed_modulator\n p20.dispense(p20.current_volume, Removal_Trash_1)\n p20.blow_out()\n p20.air_gap(1)\n ctx.delay(seconds=10)\n p20.air_gap(1)\n drop_tip(p20)\n\n ctx.comment('\\n~~~~~~~~~~~~~~ADDING Water TO SAMPLES~~~~~~~~~~~~~~\\n')\n pick_up(p20)\n for i, dest in enumerate(samples_mag):\n p20.aspirate(15, water_1)\n p20.dispense(15, dest.top())\n drop_tip(p20)\n\n ctx.comment('\\n~~~ADDING QIAseq Bead Binding Buffer TO SAMPLES~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n pick_up(p20)\n p20.aspirate(19.5, bb)\n p20.dispense(19.5, dest)\n p20.mix(3, 17, dest)\n drop_tip(p20)\n\n ctx.pause('''\n Remove Plate and Centrifuge, place back on deck at site 4,\n on the magnetic module''')\n ctx.comment('\\n~~~~~~~~~~~~~~INCUBATING SAMPLES~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(seconds=5)\n else:\n ctx.delay(minutes=5)\n\n Mag_mod.engage(height_from_base=mag_height)\n ctx.comment('\\n~~~~~~~~~~~~~~SEPARATING BEADS~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(minutes=bead_delay_time_1)\n else:\n ctx.delay(minutes=bead_delay_time_1)\n\n ctx.comment('\\n~~~~~~~~~~~~~~WASHING TWICE WITH ETHANOL~~~~~~~~~~~~~\\n')\n for _ in range(2):\n pick_up(p300)\n ctx.comment('\\n~~~~~~~~~~~~~~ADDING ETHANOL~~~~~~~~~~~~~\\n')\n if _ > 0:\n for i, dest in enumerate(samples_mag):\n p300.mix(1, 150, etoh_1)\n p300.aspirate(210, etoh_1)\n p300.dispense(200, dest.top())\n p300.aspirate(20, dest.top())\n p300.dispense(30, etoh_1.top())\n else:\n for i, dest in enumerate(samples_mag):\n p300.mix(1, 150, etoh)\n p300.aspirate(210, etoh)\n p300.dispense(200, dest.top())\n p300.aspirate(20, dest.top())\n p300.dispense(30, etoh.top())\n\n ctx.delay(seconds=30)\n ctx.comment('\\n~~~~~~~~~~~~~~REMOVING ETHANOL~~~~~~~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n side = -1 if i % 2 == 0 else 1\n if i > 0:\n pick_up(p300)\n p300.move_to(dest.top(2))\n ctx.max_speeds['Z'] /= supernatant_headspeed_modulator\n ctx.max_speeds['A'] /= supernatant_headspeed_modulator\n p300.aspirate(200, dest.bottom().move(types.Point(x=side,\n y=0, z=1)),\n rate=0.1)\n p300.move_to(dest.top(2))\n ctx.max_speeds['Z'] *= supernatant_headspeed_modulator\n ctx.max_speeds['A'] *= supernatant_headspeed_modulator\n if i > 5:\n p300.dispense(200, Removal_Trash_3)\n else:\n p300.dispense(200, Removal_Trash_2)\n drop_tip(p300)\n if _ == 1:\n for i, dest in enumerate(samples_mag):\n pick_up(p20)\n p20.aspirate(10, dest.bottom(0.25), rate=.1)\n p20.aspirate(2, dest.top())\n if i > 5:\n p20.dispense(p20.current_volume, Removal_Trash_3)\n p20.aspirate(10, Removal_Trash_3)\n else:\n p20.dispense(p20.current_volume, Removal_Trash_2)\n p20.aspirate(10, Removal_Trash_2)\n p20.drop_tip()\n\n ctx.comment('\\n~~~~~~~~~~~~~~AIR DRY BEADS FOR 5 MINUTES~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(minutes=air_dry_time)\n else:\n ctx.delay(minutes=air_dry_time)\n\n Mag_mod.disengage()\n\n ctx.pause('''\n Remove Plate and inspect pellet to confirm it is completely\n dry, place back on deck at site 4, on the magnetic module\n ''')\n\n ctx.comment('\\n~~~~~~~~~~~~~ELUTING WITH Nucleas-free Water~~~~~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n pick_up(p20)\n p20.aspirate(16, water_1)\n p20.dispense(16, dest)\n bead_mixing(dest, p20, 17)\n p20.blow_out(dest.top())\n p20.air_gap(1)\n drop_tip(p20)\n\n ctx.comment('\\n~~~~~~~~~~~~~~ELUTING FOR 2 MINUTES~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(seconds=2)\n else:\n ctx.delay(minutes=2)\n\n ctx.comment('\\n~~~~~~~~~~~~~~SEPARATING BEADS~~~~~~~~~~~~~\\n')\n Mag_mod.engage(height_from_base=mag_height)\n if TEST_MODE:\n ctx.delay(minutes=bead_delay_time)\n else:\n ctx.delay(minutes=bead_delay_time)\n\n ctx.comment('\\n~~~~~~~~~~~~~~MOVING cDNA TO FINAL PLATE~~~~~~~~~~~~~\\n')\n\n for s, d in zip(samples_mag, final_dest):\n pick_up(p20)\n p20.aspirate(14, s.bottom().move(types.Point(x=0, y=0, z=0.7)),\n rate=0.1)\n p20.dispense(14, d)\n drop_tip(p20)\n\n # ctx.comment('\\n~~~~~~~~~~~~~~FIRST STRAND SYNTHESIS SETUP~~~~~~~~~~~~~\\n')\n # for i, dest in enumerate(final_dest):\n # pick_up(p20)\n # p20.aspirate(11, mm_1)\n # p20.dispense(11, dest.top())\n # bead_mixing(dest, p20, 19)\n # p20.blow_out(dest.top())\n # p20.air_gap(1)\n # drop_tip(p20)\n\n if flash:\n if not ctx._hw_manager.hardware.is_simulator:\n cancellationToken.set_true()\n thread = create_thread(ctx, cancellationToken)\n p20.home()\n ctx.pause('\\n\\n~~~~~~~~~~~~~~PROTOCOL COMPLETE~~~~~~~~~~~~~~~\\n')\n ctx.home() # home before continuing with protocol\n Mag_mod.disengage()\n tempdeck_1.deactivate()\n tempdeck_2.deactivate()\n if flash:\n cancellationToken.set_false()\n thread.join()\n ctx.set_rail_lights(True)\n", + "content": "# flake8: noqa\n\n\n\"\"\"OPENTRONS.\"\"\"\nfrom opentrons import protocol_api\nimport math\nimport threading\nfrom time import sleep\nfrom opentrons import types\n\nmetadata = {\n 'protocolName': 'QIAseq FastSelect Extraction',\n 'author': 'Trevor ',\n 'source': 'Custom Protocol Request',\n 'apiLevel': '2.13' # CHECK IF YOUR API LEVEL HERE IS UP TO DATE\n # IN SECTION 5.2 OF THE APIV2 \"VERSIONING\"\n}\n\n# Definitions for deck light flashing\nclass CancellationToken:\n \"\"\"FLASH SETUP.\"\"\"\n\n def __init__(self):\n \"\"\"FLASH SETUP.\"\"\"\n self.is_continued = False\n\n def set_true(self):\n \"\"\"FLASH SETUP.\"\"\"\n self.is_continued = True\n\n def set_false(self):\n \"\"\"FLASH SETUP.\"\"\"\n self.is_continued = False\n\n\ndef turn_on_blinking_notification(hardware, pause):\n \"\"\"FLASH SETUP.\"\"\"\n while pause.is_continued:\n hardware.set_lights(rails=True)\n sleep(1)\n hardware.set_lights(rails=False)\n sleep(1)\n\n\ndef create_thread(ctx, cancel_token):\n \"\"\"FLASH SETUP.\"\"\"\n t1 = threading.Thread(target=turn_on_blinking_notification,\n args=(ctx._hw_manager.hardware, cancel_token))\n t1.start()\n return t1\n\n\ndef run(ctx: protocol_api.ProtocolContext):\n \"\"\"PROTOCOLS.\"\"\"\n [\n num_samples, vol_dna , flash, bead_timer, reservoir, F_Plate, D_Plate, R_Plate] = get_values( # noqa: F821 (<--- DO NOT REMOVE!)\n \"num_samples\",\"vol_dna\",\"flash\",\"bead_timer\",\"reservoir\",\"final_plate\",\"dilution_plate\",\"reagent_plate\")\n num_samples = int(num_samples)\n if reservoir == 'perkinelmer':\n res_labware = 'perkinelmer_12_reservoir_21000ul'\n else:\n res_labware = 'nest_12_reservoir_15ml'\n\n if F_Plate == 'Biorad':\n F_labware = 'opentrons_96_aluminumblock_biorad_wellplate_200ul'\n else:\n F_labware = 'appliedbiosystemsenduraplate_96_aluminumblock_220ul'\n\n if D_Plate == 'Biorad':\n D_labware = 'opentrons_96_aluminumblock_biorad_wellplate_200ul'\n else:\n D_labware = 'appliedbiosystemsenduraplate_96_aluminumblock_220ul'\n \n if R_Plate == 'Biorad':\n R_labware = 'biorad_96_wellplate_200ul_pcr'\n else:\n R_labware = 'appliedbiosystemsenduraplate_96_aluminumblock_220ul'\n\n 'Global variables'\n TEST_MODE = False\n bead_delay_time_1 = 2\n bead_delay_time = 5\n wash_delay_time = 10\n supernatant_headspeed_modulator = 10\n mag_height = 3.5\n air_dry_time = bead_timer\n ctx.max_speeds['Z'] = 125\n ctx.max_speeds['A'] = 125\n # Setup for flashing lights notification to empty trash\n cancellationToken = CancellationToken()\n\n # define all custom variables above here with descriptions:\n num_columns = math.ceil(num_samples/8)\n\n # load modules\n tempdeck_1 = ctx.load_module('temperature module gen2', '10')\n tempdeck_1.set_temperature(4)\n tempdeck_2 = ctx.load_module('temperature module gen2', '7')\n tempdeck_2.set_temperature(4)\n Mag_mod = ctx.load_module('magnetic module gen2', '4')\n Mag_mod.disengage()\n\n # load labware\n mag_plate = Mag_mod.load_labware('nest_96_wellplate_2ml_deep','Extraction Plate')\n final_plate = tempdeck_1.load_labware(F_labware, #noqa: E501\n 'Reagent Plate')\n Diluted_plate = tempdeck_2.load_labware(D_labware, # noqa: E501\n 'Diluted RNA plate')\n water_res = ctx.load_labware(res_labware, 2,\n 'Water reservoir')\n Reagent_plate = ctx.load_labware(R_labware, '1')\n\n # load tipracks\n tips3 = [ctx.load_labware('opentrons_96_tiprack_300ul', slot)\n for slot in ['8', '9', '11']]\n tips = [ctx.load_labware('opentrons_96_filtertiprack_20ul', slot)\n for slot in ['3', '5', '6']]\n # load instrument\n\n p20 = ctx.load_instrument('p20_multi_gen2', 'left',\n tip_racks=tips)\n p300 = ctx.load_instrument('p300_multi_gen2', 'right',\n tip_racks=tips3)\n\n # reagents\n samples_start = Diluted_plate.rows()[0][:num_columns]\n samples_mag = mag_plate.rows()[0][:num_columns]\n etoh = water_res.rows()[0][2]\n etoh_1 = water_res.rows()[0][3]\n final_dest = final_plate.rows()[0][:num_columns]\n water_1 = water_res.rows()[0][0]\n bb = water_res.rows()[0][1]\n bb = water_res.rows()[0][1]\n Removal_Trash_1 = water_res.rows()[0][9]\n Removal_Trash_2 = water_res.rows()[0][10]\n Removal_Trash_3 = water_res.rows()[0][11]\n mm_1 = Reagent_plate.rows()[0][0]\n beads = Reagent_plate.rows()[0][0]\n\n def pick_up(pip):\n try:\n pip.pick_up_tip()\n except protocol_api.labware.OutOfTipsError:\n if flash:\n if not ctx._hw_manager.hardware.is_simulator:\n cancellationToken.set_true()\n thread = create_thread(ctx, cancellationToken)\n pip.home()\n ctx.pause('\\n\\n~~~~~~~~~~~~~~PLEASE REPLACE TIPRACKS~~~~~~~~~~~~~~~\\n') # noqa: E501\n ctx.home() # home before continuing with protocol\n if flash:\n cancellationToken.set_false() # stop light flashing after home\n thread.join()\n ctx.set_rail_lights(True)\n pip.reset_tipracks()\n pick_up(pip)\n\n tips_dropped = 0\n\n def drop_tip(pip, home=True):\n nonlocal tips_dropped\n pip.drop_tip(home_after=home)\n if pip == p300:\n tips_dropped += 8\n else:\n tips_dropped += 1\n if tips_dropped == 288:\n if flash:\n if not ctx._hw_manager.hardware.is_simulator:\n cancellationToken.set_true()\n thread = create_thread(ctx, cancellationToken)\n pip.home()\n ctx.pause('\\n\\n~~~~~~~~~~~~~~PLEASE EMPTY TRASH~~~~~~~~~~~~~~~\\n')\n ctx.home() # home before continuing with protocol\n if flash:\n cancellationToken.set_false() # stop light flashing after home\n thread.join()\n ctx.set_rail_lights(True)\n tips_dropped = 0\n\n def bead_mixing(well, pip, mvol, reps=10):\n \"\"\"bead_mixing.\"\"\"\n \"\"\"\n 'bead_mixing' will mix liquid that contains beads. This will be done by\n aspirating from the middle of the well & dispensing from the bottom to\n mix the beads with the other liquids as much as possible. Aspiration &\n dispensing will also be reversed to ensure proper mixing.\n param well: The current well that the mixing will occur in.\n param pip: The pipet that is currently attached/ being used.\n param mvol: The volume that is transferred before the mixing steps.\n param reps: The number of mix repetitions that should occur. Note~\n During each mix rep, there are 2 cycles of aspirating from bottom,\n dispensing at the top and 2 cycles of aspirating from middle,\n dispensing at the bottom\n \"\"\"\n vol = mvol * .9\n\n pip.move_to(well.center())\n for _ in range(reps):\n pip.aspirate(vol, well.bottom(1), rate=2)\n pip.dispense(vol, well.bottom(5), rate=2)\n\n # protocol\n ctx.comment('\\n~~~~~~~~~~~~~~ADDING SAMPLES TO MAG PLATE~~~~~~~~~~~~~~\\n')\n for s, d in zip(samples_start, samples_mag):\n pick_up(p20)\n p20.aspirate(vol_dna, s)\n p20.dispense(vol_dna, d)\n drop_tip(p20)\n\n ctx.comment('\\n~~~~~~~~~~~~~~ADDING BEADS TO SAMPLES~~~~~~~~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n pick_up(p20)\n if i % 3 == 0:\n bead_mixing(beads, p20, 15)\n p20.aspirate(19.5, beads, rate=0.5)\n ctx.delay(seconds=1)\n ctx.max_speeds['Z'] /= supernatant_headspeed_modulator\n ctx.max_speeds['A'] /= supernatant_headspeed_modulator\n p20.move_to(beads.top())\n ctx.max_speeds['Z'] *= supernatant_headspeed_modulator\n ctx.max_speeds['A'] *= supernatant_headspeed_modulator\n p20.dispense(19.5, dest, rate=0.5)\n bead_mixing(dest, p20, 15, reps=6)\n p20.blow_out(dest.bottom(20))\n p20.aspirate(1, dest.top())\n ctx.delay(seconds=10)\n p20.aspirate(1, dest.top())\n drop_tip(p20)\n\n ctx.pause('Remove Plate and Centrifuge, place back on deck at site 4, on the magnetic module')\n ctx.comment('\\n~~~~~~~~~~~~~~INCUBATING SAMPLES WITH BEADS~~~~~~~~~~~~~\\n')\n\n Mag_mod.engage(height_from_base=mag_height)\n ctx.comment('\\n~~~~~~~~~~~~~~SEPARATING BEADS~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(minutes=bead_delay_time_1)\n else:\n ctx.delay(minutes=bead_delay_time_1)\n\n ctx.comment('\\n~~~~~~~~~~~~~~REMOVING SUPERNATANT~~~~~~~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n side = -1 if i % 2 == 0 else 1\n pick_up(p20)\n for _ in range(2):\n\n p20.move_to(dest.top())\n ctx.max_speeds['Z'] /= supernatant_headspeed_modulator\n ctx.max_speeds['A'] /= supernatant_headspeed_modulator\n p20.aspirate(9.75, dest.bottom().move(types.Point(x=side,\n y=0, z=1)),\n rate=0.1)\n ctx.delay(seconds=1)\n p20.move_to(dest.top())\n p20.aspirate(1.5, dest.top())\n ctx.max_speeds['Z'] *= supernatant_headspeed_modulator\n ctx.max_speeds['A'] *= supernatant_headspeed_modulator\n p20.dispense(p20.current_volume, Removal_Trash_1)\n p20.blow_out()\n p20.air_gap(1)\n ctx.delay(seconds=10)\n p20.air_gap(1)\n drop_tip(p20)\n\n ctx.comment('\\n~~~~~~~~~~~~~~ADDING Water TO SAMPLES~~~~~~~~~~~~~~\\n')\n pick_up(p20)\n for i, dest in enumerate(samples_mag):\n p20.aspirate(15, water_1)\n p20.dispense(15, dest.top())\n drop_tip(p20)\n\n ctx.comment('\\n~~~ADDING QIAseq Bead Binding Buffer TO SAMPLES~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n pick_up(p20)\n p20.aspirate(19.5, bb)\n p20.dispense(19.5, dest)\n p20.mix(3, 17, dest)\n drop_tip(p20)\n\n ctx.pause('''\n Remove Plate and Centrifuge, place back on deck at site 4,\n on the magnetic module''')\n ctx.comment('\\n~~~~~~~~~~~~~~INCUBATING SAMPLES~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(seconds=5)\n else:\n ctx.delay(minutes=5)\n\n Mag_mod.engage(height_from_base=mag_height)\n ctx.comment('\\n~~~~~~~~~~~~~~SEPARATING BEADS~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(minutes=bead_delay_time_1)\n else:\n ctx.delay(minutes=bead_delay_time_1)\n\n ctx.comment('\\n~~~~~~~~~~~~~~WASHING TWICE WITH ETHANOL~~~~~~~~~~~~~\\n')\n for _ in range(2):\n pick_up(p300)\n ctx.comment('\\n~~~~~~~~~~~~~~ADDING ETHANOL~~~~~~~~~~~~~\\n')\n if _ > 0:\n for i, dest in enumerate(samples_mag):\n p300.mix(1, 150, etoh_1)\n p300.aspirate(210, etoh_1)\n p300.dispense(200, dest.top())\n p300.aspirate(20, dest.top())\n p300.dispense(30, etoh_1.top())\n else:\n for i, dest in enumerate(samples_mag):\n p300.mix(1, 150, etoh)\n p300.aspirate(210, etoh)\n p300.dispense(200, dest.top())\n p300.aspirate(20, dest.top())\n p300.dispense(30, etoh.top())\n\n ctx.delay(seconds=30)\n ctx.comment('\\n~~~~~~~~~~~~~~REMOVING ETHANOL~~~~~~~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n side = -1 if i % 2 == 0 else 1\n if i > 0:\n pick_up(p300)\n p300.move_to(dest.top(2))\n ctx.max_speeds['Z'] /= supernatant_headspeed_modulator\n ctx.max_speeds['A'] /= supernatant_headspeed_modulator\n p300.aspirate(200, dest.bottom().move(types.Point(x=side,\n y=0, z=1)),\n rate=0.1)\n p300.move_to(dest.top(2))\n ctx.max_speeds['Z'] *= supernatant_headspeed_modulator\n ctx.max_speeds['A'] *= supernatant_headspeed_modulator\n if i > 5:\n p300.dispense(200, Removal_Trash_3)\n else:\n p300.dispense(200, Removal_Trash_2)\n drop_tip(p300)\n if _ == 1:\n for i, dest in enumerate(samples_mag):\n pick_up(p20)\n p20.aspirate(10, dest.bottom(0.25), rate=.1)\n p20.aspirate(2, dest.top())\n if i > 5:\n p20.dispense(p20.current_volume, Removal_Trash_3)\n p20.aspirate(10, Removal_Trash_3)\n else:\n p20.dispense(p20.current_volume, Removal_Trash_2)\n p20.aspirate(10, Removal_Trash_2)\n p20.drop_tip()\n\n ctx.comment('\\n~~~~~~~~~~~~~~AIR DRY BEADS FOR 5 MINUTES~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(minutes=air_dry_time)\n else:\n ctx.delay(minutes=air_dry_time)\n\n Mag_mod.disengage()\n\n ctx.pause('''\n Remove Plate and inspect pellet to confirm it is completely\n dry, place back on deck at site 4, on the magnetic module\n ''')\n\n ctx.comment('\\n~~~~~~~~~~~~~ELUTING WITH Nucleas-free Water~~~~~~~~~~~\\n')\n for i, dest in enumerate(samples_mag):\n pick_up(p20)\n p20.aspirate(16, water_1)\n p20.dispense(16, dest)\n bead_mixing(dest, p20, 17)\n p20.blow_out(dest.top())\n p20.air_gap(1)\n drop_tip(p20)\n\n ctx.comment('\\n~~~~~~~~~~~~~~ELUTING FOR 2 MINUTES~~~~~~~~~~~~~\\n')\n if TEST_MODE:\n ctx.delay(seconds=2)\n else:\n ctx.delay(minutes=2)\n\n ctx.comment('\\n~~~~~~~~~~~~~~SEPARATING BEADS~~~~~~~~~~~~~\\n')\n Mag_mod.engage(height_from_base=mag_height)\n if TEST_MODE:\n ctx.delay(minutes=bead_delay_time)\n else:\n ctx.delay(minutes=bead_delay_time)\n\n ctx.comment('\\n~~~~~~~~~~~~~~MOVING cDNA TO FINAL PLATE~~~~~~~~~~~~~\\n')\n\n for s, d in zip(samples_mag, final_dest):\n pick_up(p20)\n p20.aspirate(14, s.bottom().move(types.Point(x=0, y=0, z=0.7)),\n rate=0.1)\n p20.dispense(14, d)\n drop_tip(p20)\n\n # ctx.comment('\\n~~~~~~~~~~~~~~FIRST STRAND SYNTHESIS SETUP~~~~~~~~~~~~~\\n')\n # for i, dest in enumerate(final_dest):\n # pick_up(p20)\n # p20.aspirate(11, mm_1)\n # p20.dispense(11, dest.top())\n # bead_mixing(dest, p20, 19)\n # p20.blow_out(dest.top())\n # p20.air_gap(1)\n # drop_tip(p20)\n\n if flash:\n if not ctx._hw_manager.hardware.is_simulator:\n cancellationToken.set_true()\n thread = create_thread(ctx, cancellationToken)\n p20.home()\n ctx.pause('\\n\\n~~~~~~~~~~~~~~PROTOCOL COMPLETE~~~~~~~~~~~~~~~\\n')\n ctx.home() # home before continuing with protocol\n Mag_mod.disengage()\n tempdeck_1.deactivate()\n tempdeck_2.deactivate()\n if flash:\n cancellationToken.set_false()\n thread.join()\n ctx.set_rail_lights(True)\n", "custom_labware_defs": [ { "brand": { @@ -1426,6 +1426,66 @@ "label": "Bead Timer?", "name": "bead_timer", "type": "int" + }, + { + "label": "Is the Reservoir PerkinElmer or Nest?", + "name": "reservoir", + "options": [ + { + "label": "perkinelmer", + "value": "perkinelmer" + }, + { + "label": "nest", + "value": "nest" + } + ], + "type": "dropDown" + }, + { + "label": "Is the Final Plate Biorad or AppliedBio?", + "name": "final_plate", + "options": [ + { + "label": "Biorad", + "value": "Biorad" + }, + { + "label": "AppliedBio", + "value": "AppliedBio" + } + ], + "type": "dropDown" + }, + { + "label": "Is the Diluted DNA Plate Biorad or AppliedBio?", + "name": "dilution_plate", + "options": [ + { + "label": "Biorad", + "value": "Biorad" + }, + { + "label": "AppliedBio", + "value": "AppliedBio" + } + ], + "type": "dropDown" + }, + { + "label": "Is the Reagent Plate Biorad or AppliedBio?", + "name": "reagent_plate", + "options": [ + { + "label": "Biorad", + "value": "Biorad" + }, + { + "label": "AppliedBio", + "value": "AppliedBio" + } + ], + "type": "dropDown" } ], "instruments": [ @@ -1479,7 +1539,7 @@ "name": "Diluted RNA plate on Temperature Module GEN2 on 7", "share": false, "slot": "7", - "type": "appliedbiosystemsenduraplate_96_aluminumblock_220ul" + "type": "opentrons_96_aluminumblock_biorad_wellplate_200ul" }, { "name": "Opentrons 96 Tip Rack 300 \u00b5L on 8", diff --git a/protoBuilds/0b97ae-protocol-3B/README.json b/protoBuilds/0b97ae-protocol-3B/README.json index ea26a58e6..037597d5b 100644 --- a/protoBuilds/0b97ae-protocol-3B/README.json +++ b/protoBuilds/0b97ae-protocol-3B/README.json @@ -6,13 +6,13 @@ ] }, "deck-setup": "\nWater Reservoir (slot 2):\n Column 1: Nuclease Free Water\n Column 2: Binding Buffer\n Column 3 & 4: Ethanol\n Column 10, 11 & 12: Empty for Supernatent Removal\nDiluted RNA Plate (slot 7 Temperature Module):\n RNA Samples Starting Plate\nReagent Plate (Slot 10):\n Column 1: MasterMix\n Column 2: Magentic Beads", - "description": "This is Part 3 to the QIAseq FastSelect 5s, 16s, 23s Protocol. This protocol is used to perform the addition of samples with mastermix into a plate.\nPart 1 to this protocol is the normalization of samples.\nPart 2 to this protocol is the Fragementation.\nLinks:\n Part 1: Sample Normalization\n Part 2: QIAseq FastSelect 5s, 16s, 23s Fragmentation\n* Part 3: QIAseq FastSelect 5s, 16s, 23s Extraction", + "description": "This is Part 3 to the QIAseq FastSelect 5s, 16s, 23s Protocol. This protocol is used to perform the addition of samples with mastermix into a plate.\nPart 1 to this protocol is the normalization of samples.\nPart 2 to this protocol is the Fragementation.\nLinks:\n* Part 1: Sample Normalization\n* Part 2: QIAseq FastSelect 5s, 16s, 23s Fragmentation\n* Part 3: QIAseq FastSelect 5s, 16s, 23s Extraction", "internal": "0b97ae-protocol-3B", "labware": "\nPerkin Elmer 12 Reservoir 21000 \u00b5L\nApplied Biosystems Enduraplate 96 Aluminum Block 220 \u00b5L\nBio-Rad 96 Well Plate 200 \u00b5L PCR #hsp9601\nOpentrons 96 Filter Tip Rack 20 \u00b5L\nNEST 96 Deepwell Plate 2mL #503001\nOpentrons 96 Tip Rack 300 \u00b5L\nOpentrons 96 Well Aluminum Block with Bio-Rad Well Plate 200 \u00b5L\n", "markdown": { "author": "[Opentrons](https://opentrons.com/)\n\n\n", "categories": "* NGS LIBRARY PREP\n\t* QIASeq FastSelect\n\n\n", - "deck-setup": "![deck](https://opentrons-protocol-library-website.s3.amazonaws.com/custom-README-images/0b97ae/3F240714-EB34-4978-97F6-5BD0739E874B_1_105_c.jpeg)\nWater Reservoir (slot 2):\n\tColumn 1: Nuclease Free Water\n\tColumn 2: Binding Buffer\n\tColumn 3 & 4: Ethanol\n\tColumn 10, 11 & 12: Empty for Supernatent Removal\nDiluted RNA Plate (slot 7 Temperature Module):\n\tRNA Samples Starting Plate\nReagent Plate (Slot 10):\n\tColumn 1: MasterMix\n\tColumn 2: Magentic Beads\n\n", + "deck-setup": "![deck](https://opentrons-protocol-library-website.s3.amazonaws.com/custom-README-images/0b97ae/deck.jpg)\nWater Reservoir (slot 2):\n\tColumn 1: Nuclease Free Water\n\tColumn 2: Binding Buffer\n\tColumn 3 & 4: Ethanol\n\tColumn 10, 11 & 12: Empty for Supernatent Removal\nDiluted RNA Plate (slot 7 Temperature Module):\n\tRNA Samples Starting Plate\nReagent Plate (Slot 10):\n\tColumn 1: MasterMix\n\tColumn 2: Magentic Beads\n\n", "description": "This is Part 3 to the QIAseq FastSelect 5s, 16s, 23s Protocol. This protocol is used to perform the addition of samples with mastermix into a plate.\nPart 1 to this protocol is the normalization of samples.\nPart 2 to this protocol is the Fragementation.\n\nLinks:\n* [Part 1: Sample Normalization](http://protocols.opentrons.com/protocol/0b97ae)\n* [Part 2: QIAseq FastSelect 5s, 16s, 23s Fragmentation](http://protocols.opentrons.com/protocol/0b97ae-protocol-2B)\n* [Part 3: QIAseq FastSelect 5s, 16s, 23s Extraction](http://protocols.opentrons.com/protocol/0b97ae-protocol-3B)\n\n\n", "internal": "0b97ae-protocol-3B\n", "labware": "* Perkin Elmer 12 Reservoir 21000 \u00b5L\n* Applied Biosystems Enduraplate 96 Aluminum Block 220 \u00b5L\n* [Bio-Rad 96 Well Plate 200 \u00b5L PCR #hsp9601](http://www.bio-rad.com/en-us/sku/hsp9601-hard-shell-96-well-pcr-plates-low-profile-thin-wall-skirted-white-clear?ID=hsp9601)\n* Opentrons 96 Filter Tip Rack 20 \u00b5L\n* [NEST 96 Deepwell Plate 2mL #503001](http://www.cell-nest.com/page94?product_id=101&_l=en)\n* [Opentrons 96 Tip Rack 300 \u00b5L](https://shop.opentrons.com/collections/opentrons-tips/products/opentrons-300ul-tips)\n* [Opentrons 96 Well Aluminum Block with Bio-Rad Well Plate 200 \u00b5L](https://shop.opentrons.com/collections/hardware-modules/products/aluminum-block-set)\n\n\n", @@ -21,7 +21,7 @@ "pipettes": "* [Opentrons P20 8 Channel Electronic Pipette (GEN2)](https://shop.opentrons.com/8-channel-electronic-pipette/)\n* [Opentrons P300 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", "protocol-steps": "1. Before this protocol the RNA plate should have went through the thermocycler according to FastSelect 5s/16s/23s, Table 3 and placed on a back on the temperature deck on slot 7.\n2. The Reagent plate will be placed on the temperature module on slot 10, which will contain MasterMix in column 1 and magentic beads in column 2.\n3. The reservoir will be placed on slot 2, which will contain Nucleas Free Water in well 1, Binding Buffer in well 2, and Ethanol in wells 3 and 4. Wells 10, 11 and 12 will be used for supernatent removal.\n\n\n\n", - "reagent-setup": "![reagents](https://opentrons-protocol-library-website.s3.amazonaws.com/custom-README-images/0b97ae/part+4/reagen.jpg)\n\n\n", + "reagent-setup": "![reagents](https://opentrons-protocol-library-website.s3.amazonaws.com/custom-README-images/0b97ae/reagents.jpg)\n\n\n", "title": "QIAseq FastSelect Extraction" }, "modules": [ diff --git a/protoBuilds/gsdx/bacgene.ot2.apiv2.py.json b/protoBuilds/gsdx/bacgene.ot2.apiv2.py.json index f46f778af..182a71db5 100644 --- a/protoBuilds/gsdx/bacgene.ot2.apiv2.py.json +++ b/protoBuilds/gsdx/bacgene.ot2.apiv2.py.json @@ -1,5 +1,5 @@ { - "content": "import math\nfrom opentrons.types import Point, Mount\n\n\nmetadata = {\n 'protocolName': 'BACGene',\n 'author': 'Nick Diehl 12:\n raise Exception('Combination of listeria and salmonella samples \\\nexceeds plate capacity')\n\n # define locations of lysis buffer reagents\n lysis_buffer_listeria = lysis_rack.rows_by_name()['B'][\n 1::2]\n lysis_buffer_salmonella = lysis_rack.rows_by_name()['D'][\n 1::2]\n enzyme_listeria_1 = lysis_rack.rows_by_name()['B'][\n ::2]\n enzyme_listeria_2 = lysis_rack.rows_by_name()['C']\n enzyme_salmonella = lysis_rack.rows_by_name()['D'][\n ::2]\n positive_control_l = lysis_rack.wells_by_name()['A1']\n positive_control_s = lysis_rack.wells_by_name()['E1']\n\n # define liquids\n try:\n lysis_buffer_l_prepared_liq = ctx.define_liquid(\n name=\"listeria lysis buffer (prepared)\",\n description=\"\",\n display_color=\"#B925FF\",\n )\n lysis_buffer_l_fresh_liq = ctx.define_liquid(\n name=\"listeria lysis buffer (fresh)\",\n description=\"\",\n display_color=\"#E4ABFF\",\n )\n lysis_buffer_s_prepared_liq = ctx.define_liquid(\n name=\"salmonella lysis buffer (prepared)\",\n description=\"\",\n display_color=\"#FFD600\",\n )\n lysis_buffer_s_fresh_liq = ctx.define_liquid(\n name=\"salmonella lysis buffer (fresh)\",\n description=\"\",\n display_color=\"#FFF2AD\",\n )\n enzyme_listeria_1_liq = ctx.define_liquid(\n name=\"listeria enzyme 1\",\n description=\"\",\n display_color=\"#FF9900\",\n )\n enzyme_listeria_2_liq = ctx.define_liquid(\n name=\"listeria enzyme 2\",\n description=\"\",\n display_color=\"#9DFFD8\",\n )\n enzyme_salmonella_liq = ctx.define_liquid(\n name=\"salmonella enzyme\",\n description=\"\",\n display_color=\"#50D5FF\",\n )\n positive_control_l_liq = ctx.define_liquid(\n name=\"listeria postive control\",\n description=\"\",\n display_color=\"#FF80F5\",\n )\n positive_control_s_liq = ctx.define_liquid(\n name=\"salmonella positive control\",\n description=\"\",\n display_color=\"#7EFF42\",\n )\n samples_listeria_liq_sample = ctx.define_liquid(\n name=\"listeria samples\",\n description=\"\",\n display_color=\"#0EFFFB\",\n )\n samples_listeria_liq_lysis = ctx.define_liquid(\n name=\"listeria samples\",\n description=\"\",\n display_color=\"#0756EA\",\n )\n samples_listeria_liq_pcr = ctx.define_liquid(\n name=\"listeria samples\",\n description=\"\",\n display_color=\"#130183\",\n )\n samples_salmonella_liq_sample = ctx.define_liquid(\n name=\"salmonella samples\",\n description=\"\",\n display_color=\"#F6096D\",\n )\n samples_salmonella_liq_lysis = ctx.define_liquid(\n name=\"salmonella samples\",\n description=\"\",\n display_color=\"#FF0000\",\n )\n samples_salmonella_liq_pcr = ctx.define_liquid(\n name=\"salmonella samples\",\n description=\"\",\n display_color=\"#A92F00\",\n )\n except AttributeError:\n pass\n\n samples_single_listeria = sample_plate.wells()[:num_samples_listeria]\n num_cols_offset_samples_listeria = math.ceil(num_samples_listeria/8)\n samples_single_salmonella = sample_plate.wells()[\n num_cols_offset_samples_listeria*8:\n num_cols_offset_samples_listeria*8+num_samples_salmonella]\n lysis_single_listeria = lysis_plate.wells()[:num_samples_listeria]\n lysis_single_salmonella = lysis_plate.wells()[\n num_cols_offset_samples_listeria*8:\n num_cols_offset_samples_listeria*8+num_samples_salmonella]\n pcr_single_listeria = pcr_plate.wells()[:num_samples_listeria]\n pcr_single_salmonella = pcr_plate.wells()[\n num_cols_offset_samples_listeria*8:\n num_cols_offset_samples_listeria*8+num_samples_salmonella]\n\n # load liquids\n try:\n if num_samples_listeria > 0:\n positive_control_l.load_liquid(positive_control_l_liq, volume=10)\n if num_samples_salmonella > 0:\n positive_control_s.load_liquid(positive_control_s_liq, volume=10)\n [well.load_liquid(samples_listeria_liq_sample,\n volume=30/len(samples_single_listeria))\n for well in samples_single_listeria]\n [well.load_liquid(samples_salmonella_liq_sample,\n volume=10/len(samples_single_salmonella))\n for well in samples_single_salmonella]\n [well.load_liquid(samples_listeria_liq_lysis,\n volume=30/len(lysis_single_listeria))\n for well in lysis_single_listeria]\n [well.load_liquid(samples_salmonella_liq_lysis,\n volume=10/len(lysis_single_salmonella))\n for well in lysis_single_salmonella]\n [well.load_liquid(samples_listeria_liq_pcr,\n volume=30/len(pcr_single_listeria))\n for well in pcr_single_listeria]\n [well.load_liquid(samples_salmonella_liq_pcr,\n volume=10/len(pcr_single_salmonella))\n for well in pcr_single_salmonella]\n except AttributeError:\n pass\n\n single_tip_count_map = {m300: 0, m20: 0}\n tip_ref = m300.tip_racks[0].wells()[0]\n default_current = 1\n\n right = True\n\n def drop(pip):\n nonlocal right\n offset = 30 if right else -15\n drop_loc = ctx.loaded_labwares[12].wells()[0].top().move(\n Point(x=offset))\n pip.drop_tip(drop_loc)\n right = not right\n\n def pick_up_single(pip=m300):\n mount = Mount.LEFT if pip.mount == 'left' else Mount.RIGHT\n current_single = 1/8*default_current\n if not ctx.is_simulating():\n # attenuate pickup current\n ctx._hw_manager.hardware._attached_instruments[\n mount].update_config_item(\n 'pick_up_current', current_single)\n pip.pick_up_tip(\n [well\n for col in pip.tip_racks[-1].columns()\n for well in col[::-1]][single_tip_count_map[pip]])\n single_tip_count_map[pip] += 1\n if not ctx.is_simulating():\n # reset pickup current\n ctx._hw_manager.hardware._attached_instruments[\n mount].update_config_item('pick_up_current', default_current)\n\n def slow_withdraw(pip, well, delay_seconds=2.0, y_offset=0):\n pip.default_speed /= 10\n if delay_seconds > 0:\n ctx.delay(delay_seconds)\n pip.move_to(well.top().move(Point(y=y_offset)))\n pip.default_speed *= 10\n\n def wick(pip, well, x_magnitude=0.5, z_offset=3.0):\n radius = well.diameter/2 if well.diameter else well.width/2\n pip.default_speed /= 2\n pip.move_to(well.bottom().move(Point(x=x_magnitude*radius,\n z=z_offset)))\n pip.default_speed *= 2\n\n \"\"\" create lysis buffer with enzyme \"\"\"\n if DO_CREATE_LYSIS_BUFFER:\n\n vol_enzyme = 500.0\n num_trans = math.ceil(vol_enzyme/tip_ref.max_volume)\n vol_per_trans = round(vol_enzyme/num_trans, 1)\n\n if num_samples_listeria_remaining % 48 == 0 or \\\n num_samples_listeria_remaining % 48 == 47:\n num_partial_listeria_buffers = 0\n num_bvs_effective = 0\n else:\n num_partial_listeria_buffers = 1\n if 2*math.ceil(num_samples_listeria_remaining/2) % 48 == 0:\n num_bvs_effective = 48\n else:\n num_bvs_effective = 2*math.ceil(\n num_samples_listeria_remaining/2) % 48\n\n num_additional_listeria_buffers = math.ceil(\n ((num_samples_listeria-1) - num_bvs_effective)/48)\n\n # print(f'partial: {num_partial_listeria_buffers}')\n # print(f'additional: {num_additional_listeria_buffers}')\n\n enzyme_listeria_1_creation = enzyme_listeria_1[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers+num_additional_listeria_buffers]\n enzyme_listeria_2_creation = enzyme_listeria_2[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers+num_additional_listeria_buffers]\n lysis_buffer_listeria_creation = lysis_buffer_listeria[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers+num_additional_listeria_buffers]\n # print(lysis_buffer_listeria_creation)\n\n # load partial liq\n if num_samples_listeria > 0:\n try:\n [\n well.load_liquid(\n lysis_buffer_l_prepared_liq,\n volume=11000/num_partial_listeria_buffers)\n for well in lysis_buffer_listeria[\n :num_partial_listeria_buffers]]\n\n # load full liq\n [\n well.load_liquid(\n lysis_buffer_l_fresh_liq,\n volume=11000/num_additional_listeria_buffers)\n for well in lysis_buffer_listeria[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers +\n num_additional_listeria_buffers]]\n [\n well.load_liquid(\n enzyme_listeria_1_liq,\n volume=500/num_additional_listeria_buffers)\n for well in enzyme_listeria_1[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers +\n num_additional_listeria_buffers]]\n [\n well.load_liquid(\n enzyme_listeria_2_liq,\n volume=500/num_additional_listeria_buffers)\n for well in enzyme_listeria_2[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers +\n num_additional_listeria_buffers]]\n except AttributeError:\n pass\n\n # listeria\n for enzyme1, enzyme2, lysis_buff in zip(\n enzyme_listeria_1_creation,\n enzyme_listeria_2_creation,\n lysis_buffer_listeria_creation):\n # enzyme 1\n pick_up_single(m300)\n for _ in range(num_trans):\n m300.aspirate(\n vol_per_trans, enzyme1.bottom().move(\n Point(x=OFFSET_X_TUBERACK, z=1)))\n slow_withdraw(m300, enzyme1)\n m300.move_to(\n lysis_buff.top().move(\n Point(x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA)))\n m300.dispense(\n vol_per_trans,\n lysis_buff.bottom().move(\n Point(x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA,\n z=3)))\n m300.blow_out()\n slow_withdraw(\n m300, lysis_buff, y_offset=OFFSET_Y_LYSIS_BUFFER_LISTERIA)\n drop(m300)\n\n # enzyme 2\n pick_up_single(m300)\n for i in range(num_trans):\n m300.aspirate(\n vol_per_trans, enzyme2.bottom().move(\n Point(x=OFFSET_X_TUBERACK, z=1)))\n slow_withdraw(m300, enzyme2)\n m300.move_to(\n lysis_buff.top().move(Point(\n x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA)))\n m300.dispense(\n vol_per_trans,\n lysis_buff.bottom().move(\n Point(x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA,\n z=3)))\n if i == num_trans - 1:\n if DO_MIX:\n m300.flow_rate.aspirate *= 2\n m300.flow_rate.dispense *= 2\n m300.mix(\n 10, 200,\n lysis_buff.bottom().move(Point(\n x=OFFSET_X_TUBERACK,\n z=3, y=OFFSET_Y_LYSIS_BUFFER_LISTERIA)))\n m300.flow_rate.aspirate /= 2\n m300.flow_rate.dispense /= 2\n m300.blow_out(\n lysis_buff.bottom().move(Point(\n x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA, z=3)))\n slow_withdraw(\n m300, lysis_buff, y_offset=OFFSET_Y_LYSIS_BUFFER_LISTERIA)\n drop(m300)\n\n # salmonella\n if num_samples_salmonella_remaining % 48 == 0 or \\\n num_samples_salmonella_remaining == 47:\n num_partial_salmonella_buffers = 0\n num_bvs_effective = 0\n else:\n num_partial_salmonella_buffers = 1\n if 2*math.ceil(num_samples_salmonella_remaining/2) % 48 == 0:\n num_bvs_effective = 48\n else:\n num_bvs_effective = 2*math.ceil(\n num_samples_salmonella_remaining/2) % 48\n\n num_additional_salmonella_buffers = math.ceil(\n ((num_samples_salmonella-1) - num_bvs_effective)/48)\n\n enzyme_salmonella_creation = enzyme_salmonella[\n num_partial_salmonella_buffers:\n num_partial_salmonella_buffers+num_additional_salmonella_buffers]\n lysis_buffer_salmonella_creation = lysis_buffer_salmonella[\n num_partial_salmonella_buffers:\n num_partial_salmonella_buffers+num_additional_salmonella_buffers]\n\n # load partial liq\n if num_samples_listeria > 0:\n try:\n [\n well.load_liquid(\n lysis_buffer_s_prepared_liq,\n volume=11000/num_partial_salmonella_buffers)\n for well in lysis_buffer_salmonella[\n :num_partial_salmonella_buffers]]\n\n # load full liq\n [\n well.load_liquid(\n lysis_buffer_s_fresh_liq,\n volume=11000/num_additional_salmonella_buffers)\n for well in lysis_buffer_salmonella[\n num_partial_salmonella_buffers:\n num_partial_salmonella_buffers +\n num_additional_salmonella_buffers]]\n [\n well.load_liquid(\n enzyme_salmonella_liq,\n volume=500/num_additional_salmonella_buffers)\n for well in enzyme_salmonella[\n num_partial_salmonella_buffers:\n num_partial_salmonella_buffers +\n num_additional_salmonella_buffers]]\n except AttributeError:\n pass\n\n for enzyme, lysis_buff in zip(enzyme_salmonella_creation,\n lysis_buffer_salmonella_creation):\n # enzyme\n pick_up_single(m300)\n for i in range(num_trans):\n m300.aspirate(vol_per_trans, enzyme.bottom().move(\n Point(x=OFFSET_X_TUBERACK, z=1)))\n slow_withdraw(m300, enzyme)\n m300.move_to(\n lysis_buff.top().move(\n Point(x=OFFSET_X_TUBERACK,\n y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA)))\n m300.dispense(\n vol_per_trans,\n lysis_buff.bottom().move(\n Point(x=OFFSET_X_TUBERACK,\n y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA,\n z=3)))\n if i == num_trans - 1:\n if DO_MIX:\n m300.flow_rate.aspirate *= 2\n m300.flow_rate.dispense *= 2\n m300.mix(\n 10, 200,\n lysis_buff.bottom().move(Point(\n x=OFFSET_X_TUBERACK,\n z=3, y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA)))\n m300.flow_rate.aspirate /= 2\n m300.flow_rate.dispense /= 2\n m300.blow_out(\n lysis_buff.bottom().move(\n Point(x=OFFSET_X_TUBERACK,\n y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA,\n z=3)))\n slow_withdraw(\n m300, lysis_buff,\n y_offset=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA)\n drop(m300)\n\n \"\"\" transfer lysis buffer to lysis plate \"\"\"\n vol_overage = 20\n\n if num_samples_listeria > 0:\n if DO_DISTRIBUTE_LYSIS_BUFFER:\n lysis_buffer_listeria_dests = lysis_plate.wells()[\n :num_samples_listeria-2] + [\n lysis_plate.wells()[num_samples_listeria-1]]\n vol_lysis_buffer_listeria = 70.0\n num_dests_per_asp = int(\n (tip_ref.max_volume-vol_overage)//vol_lysis_buffer_listeria)\n num_asp = math.ceil(\n len(lysis_buffer_listeria_dests)/num_dests_per_asp)\n lysis_buffer_listeria_dest_sets = [\n lysis_buffer_listeria_dests[i*num_dests_per_asp:\n (i+1)*num_dests_per_asp]\n if i < num_asp - 1\n else lysis_buffer_listeria_dests[i*num_dests_per_asp:]\n for i in range(num_asp)]\n pick_up_single(m300)\n m300.aspirate(\n vol_overage,\n lysis_buffer_listeria[0].bottom().move(Point(\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA,\n z=OFFSET_Z_LYSIS_BUFFER_LISTERIA)))\n num_asp_listeria_remaining = math.ceil(\n (num_samples_listeria_remaining % 48) / 2)\n bump = 24 - num_asp_listeria_remaining \\\n if 24 - num_asp_listeria_remaining != 24 else 0\n for i, d_set in enumerate(lysis_buffer_listeria_dest_sets):\n set_ind = i + bump\n lysis_buff = lysis_buffer_listeria[set_ind//24]\n # m300.blow_out(lysis_buff.top(-1))\n m300.aspirate(\n len(d_set)*vol_lysis_buffer_listeria,\n lysis_buff.bottom().move(Point(\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA,\n z=OFFSET_Z_LYSIS_BUFFER_LISTERIA)))\n slow_withdraw(\n m300, lysis_buff, y_offset=OFFSET_Y_LYSIS_BUFFER_LISTERIA)\n for d in d_set:\n m300.dispense(vol_lysis_buffer_listeria, d.bottom(2))\n slow_withdraw(m300, d)\n drop(m300)\n\n if num_samples_salmonella > 0:\n if DO_DISTRIBUTE_LYSIS_BUFFER:\n available_wells = [\n well for col in lysis_plate.columns()[num_cols_listeria:]\n for well in col]\n lysis_buffer_salmonella_dests = available_wells[\n :num_samples_salmonella-2] + [\n available_wells[num_samples_salmonella-1]]\n vol_lysis_buffer_salmonella = 90.0 if not salmonella_meat else 50.0\n num_dests_per_asp = 2 # hard-set for now\n num_asp = math.ceil(\n len(lysis_buffer_salmonella_dests)/num_dests_per_asp)\n lysis_buffer_salmonella_dest_sets = [\n lysis_buffer_salmonella_dests[i*num_dests_per_asp:\n (i+1)*num_dests_per_asp]\n if i < num_asp - 1\n else lysis_buffer_salmonella_dests[i*num_dests_per_asp:]\n for i in range(num_asp)]\n pick_up_single(m300)\n m300.aspirate(\n vol_overage,\n lysis_buffer_salmonella[0].bottom().move(\n Point(y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA,\n z=OFFSET_Z_LYSIS_BUFFER_SALMONELLA)))\n num_asp_salmonella_remaining = math.ceil(\n (num_samples_salmonella_remaining % 48) / 2)\n bump_check = int(48/num_dests_per_asp)\n bump = bump_check - num_asp_salmonella_remaining \\\n if bump_check - num_asp_salmonella_remaining != bump_check \\\n else 0\n for i, d_set in enumerate(lysis_buffer_salmonella_dest_sets):\n set_ind = i + bump\n lysis_buff = lysis_buffer_salmonella[set_ind//bump_check]\n # m300.blow_out(lysis_buff.top(-1))\n # print('salmonella', i, set_ind, lysis_buff, len(d_set))\n # m300.blow_out(lysis_buff.top(-1))\n m300.aspirate(\n len(d_set)*vol_lysis_buffer_salmonella,\n lysis_buff.bottom().move(Point(\n y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA,\n z=OFFSET_Z_LYSIS_BUFFER_SALMONELLA)))\n slow_withdraw(m300, lysis_buff,\n y_offset=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA)\n for d in d_set:\n m300.dispense(vol_lysis_buffer_salmonella, d.bottom(2))\n slow_withdraw(m300, d)\n drop(m300)\n\n if DO_TRANSFER_SAMPLE_TO_LYSIS:\n \"\"\" transfer listeria \"\"\"\n vol_listeria = 30.0\n num_sample_cols_listeria = math.ceil((num_samples_listeria-2)/8)\n for s, d in zip(sample_plate.rows()[0][:num_sample_cols_listeria],\n lysis_plate.rows()[0][:num_sample_cols_listeria]):\n if sample_rack_type == 'bioplastics':\n asp_loc = s.bottom(2)\n else:\n asp_loc = s.top(-17.36)\n m300.pick_up_tip()\n m300.aspirate(vol_listeria, asp_loc)\n slow_withdraw(m300, s)\n m300.dispense(vol_listeria, d.bottom(2))\n if DO_MIX:\n m300.mix(3, 50, d.bottom(2))\n m300.blow_out(d.bottom(2))\n slow_withdraw(m300, d)\n drop(m300)\n\n \"\"\" transfer salmonella \"\"\"\n [pip, vol_salmonella] = [m20, 10.0] \\\n if not salmonella_meat else [m300, 50.0]\n num_cols_samples_salmonella = math.ceil((num_samples_salmonella-2)/8)\n for s, d in zip(\n sample_plate.rows()[0][\n num_cols_listeria:\n num_cols_listeria+num_cols_samples_salmonella],\n lysis_plate.rows()[0][\n num_cols_listeria:\n num_cols_listeria+num_cols_samples_salmonella]):\n pip.pick_up_tip()\n if sample_rack_type == 'bioplastics':\n asp_loc = s.bottom(2)\n else:\n asp_loc = s.top(-17.36)\n pip.aspirate(vol_salmonella, asp_loc)\n slow_withdraw(pip, s)\n pip.dispense(vol_salmonella, d.bottom(2))\n if DO_MIX:\n pip.mix(3, 18, d.bottom(2))\n pip.blow_out(d.bottom(2))\n slow_withdraw(pip, d)\n drop(pip)\n\n if DO_SET_TEMP:\n ctx.delay(minutes=20, msg='Incubating for 20 minutes @ 37C.')\n tempdeck.set_temperature(95)\n ctx.delay(minutes=10, msg='Incubating for 10 minutes @ 95C.')\n tempdeck.set_temperature(37)\n\n vol_sample = 5.0\n\n if DO_TRANSFER_SAMPLE_TO_PCR:\n \"\"\" transfer samples to PCR plate \"\"\"\n\n # listeria\n if num_samples_listeria > 0:\n for s, d in zip(lysis_plate.rows()[0][:num_cols_listeria],\n pcr_plate.rows()[0][:num_cols_listeria]):\n m20.pick_up_tip()\n m20.aspirate(5, s.top()) # pre air gap\n m20.aspirate(vol_sample, s)\n slow_withdraw(m20, s)\n m20.dispense(vol_sample, d.bottom(1))\n # if DO_MIX:\n # m20.mix(3, vol_sample*0.8, d.bottom(1))\n m20.dispense(m20.current_volume, d.bottom(1))\n slow_withdraw(m20, d)\n # wick(m20, d)\n drop(m20)\n\n # salmonella\n if num_samples_salmonella > 0:\n for s, d in zip(\n lysis_plate.rows()[0][\n num_cols_listeria:\n num_cols_listeria+num_cols_salmonella],\n pcr_plate.rows()[0][\n num_cols_listeria:\n num_cols_listeria+num_cols_salmonella]):\n m20.pick_up_tip()\n m20.aspirate(5, s.top()) # pre air gap\n m20.aspirate(vol_sample, s)\n slow_withdraw(m20, s)\n m20.dispense(vol_sample, d.bottom(1))\n # if DO_MIX:\n # m20.mix(3, vol_sample*0.8, d.bottom(1))\n m20.dispense(m20.current_volume, d.bottom(1))\n slow_withdraw(m20, d)\n m20.air_gap(5)\n # wick(m20, d)\n drop(m20)\n\n if DO_TRANSFER_POSITIVE_CONTROL:\n \"\"\" transfer positive controls \"\"\"\n vol_positive_control = vol_sample\n if num_samples_listeria > 0:\n positive_control_l_dest = pcr_plate.wells()[num_samples_listeria-2]\n pick_up_single(m20)\n m20.aspirate(5, positive_control_l_dest.top()) # pre air gap\n m20.aspirate(vol_positive_control, positive_control_l)\n slow_withdraw(m20, positive_control_l)\n m20.dispense(m20.current_volume, positive_control_l_dest.bottom(1))\n slow_withdraw(m20, positive_control_l_dest)\n # if DO_MIX:\n # m20.mix(3, vol_positive_control*0.8,\n # positive_control_l_dest.bottom(1))\n # wick(m20, positive_control_l_dest)\n drop(m20)\n\n if num_samples_salmonella > 0:\n available_wells = [\n well for col in pcr_plate.columns()[num_cols_listeria:]\n for well in col]\n positive_control_s_dest = available_wells[num_samples_salmonella-2]\n pick_up_single(m20)\n m20.aspirate(5, positive_control_s.top()) # pre air gap\n m20.aspirate(vol_positive_control, positive_control_s)\n slow_withdraw(m20, positive_control_s)\n m20.dispense(m20.current_volume, positive_control_s_dest.bottom(1))\n slow_withdraw(m20, positive_control_s_dest)\n # if DO_MIX:\n # m20.mix(3, vol_positive_control*0.8,\n # positive_control_s_dest.bottom(1))\n # wick(m20, positive_control_s_dest)\n drop(m20)\n\n tempdeck.deactivate()\n", + "content": "import math\nfrom opentrons.types import Point, Mount\n\n\nmetadata = {\n 'protocolName': 'BACGene',\n 'author': 'Nick Diehl 12:\n raise Exception('Combination of listeria and salmonella samples \\\nexceeds plate capacity')\n\n # define locations of lysis buffer reagents\n lysis_buffer_listeria = lysis_rack.rows_by_name()['B'][\n 1::2]\n lysis_buffer_salmonella = lysis_rack.rows_by_name()['D'][\n 1::2]\n enzyme_listeria_1 = lysis_rack.rows_by_name()['B'][\n ::2]\n enzyme_listeria_2 = lysis_rack.rows_by_name()['C']\n enzyme_salmonella = lysis_rack.rows_by_name()['D'][\n ::2]\n positive_control_l = lysis_rack.wells_by_name()['A1']\n positive_control_s = lysis_rack.wells_by_name()['E1']\n\n # define liquids\n try:\n lysis_buffer_l_prepared_liq = ctx.define_liquid(\n name=\"listeria lysis buffer (prepared)\",\n description=\"\",\n display_color=\"#B925FF\",\n )\n lysis_buffer_l_fresh_liq = ctx.define_liquid(\n name=\"listeria lysis buffer (fresh)\",\n description=\"\",\n display_color=\"#E4ABFF\",\n )\n lysis_buffer_s_prepared_liq = ctx.define_liquid(\n name=\"salmonella lysis buffer (prepared)\",\n description=\"\",\n display_color=\"#FFD600\",\n )\n lysis_buffer_s_fresh_liq = ctx.define_liquid(\n name=\"salmonella lysis buffer (fresh)\",\n description=\"\",\n display_color=\"#FFF2AD\",\n )\n enzyme_listeria_1_liq = ctx.define_liquid(\n name=\"listeria enzyme 1\",\n description=\"\",\n display_color=\"#FF9900\",\n )\n enzyme_listeria_2_liq = ctx.define_liquid(\n name=\"listeria enzyme 2\",\n description=\"\",\n display_color=\"#9DFFD8\",\n )\n enzyme_salmonella_liq = ctx.define_liquid(\n name=\"salmonella enzyme\",\n description=\"\",\n display_color=\"#50D5FF\",\n )\n positive_control_l_liq = ctx.define_liquid(\n name=\"listeria postive control\",\n description=\"\",\n display_color=\"#FF80F5\",\n )\n positive_control_s_liq = ctx.define_liquid(\n name=\"salmonella positive control\",\n description=\"\",\n display_color=\"#7EFF42\",\n )\n samples_listeria_liq_sample = ctx.define_liquid(\n name=\"listeria samples\",\n description=\"\",\n display_color=\"#0EFFFB\",\n )\n samples_listeria_liq_lysis = ctx.define_liquid(\n name=\"listeria samples\",\n description=\"\",\n display_color=\"#0756EA\",\n )\n samples_listeria_liq_pcr = ctx.define_liquid(\n name=\"listeria samples\",\n description=\"\",\n display_color=\"#130183\",\n )\n samples_salmonella_liq_sample = ctx.define_liquid(\n name=\"salmonella samples\",\n description=\"\",\n display_color=\"#F6096D\",\n )\n samples_salmonella_liq_lysis = ctx.define_liquid(\n name=\"salmonella samples\",\n description=\"\",\n display_color=\"#FF0000\",\n )\n samples_salmonella_liq_pcr = ctx.define_liquid(\n name=\"salmonella samples\",\n description=\"\",\n display_color=\"#A92F00\",\n )\n except AttributeError:\n pass\n\n samples_single_listeria = sample_plate.wells()[:num_samples_listeria]\n num_cols_offset_samples_listeria = math.ceil(num_samples_listeria/8)\n samples_single_salmonella = sample_plate.wells()[\n num_cols_offset_samples_listeria*8:\n num_cols_offset_samples_listeria*8+num_samples_salmonella]\n lysis_single_listeria = lysis_plate.wells()[:num_samples_listeria]\n lysis_single_salmonella = lysis_plate.wells()[\n num_cols_offset_samples_listeria*8:\n num_cols_offset_samples_listeria*8+num_samples_salmonella]\n pcr_single_listeria = pcr_plate.wells()[:num_samples_listeria]\n pcr_single_salmonella = pcr_plate.wells()[\n num_cols_offset_samples_listeria*8:\n num_cols_offset_samples_listeria*8+num_samples_salmonella]\n\n # load liquids\n vol_sample = 5.0\n\n try:\n if num_samples_listeria > 0:\n positive_control_l.load_liquid(\n positive_control_l_liq, volume=vol_sample)\n if num_samples_salmonella > 0:\n positive_control_s.load_liquid(\n positive_control_s_liq, volume=vol_sample)\n [well.load_liquid(samples_listeria_liq_sample,\n volume=round(30/len(samples_single_listeria)))\n for well in samples_single_listeria[\n :max(0, len(samples_single_listeria)-2)]]\n [well.load_liquid(samples_salmonella_liq_sample,\n volume=round(10/len(samples_single_salmonella)))\n for well in samples_single_salmonella[\n :max(0, len(samples_single_salmonella)-2)]]\n [well.load_liquid(samples_listeria_liq_lysis,\n volume=round(30/len(lysis_single_listeria)))\n for well in lysis_single_listeria]\n [well.load_liquid(samples_salmonella_liq_lysis,\n volume=round(10/len(lysis_single_salmonella)))\n for well in lysis_single_salmonella]\n [well.load_liquid(samples_listeria_liq_pcr,\n volume=round(30/len(pcr_single_listeria)))\n for well in pcr_single_listeria]\n [well.load_liquid(samples_salmonella_liq_pcr,\n volume=round(10/len(pcr_single_salmonella)))\n for well in pcr_single_salmonella]\n except AttributeError:\n pass\n\n single_tip_count_map = {m300: 0, m20: 0}\n tip_ref = m300.tip_racks[0].wells()[0]\n default_current = 1\n\n right = True\n\n def drop(pip):\n nonlocal right\n offset = 30 if right else -15\n drop_loc = ctx.loaded_labwares[12].wells()[0].top().move(\n Point(x=offset))\n pip.drop_tip(drop_loc)\n right = not right\n\n def pick_up_single(pip=m300):\n mount = Mount.LEFT if pip.mount == 'left' else Mount.RIGHT\n current_single = 1/8*default_current\n if not ctx.is_simulating():\n # attenuate pickup current\n ctx._hw_manager.hardware._attached_instruments[\n mount].update_config_item(\n 'pick_up_current', current_single)\n pip.pick_up_tip(\n [well\n for col in pip.tip_racks[-1].columns()\n for well in col[::-1]][single_tip_count_map[pip]])\n single_tip_count_map[pip] += 1\n if not ctx.is_simulating():\n # reset pickup current\n ctx._hw_manager.hardware._attached_instruments[\n mount].update_config_item('pick_up_current', default_current)\n\n def slow_withdraw(pip, well, delay_seconds=2.0, y_offset=0):\n pip.default_speed /= 10\n if delay_seconds > 0:\n ctx.delay(delay_seconds)\n pip.move_to(well.top().move(Point(y=y_offset)))\n pip.default_speed *= 10\n\n def wick(pip, well, x_magnitude=0.5, z_offset=3.0):\n radius = well.diameter/2 if well.diameter else well.width/2\n pip.default_speed /= 2\n pip.move_to(well.bottom().move(Point(x=x_magnitude*radius,\n z=z_offset)))\n pip.default_speed *= 2\n\n \"\"\" create lysis buffer with enzyme \"\"\"\n if DO_CREATE_LYSIS_BUFFER:\n\n vol_enzyme = 500.0\n num_trans = math.ceil(vol_enzyme/tip_ref.max_volume)\n vol_per_trans = round(vol_enzyme/num_trans, 1)\n\n if num_samples_listeria_remaining % 48 == 0 or \\\n num_samples_listeria_remaining % 48 == 47:\n num_partial_listeria_buffers = 0\n num_bvs_effective = 0\n else:\n num_partial_listeria_buffers = 1\n if 2*math.ceil(num_samples_listeria_remaining/2) % 48 == 0:\n num_bvs_effective = 48\n else:\n num_bvs_effective = 2*math.ceil(\n num_samples_listeria_remaining/2) % 48\n\n num_additional_listeria_buffers = math.ceil(\n ((num_samples_listeria-1) - num_bvs_effective)/48)\n\n # print(f'partial: {num_partial_listeria_buffers}')\n # print(f'additional: {num_additional_listeria_buffers}')\n\n enzyme_listeria_1_creation = enzyme_listeria_1[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers+num_additional_listeria_buffers]\n enzyme_listeria_2_creation = enzyme_listeria_2[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers+num_additional_listeria_buffers]\n lysis_buffer_listeria_creation = lysis_buffer_listeria[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers+num_additional_listeria_buffers]\n # print(lysis_buffer_listeria_creation)\n\n # load partial liq\n if num_samples_listeria > 0:\n try:\n [\n well.load_liquid(\n lysis_buffer_l_prepared_liq,\n volume=11000/num_partial_listeria_buffers)\n for well in lysis_buffer_listeria[\n :num_partial_listeria_buffers]]\n\n # load full liq\n [\n well.load_liquid(\n lysis_buffer_l_fresh_liq,\n volume=11000/num_additional_listeria_buffers)\n for well in lysis_buffer_listeria[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers +\n num_additional_listeria_buffers]]\n [\n well.load_liquid(\n enzyme_listeria_1_liq,\n volume=500/num_additional_listeria_buffers)\n for well in enzyme_listeria_1[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers +\n num_additional_listeria_buffers]]\n [\n well.load_liquid(\n enzyme_listeria_2_liq,\n volume=500/num_additional_listeria_buffers)\n for well in enzyme_listeria_2[\n num_partial_listeria_buffers:\n num_partial_listeria_buffers +\n num_additional_listeria_buffers]]\n except AttributeError:\n pass\n\n # listeria\n for enzyme1, enzyme2, lysis_buff in zip(\n enzyme_listeria_1_creation,\n enzyme_listeria_2_creation,\n lysis_buffer_listeria_creation):\n # enzyme 1\n pick_up_single(m300)\n for _ in range(num_trans):\n m300.aspirate(\n vol_per_trans, enzyme1.bottom().move(\n Point(x=OFFSET_X_TUBERACK, z=1)))\n slow_withdraw(m300, enzyme1)\n m300.move_to(\n lysis_buff.top().move(\n Point(x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA)))\n m300.dispense(\n vol_per_trans,\n lysis_buff.bottom().move(\n Point(x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA,\n z=3)))\n m300.blow_out()\n slow_withdraw(\n m300, lysis_buff, y_offset=OFFSET_Y_LYSIS_BUFFER_LISTERIA)\n drop(m300)\n\n # enzyme 2\n pick_up_single(m300)\n for i in range(num_trans):\n m300.aspirate(\n vol_per_trans, enzyme2.bottom().move(\n Point(x=OFFSET_X_TUBERACK, z=1)))\n slow_withdraw(m300, enzyme2)\n m300.move_to(\n lysis_buff.top().move(Point(\n x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA)))\n m300.dispense(\n vol_per_trans,\n lysis_buff.bottom().move(\n Point(x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA,\n z=3)))\n if i == num_trans - 1:\n if DO_MIX:\n m300.flow_rate.aspirate *= 2\n m300.flow_rate.dispense *= 2\n m300.mix(\n 10, 200,\n lysis_buff.bottom().move(Point(\n x=OFFSET_X_TUBERACK,\n z=3, y=OFFSET_Y_LYSIS_BUFFER_LISTERIA)))\n m300.flow_rate.aspirate /= 2\n m300.flow_rate.dispense /= 2\n m300.blow_out(\n lysis_buff.bottom().move(Point(\n x=OFFSET_X_TUBERACK,\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA, z=3)))\n slow_withdraw(\n m300, lysis_buff, y_offset=OFFSET_Y_LYSIS_BUFFER_LISTERIA)\n drop(m300)\n\n # salmonella\n if num_samples_salmonella_remaining % 48 == 0 or \\\n num_samples_salmonella_remaining == 47:\n num_partial_salmonella_buffers = 0\n num_bvs_effective = 0\n else:\n num_partial_salmonella_buffers = 1\n if 2*math.ceil(num_samples_salmonella_remaining/2) % 48 == 0:\n num_bvs_effective = 48\n else:\n num_bvs_effective = 2*math.ceil(\n num_samples_salmonella_remaining/2) % 48\n\n num_additional_salmonella_buffers = math.ceil(\n ((num_samples_salmonella-1) - num_bvs_effective)/48)\n\n enzyme_salmonella_creation = enzyme_salmonella[\n num_partial_salmonella_buffers:\n num_partial_salmonella_buffers+num_additional_salmonella_buffers]\n lysis_buffer_salmonella_creation = lysis_buffer_salmonella[\n num_partial_salmonella_buffers:\n num_partial_salmonella_buffers+num_additional_salmonella_buffers]\n\n # load partial liq\n if num_samples_salmonella > 0:\n try:\n [\n well.load_liquid(\n lysis_buffer_s_prepared_liq,\n volume=11000/num_partial_salmonella_buffers)\n for well in lysis_buffer_salmonella[\n :num_partial_salmonella_buffers]]\n\n # load full liq\n [\n well.load_liquid(\n lysis_buffer_s_fresh_liq,\n volume=11000/num_additional_salmonella_buffers)\n for well in lysis_buffer_salmonella[\n num_partial_salmonella_buffers:\n num_partial_salmonella_buffers +\n num_additional_salmonella_buffers]]\n [\n well.load_liquid(\n enzyme_salmonella_liq,\n volume=500/num_additional_salmonella_buffers)\n for well in enzyme_salmonella[\n num_partial_salmonella_buffers:\n num_partial_salmonella_buffers +\n num_additional_salmonella_buffers]]\n except AttributeError:\n pass\n\n for enzyme, lysis_buff in zip(enzyme_salmonella_creation,\n lysis_buffer_salmonella_creation):\n # enzyme\n pick_up_single(m300)\n for i in range(num_trans):\n m300.aspirate(vol_per_trans, enzyme.bottom().move(\n Point(x=OFFSET_X_TUBERACK, z=1)))\n slow_withdraw(m300, enzyme)\n m300.move_to(\n lysis_buff.top().move(\n Point(x=OFFSET_X_TUBERACK,\n y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA)))\n m300.dispense(\n vol_per_trans,\n lysis_buff.bottom().move(\n Point(x=OFFSET_X_TUBERACK,\n y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA,\n z=3)))\n if i == num_trans - 1:\n if DO_MIX:\n m300.flow_rate.aspirate *= 2\n m300.flow_rate.dispense *= 2\n m300.mix(\n 10, 200,\n lysis_buff.bottom().move(Point(\n x=OFFSET_X_TUBERACK,\n z=3, y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA)))\n m300.flow_rate.aspirate /= 2\n m300.flow_rate.dispense /= 2\n m300.blow_out(\n lysis_buff.bottom().move(\n Point(x=OFFSET_X_TUBERACK,\n y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA,\n z=3)))\n slow_withdraw(\n m300, lysis_buff,\n y_offset=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA)\n drop(m300)\n\n \"\"\" transfer lysis buffer to lysis plate \"\"\"\n vol_overage = 20\n\n if num_samples_listeria > 0:\n if DO_DISTRIBUTE_LYSIS_BUFFER:\n lysis_buffer_listeria_dests = lysis_plate.wells()[\n :num_samples_listeria-2] + [\n lysis_plate.wells()[num_samples_listeria-1]]\n vol_lysis_buffer_listeria = 70.0\n num_dests_per_asp = int(\n (tip_ref.max_volume-vol_overage)//vol_lysis_buffer_listeria)\n num_asp = math.ceil(\n len(lysis_buffer_listeria_dests)/num_dests_per_asp)\n lysis_buffer_listeria_dest_sets = [\n lysis_buffer_listeria_dests[i*num_dests_per_asp:\n (i+1)*num_dests_per_asp]\n if i < num_asp - 1\n else lysis_buffer_listeria_dests[i*num_dests_per_asp:]\n for i in range(num_asp)]\n pick_up_single(m300)\n m300.aspirate(\n vol_overage,\n lysis_buffer_listeria[0].bottom().move(Point(\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA,\n z=OFFSET_Z_LYSIS_BUFFER_LISTERIA)))\n num_asp_listeria_remaining = math.ceil(\n (num_samples_listeria_remaining % 48) / 2)\n bump = 24 - num_asp_listeria_remaining \\\n if 24 - num_asp_listeria_remaining != 24 else 0\n for i, d_set in enumerate(lysis_buffer_listeria_dest_sets):\n set_ind = i + bump\n lysis_buff = lysis_buffer_listeria[set_ind//24]\n # m300.blow_out(lysis_buff.top(-1))\n m300.aspirate(\n len(d_set)*vol_lysis_buffer_listeria,\n lysis_buff.bottom().move(Point(\n y=OFFSET_Y_LYSIS_BUFFER_LISTERIA,\n z=OFFSET_Z_LYSIS_BUFFER_LISTERIA)))\n slow_withdraw(\n m300, lysis_buff, y_offset=OFFSET_Y_LYSIS_BUFFER_LISTERIA)\n for d in d_set:\n m300.dispense(vol_lysis_buffer_listeria, d.bottom(2))\n slow_withdraw(m300, d)\n drop(m300)\n\n if num_samples_salmonella > 0:\n if DO_DISTRIBUTE_LYSIS_BUFFER:\n available_wells = [\n well for col in lysis_plate.columns()[num_cols_listeria:]\n for well in col]\n lysis_buffer_salmonella_dests = available_wells[\n :num_samples_salmonella-2] + [\n available_wells[num_samples_salmonella-1]]\n vol_lysis_buffer_salmonella = 90.0 if not salmonella_meat else 50.0\n num_dests_per_asp = 2 # hard-set for now\n num_asp = math.ceil(\n len(lysis_buffer_salmonella_dests)/num_dests_per_asp)\n lysis_buffer_salmonella_dest_sets = [\n lysis_buffer_salmonella_dests[i*num_dests_per_asp:\n (i+1)*num_dests_per_asp]\n if i < num_asp - 1\n else lysis_buffer_salmonella_dests[i*num_dests_per_asp:]\n for i in range(num_asp)]\n pick_up_single(m300)\n m300.aspirate(\n vol_overage,\n lysis_buffer_salmonella[0].bottom().move(\n Point(y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA,\n z=OFFSET_Z_LYSIS_BUFFER_SALMONELLA)))\n num_asp_salmonella_remaining = math.ceil(\n (num_samples_salmonella_remaining % 48) / 2)\n bump_check = int(48/num_dests_per_asp)\n bump = bump_check - num_asp_salmonella_remaining \\\n if bump_check - num_asp_salmonella_remaining != bump_check \\\n else 0\n for i, d_set in enumerate(lysis_buffer_salmonella_dest_sets):\n set_ind = i + bump\n lysis_buff = lysis_buffer_salmonella[set_ind//bump_check]\n # m300.blow_out(lysis_buff.top(-1))\n # print('salmonella', i, set_ind, lysis_buff, len(d_set))\n # m300.blow_out(lysis_buff.top(-1))\n m300.aspirate(\n len(d_set)*vol_lysis_buffer_salmonella,\n lysis_buff.bottom().move(Point(\n y=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA,\n z=OFFSET_Z_LYSIS_BUFFER_SALMONELLA)))\n slow_withdraw(m300, lysis_buff,\n y_offset=-OFFSET_Y_LYSIS_BUFFER_SALMONELLA)\n for d in d_set:\n m300.dispense(vol_lysis_buffer_salmonella, d.bottom(2))\n slow_withdraw(m300, d)\n drop(m300)\n\n if DO_TRANSFER_SAMPLE_TO_LYSIS:\n \"\"\" transfer listeria \"\"\"\n vol_listeria = 30.0\n num_sample_cols_listeria = math.ceil((num_samples_listeria-2)/8)\n for s, d in zip(sample_plate.rows()[0][:num_sample_cols_listeria],\n lysis_plate.rows()[0][:num_sample_cols_listeria]):\n if sample_rack_type == 'bioplastics':\n asp_loc = s.bottom(2)\n else:\n asp_loc = s.top(-17.36)\n m300.pick_up_tip()\n m300.aspirate(vol_listeria, asp_loc)\n slow_withdraw(m300, s)\n m300.dispense(vol_listeria, d.bottom(2))\n if DO_MIX:\n m300.mix(3, 50, d.bottom(2))\n m300.blow_out(d.bottom(2))\n slow_withdraw(m300, d)\n drop(m300)\n\n \"\"\" transfer salmonella \"\"\"\n [pip, vol_salmonella] = [m20, 10.0] \\\n if not salmonella_meat else [m300, 50.0]\n num_cols_samples_salmonella = math.ceil((num_samples_salmonella-2)/8)\n for s, d in zip(\n sample_plate.rows()[0][\n num_cols_listeria:\n num_cols_listeria+num_cols_samples_salmonella],\n lysis_plate.rows()[0][\n num_cols_listeria:\n num_cols_listeria+num_cols_samples_salmonella]):\n pip.pick_up_tip()\n if sample_rack_type == 'bioplastics':\n asp_loc = s.bottom(2)\n else:\n asp_loc = s.top(-17.36)\n pip.aspirate(vol_salmonella, asp_loc)\n slow_withdraw(pip, s)\n pip.dispense(vol_salmonella, d.bottom(2))\n if DO_MIX:\n pip.mix(3, 18, d.bottom(2))\n pip.blow_out(d.bottom(2))\n slow_withdraw(pip, d)\n drop(pip)\n\n if DO_SET_TEMP:\n ctx.delay(minutes=20, msg='Incubating for 20 minutes @ 37C.')\n tempdeck.set_temperature(95)\n ctx.delay(minutes=10, msg='Incubating for 10 minutes @ 95C.')\n tempdeck.set_temperature(37)\n\n if DO_TRANSFER_SAMPLE_TO_PCR:\n \"\"\" transfer samples to PCR plate \"\"\"\n\n # listeria\n if num_samples_listeria > 0:\n for s, d in zip(lysis_plate.rows()[0][:num_cols_listeria],\n pcr_plate.rows()[0][:num_cols_listeria]):\n m20.pick_up_tip()\n m20.aspirate(5, s.top()) # pre air gap\n m20.aspirate(vol_sample, s)\n slow_withdraw(m20, s)\n m20.dispense(vol_sample, d.bottom(1))\n # if DO_MIX:\n # m20.mix(3, vol_sample*0.8, d.bottom(1))\n m20.dispense(m20.current_volume, d.bottom(1))\n slow_withdraw(m20, d)\n # wick(m20, d)\n drop(m20)\n\n # salmonella\n if num_samples_salmonella > 0:\n for s, d in zip(\n lysis_plate.rows()[0][\n num_cols_listeria:\n num_cols_listeria+num_cols_salmonella],\n pcr_plate.rows()[0][\n num_cols_listeria:\n num_cols_listeria+num_cols_salmonella]):\n m20.pick_up_tip()\n m20.aspirate(5, s.top()) # pre air gap\n m20.aspirate(vol_sample, s)\n slow_withdraw(m20, s)\n m20.dispense(vol_sample, d.bottom(1))\n # if DO_MIX:\n # m20.mix(3, vol_sample*0.8, d.bottom(1))\n m20.dispense(m20.current_volume, d.bottom(1))\n slow_withdraw(m20, d)\n m20.air_gap(5)\n # wick(m20, d)\n drop(m20)\n\n if DO_TRANSFER_POSITIVE_CONTROL:\n \"\"\" transfer positive controls \"\"\"\n vol_positive_control = vol_sample\n if num_samples_listeria > 0:\n positive_control_l_dest = pcr_plate.wells()[num_samples_listeria-2]\n pick_up_single(m20)\n m20.aspirate(5, positive_control_l_dest.top()) # pre air gap\n m20.aspirate(vol_positive_control, positive_control_l)\n slow_withdraw(m20, positive_control_l)\n m20.dispense(m20.current_volume, positive_control_l_dest.bottom(1))\n slow_withdraw(m20, positive_control_l_dest)\n # if DO_MIX:\n # m20.mix(3, vol_positive_control*0.8,\n # positive_control_l_dest.bottom(1))\n # wick(m20, positive_control_l_dest)\n drop(m20)\n\n if num_samples_salmonella > 0:\n available_wells = [\n well for col in pcr_plate.columns()[num_cols_listeria:]\n for well in col]\n positive_control_s_dest = available_wells[num_samples_salmonella-2]\n pick_up_single(m20)\n m20.aspirate(5, positive_control_s.top()) # pre air gap\n m20.aspirate(vol_positive_control, positive_control_s)\n slow_withdraw(m20, positive_control_s)\n m20.dispense(m20.current_volume, positive_control_s_dest.bottom(1))\n slow_withdraw(m20, positive_control_s_dest)\n # if DO_MIX:\n # m20.mix(3, vol_positive_control*0.8,\n # positive_control_s_dest.bottom(1))\n # wick(m20, positive_control_s_dest)\n drop(m20)\n\n tempdeck.deactivate()\n\n if do_flash:\n flash_lights()\n", "custom_labware_defs": [ { "brand": { @@ -4871,6 +4871,21 @@ } ], "type": "dropDown" + }, + { + "label": "flash on completion", + "name": "do_flash", + "options": [ + { + "label": "no", + "value": false + }, + { + "label": "yes", + "value": true + } + ], + "type": "dropDown" } ], "instruments": [ diff --git a/protocols/0b97ae-protocol-3B/0b97ae-protocol-3B.ot2.apiv2.py b/protocols/0b97ae-protocol-3B/0b97ae-protocol-3B.ot2.apiv2.py index 5a2bc25d9..3d3aa4788 100644 --- a/protocols/0b97ae-protocol-3B/0b97ae-protocol-3B.ot2.apiv2.py +++ b/protocols/0b97ae-protocol-3B/0b97ae-protocol-3B.ot2.apiv2.py @@ -53,9 +53,28 @@ def create_thread(ctx, cancel_token): def run(ctx: protocol_api.ProtocolContext): """PROTOCOLS.""" [ - num_samples, vol_dna , flash, bead_timer] = get_values( # noqa: F821 (<--- DO NOT REMOVE!) - "num_samples","vol_dna","flash","bead_timer") + num_samples, vol_dna , flash, bead_timer, reservoir, F_Plate, D_Plate, R_Plate] = get_values( # noqa: F821 (<--- DO NOT REMOVE!) + "num_samples","vol_dna","flash","bead_timer","reservoir","final_plate","dilution_plate","reagent_plate") num_samples = int(num_samples) + if reservoir == 'perkinelmer': + res_labware = 'perkinelmer_12_reservoir_21000ul' + else: + res_labware = 'nest_12_reservoir_15ml' + + if F_Plate == 'Biorad': + F_labware = 'opentrons_96_aluminumblock_biorad_wellplate_200ul' + else: + F_labware = 'appliedbiosystemsenduraplate_96_aluminumblock_220ul' + + if D_Plate == 'Biorad': + D_labware = 'opentrons_96_aluminumblock_biorad_wellplate_200ul' + else: + D_labware = 'appliedbiosystemsenduraplate_96_aluminumblock_220ul' + + if R_Plate == 'Biorad': + R_labware = 'biorad_96_wellplate_200ul_pcr' + else: + R_labware = 'appliedbiosystemsenduraplate_96_aluminumblock_220ul' 'Global variables' TEST_MODE = False @@ -83,13 +102,13 @@ def run(ctx: protocol_api.ProtocolContext): # load labware mag_plate = Mag_mod.load_labware('nest_96_wellplate_2ml_deep','Extraction Plate') - final_plate = tempdeck_1.load_labware('opentrons_96_aluminumblock_biorad_wellplate_200ul', #noqa: E501 + final_plate = tempdeck_1.load_labware(F_labware, #noqa: E501 'Reagent Plate') - Diluted_plate = tempdeck_2.load_labware('appliedbiosystemsenduraplate_96_aluminumblock_220ul', # noqa: E501 + Diluted_plate = tempdeck_2.load_labware(D_labware, # noqa: E501 'Diluted RNA plate') - water_res = ctx.load_labware('perkinelmer_12_reservoir_21000ul', 2, + water_res = ctx.load_labware(res_labware, 2, 'Water reservoir') - Reagent_plate = ctx.load_labware('biorad_96_wellplate_200ul_pcr', '1') + Reagent_plate = ctx.load_labware(R_labware, '1') # load tipracks tips3 = [ctx.load_labware('opentrons_96_tiprack_300ul', slot) diff --git a/protocols/0b97ae-protocol-3B/README.md b/protocols/0b97ae-protocol-3B/README.md index 2e5a120a2..2fc3530ce 100644 --- a/protocols/0b97ae-protocol-3B/README.md +++ b/protocols/0b97ae-protocol-3B/README.md @@ -42,7 +42,7 @@ Links: ### Deck Setup -![deck](https://opentrons-protocol-library-website.s3.amazonaws.com/custom-README-images/0b97ae/3F240714-EB34-4978-97F6-5BD0739E874B_1_105_c.jpeg) +![deck](https://opentrons-protocol-library-website.s3.amazonaws.com/custom-README-images/0b97ae/deck.jpg) Water Reservoir (slot 2): Column 1: Nuclease Free Water Column 2: Binding Buffer @@ -55,7 +55,7 @@ Reagent Plate (Slot 10): Column 2: Magentic Beads ### Reagent Setup -![reagents](https://opentrons-protocol-library-website.s3.amazonaws.com/custom-README-images/0b97ae/part+4/reagen.jpg) +![reagents](https://opentrons-protocol-library-website.s3.amazonaws.com/custom-README-images/0b97ae/reagents.jpg) ### Protocol Steps diff --git a/protocols/0b97ae-protocol-3B/fields.json b/protocols/0b97ae-protocol-3B/fields.json index 4164a7a51..46d2bbd88 100644 --- a/protocols/0b97ae-protocol-3B/fields.json +++ b/protocols/0b97ae-protocol-3B/fields.json @@ -38,5 +38,41 @@ "label": "Bead Timer?", "name": "bead_timer", "default": 6 + }, + { + "type": "dropDown", + "label": "Is the Reservoir PerkinElmer or Nest?", + "name": "reservoir", + "options": [ + {"label": "perkinelmer", "value": "perkinelmer"}, + {"label": "nest", "value": "nest"} + ] + }, + { + "type": "dropDown", + "label": "Is the Final Plate Biorad or AppliedBio?", + "name": "final_plate", + "options": [ + {"label": "Biorad", "value": "Biorad"}, + {"label": "AppliedBio", "value": "AppliedBio"} + ] + }, + { + "type": "dropDown", + "label": "Is the Diluted DNA Plate Biorad or AppliedBio?", + "name": "dilution_plate", + "options": [ + {"label": "Biorad", "value": "Biorad"}, + {"label": "AppliedBio", "value": "AppliedBio"} + ] + }, + { + "type": "dropDown", + "label": "Is the Reagent Plate Biorad or AppliedBio?", + "name": "reagent_plate", + "options": [ + {"label": "Biorad", "value": "Biorad"}, + {"label": "AppliedBio", "value": "AppliedBio"} + ] } ] diff --git a/protocols/gsdx/bacgene.ot2.apiv2.py b/protocols/gsdx/bacgene.ot2.apiv2.py index aa27099a6..1dead5756 100644 --- a/protocols/gsdx/bacgene.ot2.apiv2.py +++ b/protocols/gsdx/bacgene.ot2.apiv2.py @@ -19,9 +19,9 @@ DO_SET_TEMP = True REUSING_LYSIS_BUFFER = True OFFSET_Y_LYSIS_BUFFER_LISTERIA = 13.0 -OFFSET_Z_LYSIS_BUFFER_LISTERIA = -5.0 +OFFSET_Z_LYSIS_BUFFER_LISTERIA = -4.5 OFFSET_Y_LYSIS_BUFFER_SALMONELLA = 11.0 # magnitude (positive number!) -OFFSET_Z_LYSIS_BUFFER_SALMONELLA = -5.0 +OFFSET_Z_LYSIS_BUFFER_SALMONELLA = -4.5 OFFSET_X_TUBERACK = 0.5 P20_MOUNT = 'left' P300_MOUNT = 'right' @@ -29,12 +29,19 @@ def run(ctx): + def flash_lights(): + initial_status = ctx.rail_lights_on + for _ in range(19): + ctx.set_rail_lights(not ctx.rail_lights_on) + ctx.delay(seconds=0.25) + ctx.set_rail_lights(initial_status) + [num_samples_listeria, num_samples_salmonella, num_samples_listeria_remaining, num_samples_salmonella_remaining, - sample_rack_type, salmonella_meat] = get_values( # noqa: F821 + sample_rack_type, salmonella_meat, do_flash] = get_values( # noqa: F821 'num_samples_listeria', 'num_samples_salmonella', 'num_samples_listeria_remaining', 'num_samples_salmonella_remaining', - 'sample_rack_type', 'salmonella_meat') + 'sample_rack_type', 'salmonella_meat', 'do_flash') # modules tempdeck = ctx.load_module('temperature module gen2', '10') @@ -190,28 +197,34 @@ def run(ctx): num_cols_offset_samples_listeria*8+num_samples_salmonella] # load liquids + vol_sample = 5.0 + try: if num_samples_listeria > 0: - positive_control_l.load_liquid(positive_control_l_liq, volume=10) + positive_control_l.load_liquid( + positive_control_l_liq, volume=vol_sample) if num_samples_salmonella > 0: - positive_control_s.load_liquid(positive_control_s_liq, volume=10) + positive_control_s.load_liquid( + positive_control_s_liq, volume=vol_sample) [well.load_liquid(samples_listeria_liq_sample, - volume=30/len(samples_single_listeria)) - for well in samples_single_listeria] + volume=round(30/len(samples_single_listeria))) + for well in samples_single_listeria[ + :max(0, len(samples_single_listeria)-2)]] [well.load_liquid(samples_salmonella_liq_sample, - volume=10/len(samples_single_salmonella)) - for well in samples_single_salmonella] + volume=round(10/len(samples_single_salmonella))) + for well in samples_single_salmonella[ + :max(0, len(samples_single_salmonella)-2)]] [well.load_liquid(samples_listeria_liq_lysis, - volume=30/len(lysis_single_listeria)) + volume=round(30/len(lysis_single_listeria))) for well in lysis_single_listeria] [well.load_liquid(samples_salmonella_liq_lysis, - volume=10/len(lysis_single_salmonella)) + volume=round(10/len(lysis_single_salmonella))) for well in lysis_single_salmonella] [well.load_liquid(samples_listeria_liq_pcr, - volume=30/len(pcr_single_listeria)) + volume=round(30/len(pcr_single_listeria))) for well in pcr_single_listeria] [well.load_liquid(samples_salmonella_liq_pcr, - volume=10/len(pcr_single_salmonella)) + volume=round(10/len(pcr_single_salmonella))) for well in pcr_single_salmonella] except AttributeError: pass @@ -423,7 +436,7 @@ def wick(pip, well, x_magnitude=0.5, z_offset=3.0): num_partial_salmonella_buffers+num_additional_salmonella_buffers] # load partial liq - if num_samples_listeria > 0: + if num_samples_salmonella > 0: try: [ well.load_liquid( @@ -635,8 +648,6 @@ def wick(pip, well, x_magnitude=0.5, z_offset=3.0): ctx.delay(minutes=10, msg='Incubating for 10 minutes @ 95C.') tempdeck.set_temperature(37) - vol_sample = 5.0 - if DO_TRANSFER_SAMPLE_TO_PCR: """ transfer samples to PCR plate """ @@ -713,3 +724,6 @@ def wick(pip, well, x_magnitude=0.5, z_offset=3.0): drop(m20) tempdeck.deactivate() + + if do_flash: + flash_lights() diff --git a/protocols/gsdx/fields.json b/protocols/gsdx/fields.json index 543bf3099..0e7ff6cc5 100644 --- a/protocols/gsdx/fields.json +++ b/protocols/gsdx/fields.json @@ -1,44 +1,59 @@ [ - { - "type": "int", - "label": "number of listeria wells to run (including +/- controls)", - "name": "num_samples_listeria", - "default": 48 - }, - { - "type": "int", - "label": "number of salmonella wells to run (including +/- controls)", - "name": "num_samples_salmonella", - "default": 48 - }, - { - "type": "int", - "label": "number of listeria wells in kit remaining", - "name": "num_samples_listeria_remaining", - "default": 96 - }, - { - "type": "int", - "label": "number of salmonella wells in kit remaining", - "name": "num_samples_salmonella_remaining", - "default": 96 - }, - { - "type": "dropDown", - "label": "sample rack format", - "name": "sample_rack_type", - "options": [ - {"label": "KingFisher 96 Tube Rack with GoldStandard 1.1 mL", "value": "kingfisher_96_tuberack_1100ul"}, - {"label": "BIOPlastics BV 96 Aluminum Block 200 µL", "value": "bioplasticsbv_96_aluminumblock_200ul"} - ] - }, - { - "type": "dropDown", - "label": "running salmonella meat", - "name": "salmonella_meat", - "options": [ - {"label": "no", "value": false}, - {"label": "yes", "value": true} - ] - } -] \ No newline at end of file + { + "type": "int", + "label": "number of listeria wells to run (including +/- controls)", + "name": "num_samples_listeria", + "default": 48 + }, + { + "type": "int", + "label": "number of salmonella wells to run (including +/- controls)", + "name": "num_samples_salmonella", + "default": 48 + }, + { + "type": "int", + "label": "number of listeria wells in kit remaining", + "name": "num_samples_listeria_remaining", + "default": 96 + }, + { + "type": "int", + "label": "number of salmonella wells in kit remaining", + "name": "num_samples_salmonella_remaining", + "default": 96 + }, + { + "type": "dropDown", + "label": "sample rack format", + "name": "sample_rack_type", + "options": [ + { + "label": "KingFisher 96 Tube Rack with GoldStandard 1.1 mL", + "value": "kingfisher_96_tuberack_1100ul" + }, + { + "label": "BIOPlastics BV 96 Aluminum Block 200 µL", + "value": "bioplasticsbv_96_aluminumblock_200ul" + } + ] + }, + { + "type": "dropDown", + "label": "running salmonella meat", + "name": "salmonella_meat", + "options": [ + { "label": "no", "value": false }, + { "label": "yes", "value": true } + ] + }, + { + "type": "dropDown", + "label": "flash on completion", + "name": "do_flash", + "options": [ + { "label": "no", "value": false }, + { "label": "yes", "value": true } + ] + } +]