I am working on simulating a protocol for Opentrons OT-2, and I have the visualizer running but it only shows the starting deck, and stays that way for the duration of the protocol. If I close the tab and open it again after the protocol is complete, it updates the deck to what it would look like after the completed method. Can anyone tell me what my issue might be and how I can get it to update in live time as the liquid is moving? Thank you!
import asyncio
from pylabrobot.liquid_handling import LiquidHandler, OpentronsOT2Backend
from pylabrobot.liquid_handling.standard import Mix
from pylabrobot.resources import OTDeck, Plate, Well, WellBottomType, create_ordered_items_2d
from pylabrobot.liquid_handling.backends import OpentronsOT2Simulator
from pylabrobot.resources.opentrons.load import load_ot_tip_rack
from pylabrobot.resources.coordinate import Coordinate
from pylabrobot.liquid_handling.backends import LiquidHandlerChatterboxBackend
from pylabrobot.visualizer.visualizer import Visualizer
from pylabrobot.resources import set_tip_tracking, set_volume_tracking
set_tip_tracking(True)
set_volume_tracking(True)
async def main():
deck = OTDeck() lh = LiquidHandler(backend=OpentronsOT2Simulator(), deck=deck) await lh.setup() vis = Visualizer(resource=lh) await vis.setup() print("Visualizer is running. Open http://127.0.0.1:1337 in your browser.") *#0 is left, 1 is right* p20=1 p300=0 index_letters=\["A", "B", "C", "D", "E", "F", "G", "H"\] *#Create Custom Labware* plate_2 = Plate( name="costaralpaqua_96_wellplate_2200ul", size_x=127.76, size_y=85.47, size_z=72.82, ordered_items=create_ordered_items_2d( Well, num_items_x=12, num_items_y=8, dx=14.38, dy=11.25, dz=1, item_dx=9, item_dy=9, size_x=8.15, size_y=8.15, size_z=42.42, bottom_type=WellBottomType.V, max_volume=2200, ), ) plate_1 = Plate( name="costar_96_wellplate_2200ul", size_x=127.76, size_y=85.47, size_z=43.82, ordered_items=create_ordered_items_2d( Well, num_items_x=12, num_items_y=8, dx=14.38, dy=11.25, dz=1, item_dx=9, item_dy=9, size_x=8.15, size_y=8.15, size_z=42.42, bottom_type=WellBottomType.V, max_volume=2200, ), ) reservoir_1 = Plate( name="axygen_12_reservoir_22000ul", size_x=127.35, size_y=85.10, size_z=43.80, ordered_items=create_ordered_items_2d( Well, num_items_x=12, num_items_y=1, dx=14.98, dy=40.80, dz=1, item_dx=9, item_dy=0, size_x=8.00, size_y=71.00, size_z=37.50, bottom_type=WellBottomType.FLAT, max_volume=22000, ), ) plate_3 = Plate( name="axygen_96_wellplate_1100ul 1", size_x=127.76, size_y=85.47, size_z=27, ordered_items=create_ordered_items_2d( Well, num_items_x=12, num_items_y=8, dx=14.24, dy=11.19, dz=1, item_dx=9, item_dy=9, size_x=8.71, size_y=8.71, size_z=23.48, bottom_type=WellBottomType.U, max_volume=1100, ), ) plate_4 = Plate( name="axygen_96_wellplate_1100ul 2", size_x=127.76, size_y=85.47, size_z=27, ordered_items=create_ordered_items_2d( Well, num_items_x=12, num_items_y=8, dx=14.24, dy=11.19, dz=1, item_dx=9, item_dy=9, size_x=8.71, size_y=8.71, size_z=23.48, bottom_type=WellBottomType.U, max_volume=1100, ), ) *#Load Labware* tiprack_1 = load_ot_tip_rack( ot_name="opentrons_96_tiprack_300ul", plr_resource_name = "300uL Tip Rack 1" ) tiprack_2 = load_ot_tip_rack( ot_name="opentrons_96_tiprack_300ul", plr_resource_name = "300uL Tip Rack 2" ) tiprack_3 = load_ot_tip_rack( ot_name="opentrons_96_tiprack_300ul", plr_resource_name = "300uL Tip Rack 3" ) tiprack_4 = load_ot_tip_rack( ot_name="opentrons_96_tiprack_300ul", plr_resource_name = "300uL Tip Rack 4" ) tiprack_5 = load_ot_tip_rack( ot_name="opentrons_96_tiprack_300ul", plr_resource_name = "300uL Tip Rack 5" ) tiprack_6 = load_ot_tip_rack( ot_name="opentrons_96_tiprack_300ul", plr_resource_name = "300uL Tip Rack 6" ) *#Assign Deck Locations* lh.deck.assign_child_at_slot(tiprack_1, slot=2) lh.deck.assign_child_at_slot(tiprack_2, slot=3) lh.deck.assign_child_at_slot(tiprack_3, slot=5) lh.deck.assign_child_at_slot(tiprack_4, slot=6) lh.deck.assign_child_at_slot(tiprack_5, slot=9) lh.deck.assign_child_at_slot(tiprack_6, slot=8) lh.deck.assign_child_at_slot(reservoir_1, slot=11) lh.deck.assign_child_at_slot(plate_1, slot=1) lh.deck.assign_child_at_slot(plate_2, slot=4) lh.deck.assign_child_at_slot(plate_3, slot=10) lh.deck.assign_child_at_slot(plate_4, slot=7) *#Load Tips* tiprack_1.fill() tiprack_2.fill() tiprack_3.fill() tiprack_4.fill() tiprack_5.fill() plate_1.set_well_volumes(\[1000\]\*96) plate_4.set_well_volumes(\[50\]\*96) reservoir_1.set_well_volumes(\[20000, 20000, 20000, 20000, 9600, 20000, 0, 0, 0, 0, 0, 0\]) *#Wash Buffer* wash_tips = \[tiprack_3, tiprack_4, tiprack_5\] *#Start Method* *#Equilibrate Beads* for i in range(8): for m in range(12): index = index_letters\[i\] + str(m+1) await lh.pick_up_tips(tiprack_1\[index\], use_channels=\[p300\]) await lh.aspirate(reservoir_1\["A6"\], vols=\[200\], use_channels=\[p300\]) await lh.dispense(plate_4\[index\], vols=\[200\], use_channels=\[p300\]) for j in range(10): await lh.aspirate(plate_4\[index\], vols=\[150\], use_channels=\[p300\]) await lh.dispense(plate_4\[index\], vols=\[150\], use_channels=\[p300\]) await lh.aspirate(plate_4\[index\], vols=\[250\], use_channels=\[p300\]) await lh.dispense(plate_2\[index\], vols=\[250\], use_channels=\[p300\]) await asyncio.sleep(1) *#Temporarily change this to 1* await lh.aspirate(plate_2\[index\], vols=\[200\], use_channels=\[p300\]) await lh.dispense(reservoir_1\["A7"\], vols=\[200\], use_channels=\[p300\]) await lh.return_tips() print("Checkpoint 1 " + str(i+1) + str(m+1)) for i in range(8): for m in range(12): index = index_letters\[i\] + str(m+1) await lh.pick_up_tips(tiprack_2\[index\], use_channels=\[p300\]) for k in range(4): await lh.aspirate(plate_1\[index\], vols=\[250\], use_channels=\[p300\]) await lh.dispense(plate_2\[index\], vols=\[250\], use_channels=\[p300\], blow_out=True, blow_out_air_volume=\[50\]) print("Checkpoint 2 " + str(i+1) + str(m+1)) for l in range(9): await lh.aspirate(plate_2\[index\], vols=\[250\], use_channels=\[p300\]) await lh.dispense(plate_2\[index\], vols=\[250\], use_channels=\[p300\]) await lh.aspirate(plate_2\[index\], vols=\[250\], flow_rate=200, use_channels=\[p300\]) await lh.dispense(plate_2\[index\], vols=\[250\], flow_rate=50, use_channels=\[p300\], blow_out=True, blow_out_air_volume=\[50\]) *#Touch tip* *#Pause* await lh.move_channel_z(p300, 72) *#Fill this with top of well height* await asyncio.sleep(1) *#Temporarily change this to 1 from 10* for k in range(4): await lh.aspirate(plate_2\[index\], vols=\[250\], flow_rate=200, use_channels=\[p300\], offsets=\[Coordinate(x=0, y=0, z=4)\]) await lh.dispense(plate_1\[index\], vols=\[250\], flow_rate=50, use_channels=\[p300\]) *#maybe add an offset to make it dispense at the top* print("Checkpoint 3 " + str(i+1) + str(m+1)) await lh.return_tips() *#await lh.discard_tips()* *#Wash Step* for l in range(2): print("Checkpoint 4&5 " + str(l+1)) for m in range(8): print("Checkpoint 6 " + str(m+1)) for n in range(12): index = index_letters\[m\] + str(n+1) await lh.pick_up_tips(wash_tips\[l\]\[index\], use_channels=\[p300\]) *#Determining which wash buffer reservoir to take from* if m < 2: wash_reservoir = 1 if m >= 2 and m < 4: wash_reservoir = 2 if m >= 4 and m < 6: wash_reservoir = 3 if m >= 6 and m < 8: wash_reservoir = 4 *#Transfer Wash Buffer to Plate* for o in range(2): await lh.aspirate(reservoir_1\["A"+str(wash_reservoir)\], vols=\[200\], use_channels=\[p300\]) *#has at z=2 but i changed labware* await lh.dispense(plate_2\[index\], vols=\[200\], mix=\[Mix(volume=200, repetitions=10, flow_rate=100)\], use_channels=\[p300\]) *#Aspirate Wash Buffer* for o in range(2): await lh.aspirate(plate_2\[index\], vols=\[200\], use_channels=\[p300\], offsets=\[Coordinate(x=0,y=0,z=.5)\]) await lh.dispense(reservoir_1\["A"+str(wash_reservoir+7)\], vols=\[200\], use_channels=\[p300\]) await lh.return_tips() *#await lh.discard_tips()* *#Elution Step* for i in range(8): print("Checkpoint 7 " + str(i+1)) for j in range(12): index = index_letters\[i\] + str(j+1) await lh.pick_up_tips(tiprack_6\[index\], use_channels=\[p300\]) *#Transferring Elution Buffer to Wells + Resuspending* await lh.aspirate(reservoir_1\["A5"\], vols=\[100\], use_channels=\[p300\]) await lh.dispense(plate_2\[index\], vols=\[100\], mix=\[Mix(volume=50, repetitions=5, flow_rate=100)\], use_channels=\[p300\]) *#Dispense at top -- 20 for blowout, might not work* *#Transferring Eluted Protein to Final Plate* await lh.aspirate(plate_2\[index\], vols=\[100\], use_channels=\[p300\]) await lh.dispense(plate_3\[index\], vols=\[100\], use_channels=\[p300\], blow_out=True, blow_out_air_volume=\[50\]) await lh.return_tips() *#await lh.discard_tips()* await asyncio.Event().wait() await vis.stop() await lh.stop()if _name_ == “_main_”:
asyncio.run(main())