From e9e9fa3c7c38dac146f36cbbed85ca3344043237 Mon Sep 17 00:00:00 2001 From: ncdiehl11 Date: Thu, 7 Sep 2023 11:29:38 -0400 Subject: [PATCH] implement height tracking and viscosity checks --- .../0909e6/media_transfer.ot2.apiv2.py.json | 2 +- protocols/0909e6/media_transfer.ot2.apiv2.py | 72 ++++++++++++++++--- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/protoBuilds/0909e6/media_transfer.ot2.apiv2.py.json b/protoBuilds/0909e6/media_transfer.ot2.apiv2.py.json index ad11c74a5..1710ea15c 100644 --- a/protoBuilds/0909e6/media_transfer.ot2.apiv2.py.json +++ b/protoBuilds/0909e6/media_transfer.ot2.apiv2.py.json @@ -1,5 +1,5 @@ { - "content": "import math\nfrom opentrons.protocol_api.labware import Well\nfrom opentrons.protocols.api_support.types import APIVersion\n\nmetadata = {\n 'protocolName': 'DOE',\n 'author': 'Nick self.min_height:\n self.height = self.height - dh\n else:\n self.height = self.min_height\n if self.current_volume - vol > 0:\n self.current_volume = self.current_volume - vol\n else:\n self.current_volume = 0\n return self.well.bottom(self.height)\n\n def height_inc(self, vol):\n dh = (vol/(math.pi*(self.radius**2)))*self.comp_coeff\n if self.height + dh < self.depth:\n self.height = self.height + dh\n else:\n self.height = self.depth\n self.current_volume += vol\n return self.well.bottom(self.height + 20)\n\n # labware\n tuberack50 = ctx.load_labware('opentrons_6_tuberack_falcon_50ml_conical',\n '1', 'media tuberack')\n tuberacks15 = [\n ctx.load_labware(\n 'opentrons_15_tuberack_falcon_15ml_conical', slot,\n f'factors {tube_set}')\n for i, (slot, tube_set) in enumerate(\n zip(['4', '7'], ['1-15', '16-30']))]\n tuberacks2 = [\n ctx.load_labware(\n 'opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap', slot,\n f'factors {tube_set}')\n for i, (slot, tube_set) in enumerate(\n zip(['5', '8'], ['31-54', '55-78']))]\n plate = ctx.load_labware('usascientific_96_wellplate_2.4ml_deep', '2')\n tiprack_small = [ctx.load_labware(tiprack_small_type, '3')]\n tiprack1000 = [\n ctx.load_labware('opentrons_96_filtertiprack_1000ul', slot)\n for slot in ['6']]\n\n # pipettes\n pip_small = ctx.load_instrument(type_pipette_small, 'left',\n tip_racks=tiprack_small)\n p1000 = ctx.load_instrument('p1000_single_gen2', 'right',\n tip_racks=tiprack1000)\n\n # reagents\n vol_media_list = [float(val) for val in vol_media_tubes.split(',')]\n media_rows_ordered = [tube for row in tuberack50.rows() for tube in row]\n media = [\n WellH(well, current_volume=vol, height=well.depth*(vol/50000)*0.9)\n for well, vol in zip(\n media_rows_ordered[:len(vol_media_list)],\n [vol_media_tube*1000 for vol_media_tube in vol_media_list])]\n\n # parse data\n factor_data = [\n [float(val) for val in line.split(',')[1:] if val.strip()]\n for line in csv_factors.splitlines()[2:]\n ]\n\n all_factor_tubes = [\n well for rack_set in [tuberacks15, tuberacks2]\n for rack in rack_set\n for well in rack.wells()]\n\n factor_indices = [\n int(cell.strip().split(' ')[-1]) - 1\n for cell in csv_factors.splitlines()[0].split(',')[1:]\n if cell.strip()]\n factor_tubes = [\n all_factor_tubes[ind] for ind in factor_indices]\n factor_volumes_ul = [\n float(cell)*1000 for cell in csv_factors.splitlines()[1].split(',')[1:]\n if cell.strip()]\n # ref_vol = tuberacks15[0].wells()[0].max_volume / 1000 # 2ml or 15ml\n # ref_height = tuberacks15[0].wells()[0].depth\n factor_heights = [\n # ensure tip is submerged\n round(factor_vol/(factor_tube.max_volume)*factor_tube.depth*0.9,\n 1)\n for factor_tube, factor_vol in zip(factor_tubes, factor_volumes_ul)]\n factors = [\n WellH(well, current_volume=vol, height=height)\n for well, vol, height in zip(\n factor_tubes, factor_volumes_ul, factor_heights)]\n\n def slow_withdraw(well, pip=p1000):\n ctx.max_speeds['A'] = 25\n ctx.max_speeds['Z'] = 25\n pip.move_to(well.top())\n del ctx.max_speeds['A']\n del ctx.max_speeds['Z']\n\n def split_media_vol(vol):\n num_transfers = math.ceil(vol/(1000-vol_pre_airgap_1000))\n vol_per_transfer = round(vol/num_transfers, 1)\n return [vol_per_transfer]*num_transfers\n\n # iterate\n iterator_media = iter(media)\n current_media = next(iterator_media)\n\n def check_media(vol):\n nonlocal current_media\n if current_media.current_volume - vol < current_media.min_vol:\n current_media = next(iterator_media)\n\n def custom_distribute(info, pip):\n pip_volume = pip.tip_racks[0].wells()[0].max_volume\n vol_pre_airgap = vol_pre_airgap_small if pip == \\\n pip_small else vol_pre_airgap_1000\n max_vol = pip_volume\n sets = []\n running = []\n current_vol = 0\n for d in info:\n well = [key for key in d.keys()][0]\n vol = [val for val in d.values()][0]\n if vol > 0:\n if current_vol + vol + vol_pre_airgap > max_vol:\n sets.append(running)\n running = []\n current_vol = 0\n running.append({well: vol})\n current_vol += vol + vol_pre_airgap\n sets.append(running)\n return sets\n\n # transfer media\n p1000.pick_up_tip()\n wells_ordered = [well for row in plate.rows() for well in row]\n vols_media = [\n float(line.split(',')[0]) for line in csv_factors.splitlines()[2:]]\n media_info = []\n for well, vol_media in zip(wells_ordered, vols_media):\n vols_split = split_media_vol(vol_media)\n for vol in vols_split:\n media_info.append({well: vol})\n\n for d in media_info:\n well = list(d.keys())[0]\n asp_vol = list(d.values())[0]\n if p1000.current_volume:\n p1000.dispense(p1000.current_volume, current_media.well.top())\n check_media(asp_vol)\n p1000.aspirate(vol_pre_airgap_1000, current_media.well.top())\n p1000.aspirate(asp_vol, current_media.height_dec(asp_vol))\n slow_withdraw(current_media.well, p1000)\n p1000.dispense(p1000.current_volume, well.bottom(well.depth/2))\n p1000.blow_out(well.bottom(well.depth/2))\n slow_withdraw(well, p1000)\n\n # media_sets = custom_distribute(media_info, pip=p1000)\n # for media_set in media_sets:\n # if p1000.current_volume:\n # p1000.dispense(p1000.current_volume, current_media.well.top())\n # # pre-air_gap to fully void tip on blow_out\n # for d in media_set:\n # asp_vol = sum(d.values())\n # check_media(asp_vol)\n # p1000.aspirate(vol_pre_airgap_1000, current_media.well.top())\n # p1000.aspirate(asp_vol, current_media.height_dec(asp_vol))\n # slow_withdraw(current_media.well, p1000)\n # for i, d in enumerate(media_set):\n # well = [key for key in d.keys()][0]\n # vol = [val for val in d.values()][0]\n # p1000.dispense(vol+vol_pre_airgap_1000,\n # well.bottom(well.depth/2))\n # if i == len(media_set) - 1:\n # p1000.blow_out(well.bottom(well.depth/2))\n # slow_withdraw(well, p1000)\n p1000.return_tip()\n p1000.reset_tipracks()\n\n # transfer factors\n for i, factor in enumerate(factors):\n factor_vols = [line[i] for line in factor_data]\n factor_info = [\n {well: vol}\n for well, vol in zip(wells_ordered, factor_vols)]\n factor_sets = custom_distribute(factor_info, pip=pip_small)\n for factor_set in factor_sets:\n # aspirate total vol needed\n if not pip_small.has_tip:\n pip_small.pick_up_tip()\n # pre-air_gap to fully void tip on blow_out\n for d in factor_set:\n well = [k for k in d.keys()][0]\n asp_vol = [k for k in d.values()][0]\n if asp_vol + vol_pre_airgap_small <= pip_small.max_volume:\n ag_vol = vol_pre_airgap_small\n else:\n ag_vol = pip_small.max_volume - asp_vol\n pip_small.aspirate(ag_vol, factor.well.top())\n pip_small.aspirate(asp_vol, factor.height_dec(asp_vol))\n slow_withdraw(factor.well, pip_small)\n pip_small.dispense(\n pip_small.current_volume, well.bottom(well.depth/2))\n pip_small.blow_out(well.top(-2))\n\n # total_factor_vol = sum([sum(dict.values()) for dict in\n # factor_set])\n # p300.aspirate(total_factor_vol,\n # factor.height_dec(total_factor_vol))\n # for i, dict in enumerate(factor_set):\n # for well, vol in dict.items():\n # pip_small.dispense(\n # vol+vol_pre_airgap_small, well.bottom(well.depth/2))\n # if i == len(factor_set) - 1:\n # pip_small.blow_out(well.top(-2))\n\n # for d in factor_set:\n # asp_vol = sum(d.values())\n # if asp_vol + vol_pre_airgap_small <= pip_small.max_volume:\n # ag_vol = vol_pre_airgap_small\n # else:\n # ag_vol = pip_small.max_volume - asp_vol\n # pip_small.aspirate(ag_vol, factor.well.top())\n # pip_small.aspirate(asp_vol, factor.height_dec(asp_vol))\n # # total_factor_vol = sum([sum(dict.values()) for dict in\n # # factor_set])\n # # p300.aspirate(total_factor_vol,\n # # factor.height_dec(total_factor_vol))\n # slow_withdraw(factor.well, pip_small)\n # for i, dict in enumerate(factor_set):\n # for well, vol in dict.items():\n # pip_small.dispense(\n # vol+vol_pre_airgap_small, well.bottom(well.depth/2))\n # if i == len(factor_set) - 1:\n # pip_small.blow_out(well.top(-2))\n if pip_small.has_tip:\n pip_small.drop_tip()\n\n # mix\n for well in plate.wells()[:len(factor_data)]:\n p1000.pick_up_tip()\n p1000.mix(reps_mix, vol_mix, well.bottom(2))\n slow_withdraw(well, p1000)\n p1000.drop_tip()\n", + "content": "import math\nfrom opentrons.protocol_api.labware import Well\nfrom opentrons.protocols.api_support.types import APIVersion\nfrom opentrons.types import Point\n\nmetadata = {\n 'protocolName': 'DOE',\n 'author': 'Nick self.min_height:\n self.height = self.height - dh\n else:\n self.height = self.min_height\n if self.current_volume - vol > 0:\n self.current_volume = self.current_volume - vol\n else:\n self.current_volume = 0\n return self.well.bottom(self.height)\n\n def height_inc(self, vol):\n dh = (vol/(math.pi*(self.radius**2)))*self.comp_coeff\n if self.height + dh < self.depth:\n self.height = self.height + dh\n else:\n self.height = self.depth\n self.current_volume += vol\n return self.well.bottom(self.height + 20)\n\n # labware\n tuberack50 = ctx.load_labware('opentrons_6_tuberack_falcon_50ml_conical',\n '1', 'media tuberack')\n tuberacks15 = [\n ctx.load_labware(\n 'opentrons_15_tuberack_falcon_15ml_conical', slot,\n f'factors {tube_set}')\n for i, (slot, tube_set) in enumerate(\n zip(['4', '7'], ['1-15', '16-30']))]\n tuberacks2 = [\n ctx.load_labware(\n 'opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap', slot,\n f'factors {tube_set}')\n for i, (slot, tube_set) in enumerate(\n zip(['5', '8'], ['31-54', '55-78']))]\n plate = ctx.load_labware('usascientific_96_wellplate_2.4ml_deep', '2')\n tiprack_small = [ctx.load_labware(tiprack_small_type, '3')]\n tiprack1000 = [\n ctx.load_labware('opentrons_96_filtertiprack_1000ul', slot)\n for slot in ['6']]\n\n # pipettes\n pip_small = ctx.load_instrument(type_pipette_small, 'left',\n tip_racks=tiprack_small)\n p1000 = ctx.load_instrument('p1000_single_gen2', 'right',\n tip_racks=tiprack1000)\n\n # reagents\n vol_media_list = [float(val) for val in vol_media_tubes.split(',')]\n media_rows_ordered = [tube for row in tuberack50.rows() for tube in row]\n media = [\n WellH(well, current_volume=vol, height=well.depth*(vol/50000)*0.9)\n for well, vol in zip(\n media_rows_ordered[:len(vol_media_list)],\n [vol_media_tube*1000 for vol_media_tube in vol_media_list])]\n\n # parse data\n factor_data = [\n [float(val) for val in line.split(',')[1:] if val.strip()]\n for line in csv_factors.splitlines()[3:]\n ]\n\n all_factor_tubes = [\n well for rack_set in [tuberacks15, tuberacks2]\n for rack in rack_set\n for well in rack.wells()]\n\n factor_indices = [\n int(cell.strip().split(' ')[-1]) - 1\n for cell in csv_factors.splitlines()[0].split(',')[1:]\n if cell.strip()]\n factor_tubes = [\n all_factor_tubes[ind] for ind in factor_indices]\n factor_viscosities = [\n bool(visc) for visc in csv_factors.splitlines()[1].split(',')[1:]\n if visc.strip()]\n factor_volumes_ul = [\n float(cell)*1000 for cell in csv_factors.splitlines()[2].split(',')[1:]\n if cell.strip()]\n # ref_vol = tuberacks15[0].wells()[0].max_volume / 1000 # 2ml or 15ml\n # ref_height = tuberacks15[0].wells()[0].depth\n factor_heights = [\n # ensure tip is submerged\n round(factor_vol/(factor_tube.max_volume)*factor_tube.depth*0.9,\n 1)\n for factor_tube, factor_vol in zip(factor_tubes, factor_volumes_ul)]\n factors = [\n WellH(well, current_volume=vol, height=height)\n for well, vol, height in zip(\n factor_tubes, factor_volumes_ul, factor_heights)]\n\n def slow_withdraw(well, pip=p1000, delay_s=2.0):\n ctx.max_speeds['A'] = 25\n ctx.max_speeds['Z'] = 25\n if delay_s > 0:\n ctx.delay(seconds=delay_s)\n pip.move_to(well.top())\n del ctx.max_speeds['A']\n del ctx.max_speeds['Z']\n\n def split_media_vol(vol):\n num_transfers = math.ceil(vol/(1000-vol_pre_airgap_1000))\n vol_per_transfer = round(vol/num_transfers, 1)\n return [vol_per_transfer]*num_transfers\n\n # iterate\n iterator_media = iter(media)\n current_media = next(iterator_media)\n\n def check_media(vol):\n nonlocal current_media\n if current_media.current_volume - vol < current_media.min_vol:\n current_media = next(iterator_media)\n\n def custom_distribute(info, pip):\n pip_volume = pip.tip_racks[0].wells()[0].max_volume\n vol_pre_airgap = vol_pre_airgap_small if pip == \\\n pip_small else vol_pre_airgap_1000\n max_vol = pip_volume\n sets = []\n running = []\n current_vol = 0\n for d in info:\n well = [key for key in d.keys()][0]\n vol = [val for val in d.values()][0]\n if vol > 0:\n if current_vol + vol + vol_pre_airgap > max_vol:\n sets.append(running)\n running = []\n current_vol = 0\n running.append({well: vol})\n current_vol += vol + vol_pre_airgap\n sets.append(running)\n return sets\n\n # transfer media\n p1000.pick_up_tip()\n wells_ordered = [well for row in plate.rows() for well in row]\n vols_media = [\n float(line.split(',')[0]) for line in csv_factors.splitlines()[2:]]\n media_info = []\n for well, vol_media in zip(wells_ordered, vols_media):\n vols_split = split_media_vol(vol_media)\n for vol in vols_split:\n media_info.append({well: vol})\n\n wells_h = [\n WellH(well, height=0) for well in wells_ordered]\n\n for d in media_info:\n well = list(d.keys())[0]\n asp_vol = list(d.values())[0]\n if p1000.current_volume:\n p1000.dispense(p1000.current_volume, current_media.well.top())\n check_media(asp_vol)\n p1000.aspirate(vol_pre_airgap_1000, current_media.well.top())\n p1000.aspirate(asp_vol, current_media.height_dec(asp_vol))\n slow_withdraw(current_media.well, p1000)\n p1000.dispense(p1000.current_volume, well.bottom(well.depth/2))\n p1000.blow_out(well.bottom(well.depth/2))\n slow_withdraw(well, p1000)\n\n # media_sets = custom_distribute(media_info, pip=p1000)\n # for media_set in media_sets:\n # if p1000.current_volume:\n # p1000.dispense(p1000.current_volume, current_media.well.top())\n # # pre-air_gap to fully void tip on blow_out\n # for d in media_set:\n # asp_vol = sum(d.values())\n # check_media(asp_vol)\n # p1000.aspirate(vol_pre_airgap_1000, current_media.well.top())\n # p1000.aspirate(asp_vol, current_media.height_dec(asp_vol))\n # slow_withdraw(current_media.well, p1000)\n # for i, d in enumerate(media_set):\n # well = [key for key in d.keys()][0]\n # vol = [val for val in d.values()][0]\n # p1000.dispense(vol+vol_pre_airgap_1000,\n # well.bottom(well.depth/2))\n # if i == len(media_set) - 1:\n # p1000.blow_out(well.bottom(well.depth/2))\n # slow_withdraw(well, p1000)\n p1000.return_tip()\n p1000.reset_tipracks()\n\n viscosity_map = {\n 20: {\n 'aspirate': 6.5,\n 'delay_aspiration': 2.0,\n 'dispense': 6.5,\n 'delay_dispense': 2.0,\n 'default': 7.56\n },\n 300: {\n 'aspirate': 80,\n 'delay_aspiration': 2.0,\n 'dispense': 80,\n 'delay_dispense': 2.0,\n 'default': 92.86\n },\n 1000: {\n 'aspirate': 247,\n 'delay_aspiration': 2.0,\n 'dispense': 247,\n 'delay_dispense': 2.0,\n 'default': 247\n }\n }\n\n # transfer factors\n for i, (visc, factor) in enumerate(zip(factor_viscosities, factors)):\n factor_vols = [line[i] for line in factor_data]\n factor_info = [\n {well: vol}\n for well, vol in zip(wells_h, factor_vols)]\n factor_sets = custom_distribute(factor_info, pip=pip_small)\n if visc:\n asp_rate_relative = viscosity_map[\n int(pip_small.max_volume)]['aspirate'] / (\n viscosity_map[int(pip_small.max_volume)]['default'])\n asp_delay = viscosity_map[\n int(pip_small.max_volume)]['delay_aspiration']\n disp_rate_relative = viscosity_map[\n int(pip_small.max_volume)]['dispense'] / (\n viscosity_map[int(pip_small.max_volume)]['default'])\n disp_delay = viscosity_map[\n int(pip_small.max_volume)]['delay_dispense']\n else:\n asp_rate_relative = 1\n asp_delay = 2.0\n disp_rate_relative = 1\n disp_delay = 2.0\n for factor_set in factor_sets:\n # aspirate total vol needed\n if not pip_small.has_tip:\n pip_small.pick_up_tip()\n # pre-air_gap to fully void tip on blow_out\n for d in factor_set:\n well = [k for k in d.keys()][0]\n asp_vol = [k for k in d.values()][0]\n if asp_vol + vol_pre_airgap_small <= pip_small.max_volume:\n ag_vol = vol_pre_airgap_small\n else:\n ag_vol = pip_small.max_volume - asp_vol\n pip_small.aspirate(ag_vol, factor.well.top())\n pip_small.aspirate(\n asp_vol, factor.height_dec(asp_vol),\n rate=asp_rate_relative)\n slow_withdraw(factor.well, pip_small, delay_s=asp_delay)\n pip_small.dispense(\n pip_small.current_volume,\n well.height_inc(asp_vol).move(Point(z=3)),\n rate=disp_rate_relative)\n ctx.delay(seconds=disp_delay)\n pip_small.blow_out(well.top(-2))\n\n # total_factor_vol = sum([sum(dict.values()) for dict in\n # factor_set])\n # p300.aspirate(total_factor_vol,\n # factor.height_dec(total_factor_vol))\n # for i, dict in enumerate(factor_set):\n # for well, vol in dict.items():\n # pip_small.dispense(\n # vol+vol_pre_airgap_small, well.bottom(well.depth/2))\n # if i == len(factor_set) - 1:\n # pip_small.blow_out(well.top(-2))\n\n # for d in factor_set:\n # asp_vol = sum(d.values())\n # if asp_vol + vol_pre_airgap_small <= pip_small.max_volume:\n # ag_vol = vol_pre_airgap_small\n # else:\n # ag_vol = pip_small.max_volume - asp_vol\n # pip_small.aspirate(ag_vol, factor.well.top())\n # pip_small.aspirate(asp_vol, factor.height_dec(asp_vol))\n # # total_factor_vol = sum([sum(dict.values()) for dict in\n # # factor_set])\n # # p300.aspirate(total_factor_vol,\n # # factor.height_dec(total_factor_vol))\n # slow_withdraw(factor.well, pip_small)\n # for i, dict in enumerate(factor_set):\n # for well, vol in dict.items():\n # pip_small.dispense(\n # vol+vol_pre_airgap_small, well.bottom(well.depth/2))\n # if i == len(factor_set) - 1:\n # pip_small.blow_out(well.top(-2))\n if pip_small.has_tip:\n pip_small.drop_tip()\n\n # mix\n for well in plate.wells()[:len(factor_data)]:\n p1000.pick_up_tip()\n p1000.mix(reps_mix, vol_mix, well.bottom(2))\n slow_withdraw(well, p1000)\n p1000.drop_tip()\n", "custom_labware_defs": [], "fields": [ { diff --git a/protocols/0909e6/media_transfer.ot2.apiv2.py b/protocols/0909e6/media_transfer.ot2.apiv2.py index 9ed17a652..b67c22805 100644 --- a/protocols/0909e6/media_transfer.ot2.apiv2.py +++ b/protocols/0909e6/media_transfer.ot2.apiv2.py @@ -1,6 +1,7 @@ import math from opentrons.protocol_api.labware import Well from opentrons.protocols.api_support.types import APIVersion +from opentrons.types import Point metadata = { 'protocolName': 'DOE', @@ -36,7 +37,7 @@ def __init__(self, well, height=5, min_height=2.5, self.height = height self.min_height = min_height self.comp_coeff = comp_coeff - self.radius = self.diameter/2 + self.radius = self.diameter/2 if self.diameter else self.width/2 self.current_volume = current_volume self.min_vol = min_vol @@ -100,7 +101,7 @@ def height_inc(self, vol): # parse data factor_data = [ [float(val) for val in line.split(',')[1:] if val.strip()] - for line in csv_factors.splitlines()[2:] + for line in csv_factors.splitlines()[3:] ] all_factor_tubes = [ @@ -114,8 +115,11 @@ def height_inc(self, vol): if cell.strip()] factor_tubes = [ all_factor_tubes[ind] for ind in factor_indices] + factor_viscosities = [ + bool(visc) for visc in csv_factors.splitlines()[1].split(',')[1:] + if visc.strip()] factor_volumes_ul = [ - float(cell)*1000 for cell in csv_factors.splitlines()[1].split(',')[1:] + float(cell)*1000 for cell in csv_factors.splitlines()[2].split(',')[1:] if cell.strip()] # ref_vol = tuberacks15[0].wells()[0].max_volume / 1000 # 2ml or 15ml # ref_height = tuberacks15[0].wells()[0].depth @@ -129,9 +133,11 @@ def height_inc(self, vol): for well, vol, height in zip( factor_tubes, factor_volumes_ul, factor_heights)] - def slow_withdraw(well, pip=p1000): + def slow_withdraw(well, pip=p1000, delay_s=2.0): ctx.max_speeds['A'] = 25 ctx.max_speeds['Z'] = 25 + if delay_s > 0: + ctx.delay(seconds=delay_s) pip.move_to(well.top()) del ctx.max_speeds['A'] del ctx.max_speeds['Z'] @@ -182,6 +188,9 @@ def custom_distribute(info, pip): for vol in vols_split: media_info.append({well: vol}) + wells_h = [ + WellH(well, height=0) for well in wells_ordered] + for d in media_info: well = list(d.keys())[0] asp_vol = list(d.values())[0] @@ -217,13 +226,53 @@ def custom_distribute(info, pip): p1000.return_tip() p1000.reset_tipracks() + viscosity_map = { + 20: { + 'aspirate': 6.5, + 'delay_aspiration': 2.0, + 'dispense': 6.5, + 'delay_dispense': 2.0, + 'default': 7.56 + }, + 300: { + 'aspirate': 80, + 'delay_aspiration': 2.0, + 'dispense': 80, + 'delay_dispense': 2.0, + 'default': 92.86 + }, + 1000: { + 'aspirate': 247, + 'delay_aspiration': 2.0, + 'dispense': 247, + 'delay_dispense': 2.0, + 'default': 247 + } + } + # transfer factors - for i, factor in enumerate(factors): + for i, (visc, factor) in enumerate(zip(factor_viscosities, factors)): factor_vols = [line[i] for line in factor_data] factor_info = [ {well: vol} - for well, vol in zip(wells_ordered, factor_vols)] + for well, vol in zip(wells_h, factor_vols)] factor_sets = custom_distribute(factor_info, pip=pip_small) + if visc: + asp_rate_relative = viscosity_map[ + int(pip_small.max_volume)]['aspirate'] / ( + viscosity_map[int(pip_small.max_volume)]['default']) + asp_delay = viscosity_map[ + int(pip_small.max_volume)]['delay_aspiration'] + disp_rate_relative = viscosity_map[ + int(pip_small.max_volume)]['dispense'] / ( + viscosity_map[int(pip_small.max_volume)]['default']) + disp_delay = viscosity_map[ + int(pip_small.max_volume)]['delay_dispense'] + else: + asp_rate_relative = 1 + asp_delay = 2.0 + disp_rate_relative = 1 + disp_delay = 2.0 for factor_set in factor_sets: # aspirate total vol needed if not pip_small.has_tip: @@ -237,10 +286,15 @@ def custom_distribute(info, pip): else: ag_vol = pip_small.max_volume - asp_vol pip_small.aspirate(ag_vol, factor.well.top()) - pip_small.aspirate(asp_vol, factor.height_dec(asp_vol)) - slow_withdraw(factor.well, pip_small) + pip_small.aspirate( + asp_vol, factor.height_dec(asp_vol), + rate=asp_rate_relative) + slow_withdraw(factor.well, pip_small, delay_s=asp_delay) pip_small.dispense( - pip_small.current_volume, well.bottom(well.depth/2)) + pip_small.current_volume, + well.height_inc(asp_vol).move(Point(z=3)), + rate=disp_rate_relative) + ctx.delay(seconds=disp_delay) pip_small.blow_out(well.top(-2)) # total_factor_vol = sum([sum(dict.values()) for dict in