Visualizer not updating

My lab is acquiring an OT-2, so I’m trying to set up some test programs to run once it arrives, but since we don’t have the robot yet, I want to use the visualizer. However, every time I run my code, I get a blank visualizer. I even tried copying the code directly from the documentation (as shown below) and have the same issue. Is there something I am missing? Thanks in advance!

from pylabrobot.liquid_handling import LiquidHandler
from pylabrobot.liquid_handling.backends import ChatterBoxBackend
from pylabrobot.visualizer.visualizer import Visualizer
from pylabrobot.resources.hamilton import STARLetDeck
lh = LiquidHandler(backend=ChatterBoxBackend(), deck=STARLetDeck())

await lh.setup()
vis = Visualizer(resource=lh)
await vis.setup()

from pylabrobot.resources import (
    TIP_CAR_480_A00,
    PLT_CAR_L5AC_A00,
    Cos_96_DW_1mL,
    HTF_L
)
tip_car = TIP_CAR_480_A00(name='tip carrier')
tip_car[0] = tip_rack1 = HTF_L(name='tips_01', with_tips=False)
tip_car[1] = tip_rack2 = HTF_L(name='tips_02', with_tips=False)
tip_car[2] = tip_rack3 = HTF_L(name='tips_03', with_tips=False)
tip_car[3] = tip_rack4 = HTF_L(name='tips_04', with_tips=False)
tip_car[4] = tip_rack5 = HTF_L(name='tips_05', with_tips=False)
lh.deck.assign_child_resource(tip_car, rails=15)
plt_car = PLT_CAR_L5AC_A00(name='plate carrier')
plt_car[0] = plate_1 = Cos_96_DW_1mL(name='plate_01')
plt_car[1] = plate_2 = Cos_96_DW_1mL(name='plate_02')
plt_car[2] = plate_3 = Cos_96_DW_1mL(name='plate_03')
lh.deck.assign_child_resource(plt_car, rails=8)
2 Likes

welcome to the forum!

i am unable to reproduce this error…

  • are you using the latest version from github?
  • can you share the output of the javascript console in your browser?

Also, can you share the print output when the server starts? It’s possible you are looking at the wrong URL if you have tried this multiple times and have multiple servers running

Websocket server started at http://127.0.0.1:2121
File server started at http://127.0.0.1:1337 . Open this URL in your browser.

Just got it working by restarting my kernel (I’m using a Jupyter notebook). Is there a way to refresh the visualization output in the same file server? It seems like I need to restart the kernel anytime I update the code or else the previous visualization will show.

1 Like

it should update automatically? as stefan said, make sure the port you are opening in your browser matches what you see in the python output.

Thanks. I’ll play around more next week and see if I can get it working correctly.

1 Like

Just want to follow up and say that I have it working now. A couple notes about how the visualizer seems to work in case anyone has this problem in the future:

  1. Once resources are defined and assigned to spots, they cannot be modified without restarting the visualizer.
  2. It is helpful to run the code line by line so you can see the result of each step.
  3. Be diligent about stopping and closing the visualizer using await vis.stop() and closing the window. Do this any time you want to make a change to your protocol or are done using the visualizer.
2 Likes

great feedback

  1. Once resources are defined and assigned to spots, they cannot be modified without restarting the visualizer.

attributes like size? / in what usecase would expect the visualizer to update?

  1. Be diligent about stopping and closing the visualizer using await vis.stop() and closing the window. Do this any time you want to make a change to your protocol or are done using the visualizer.

why is it needed to do this when making a change to the protocol?

  1. If, for example I want to move a carrier to a different rail, or a rack to a different carrier spot, the visualizer will not update. You will get an error like “resource with name ‘tip carrier’ already defined” or “spot 3 is already occupied” or “resource tips_01 already assigned to deck.” The reason this was an issue for me is that my lab does not have our robot yet, so I am working on protocols virtually where there is no robot to reset. In practice, you would never rearrange the deck once the robot is running, so it wouldn’t be an issue.

  2. Mostly comes back to the reason stated above, or if you need to reset/restart the protocol. I think one of the main problems I had when I first posted was that old servers weren’t fully shut down before I opened new ones. Newbie mistake I guess.

1 Like

Hi @Jaren,
Fellow PLR User and enthusiast here :slight_smile:

If I understand you correctly, you are interested in a friendlier version of “trying out deck configurations in visualisation/simulation mode”?

E.g. to answer questions like “what plates will tips traverse over when I place plate_xyz on slot 5?” (E.g. to assess cross-contamination risk)
Or to assess minimal pipette movement to increase processing speed.

If this is the case, you are right, the visualizer doesn’t and in my opinion should not allow moving labware (plates, tip racks, tube racks) around because the OT-2 cannot move these items around
(with a Hamilton, Tecan or a Flex you would be able to use lh.move_resource() to simulate the movement [though I don’t think the Flex is yet integrated into PLR]).

Instead I recommend have a split screen, and use your Notebook in VScode or JupyterLab, not Jupter Notebook.

Jupyterlab and VScode have a button “Restart Kernel and Run Up to Current Cell” which means you just stay at your deck setup, make a change, click the button, a new visualizer should open up automatically in the second window, and you can visually inspect your new deck layout.
That way you can go through at least 5 different deck designs per minute :slight_smile:

2 Likes

I actually disagree and think that we should correctly visualize what is going on in the labware tree, even when modified directly instead of lh.move_resource. The goal is to visualize what PLR is “thinking”. (Humans might move those resources on OT while iterating on a protocol.) I will investigate.

Great temporary solution, but let’s aim for a Visualizer where no kernel restart is necessary. We should do much more than 5/min. @Jaren, please keep reporting on what you need :slight_smile:

2 Likes

That is a very good point, I am convinced, that would also help a ton with coboting.

What do you think about

lh.move_resource(resource_x, destination_x, use_arm="manual")

question = input(f"Have you moved {resource_x} to {destination_x}?")

?

That way nothing fancy has to be invented, and the move command is only a wrapper for the unassign and assign processes?

I think just resource.unassing() and deck.assign_child_resource(resource, location=new) should work.

I actually think the current visualizer is sufficient for my needs now that I understand how it works. This week I’ll begin actually coding protocols that we use in our lab, so I’ll post any feedback as I work on that.

I actually haven’t been needing to restart my kernel as long as I stop the visualizer, so adding a stop command to the front of my code would probably accomplish the same thing. That being said, I agree with Rick that the visualizer should match the PLR code to speed up changing deck designs and avoid a situation where somebody accidentally runs an incorrect protocol based on what the visualizer showed.

1 Like