VWorks loops

I’m running VWorks 13.0 with an Agilent Bravo NGS B. I’m resuspending magnetic beads that are in a ring after sitting on a magnet. To make sure I recover them all, I’m pipetting buffer around the ring in 12 steps moving clockwise after each dispensing step.

The easiest way to program this is with one dispense task inside a loop with a counter to increment the pipetting technique:
[loop start] – dispense – [loop end, counter++] x 12

This works but but the head rises out of the well after each cycle. That’s fine but with 12 consecutive dispensing tasks the tip stays at the dispensing height and works its way around the bead ring quickly. I like this more but having 12 tasks makes it harder to update settings later.

A couple questions:

  1. Does anyone know why the head changes Z-axis position between loops but not consecutive dispensing steps? Can it be prevented?

  2. Is it possible to implement a dispensing loop with a single dispense task plus javascript in the advanced settings pane? I think the answer is no because javascript in the advanced settings pane executes before the actual task and therefore cannot loop instrument motion but I thought someone here might know a clever trick.

thanks,

Just seeing this thread a year later, we should move it to the Agilent Section.

you can simulate the behavior of a loop using task.repeat() but i am not sure if this will keep the head in the wells.

// declare a counter in some other task
var dispCounter = 0;
// In the dispense task, set the volume paramter in the task to to the total volume
// in the aspiration task (this will eliminate any compilier volume errors)


// in the advanced setting of the dispense task use this script and change the values as neeeded
if(dispCounter < 5)
{
  task.Volume = 2;
  task.repeat();
  dispCounter++;
}

You could still do the 12 individual tasks if that is the only way to make it work.

You should write your settings to a set of variables in the Startup Script, then set up each task to reference the variables. That way if you have to tweak the settings, you tweak the variable, then all the tasks are tweaked accordingly. You only have to set up 12 tasks once.

Could also try to combine tasks into a Macro. Then you could collapse the Macro so it isn’t taking up real estate on the protocol GUI.

If task.repeat() does work though, I do suggest that with a breakout/task.skip() count.

Oh, clever that you can get loop-like behavior with task.repeat like that. I’ll have to give it a try and see if it prevents the z-height change between dispensing steps.

@Robotech87, you’re suggesting using task.skip() to make sure the task.repeat() ends when it’s supposed to? Can you explain a bit more about where you’d place it relative to the if loop?

@sgoldman101 it would be something like this:

var taskCounter = 0;

if(taskCounter <= 11){
     taskCounter++;
     task.repeat();
}else{
     taskCounter = 0;
     task.skip();
}

What that does is count each time the task loops. Then after it loops the 12th time, it resets the count and skips the task, aka it breaks out of the loop and moves forward the protocol.

Above is more or less the same as what Pete mentioned. But I assume he wrote his loop with the intend of it running one time. I work in a high throughput environment and would need to repeat everything for hundreds of plates. So mine resets the counter and does loop again for the next plate.

2 Likes

Thanks for the example code. In my case, I’d only be running through the loop once but it seems like a good idea to reset the loop variable anyway. If it persists between runs maybe it could do some mischief.

@sgoldman101 Could you eventually manage? Sorry I had not seen your post. I can confirm what you saw, unfortunately the head gets always moved above the wells when the “open loop” is executed. It is by design.

On a related note: the code written above generates an infinite loop because you are resetting taskCounter to zero every time. As @Pete suggested, you have to do it before entering the task you want to “task.repeat”.

Another possibility is:

taskCounter = taskCounter || 0;
taskCounter = taskCounter > 11 ? 0 : ++taskCounter;
print(taskCounter);
taskCounter ? task.repeat() : task.skip();

The first line sets taskCounter to zero if that variable does not exist (thus preventing the code from aborting), the others lines use ternary operators to reset taskCounter to zero when it exceeds 11 (or any variable you may want to use) and skip the task when taskCounter is zero.

Finally, the way a VWorks task works is the following:

  1. The parameters from the “task parameters” panel are evaluated and assigned to the task.
  2. The code in the “advanced settings” is executed and the “task object” parameters (if any) assigned to the task (possibly overwriting the ones already assigned in step (1)).
  3. The task is executed.

Mauro,

Thanks for the added caution about breaking out of the loop. I’ve recently been improving the manual version of my protocol to make it more automation friendly but am on the fence about when it makes sense to commit time to port the modified version back onto the Bravo.

In the process of figuring out a magentic bead clumping issue with my current Bravo protocols (finally solved) I ended up complicating the liquid handling in ways that are probably unnecessary now.

I’d been wanting to post a question here about decision points for when it’s worthwhile to cut over from a low/medium throughput manual protocol to a high throughput automation protocol but couldn’t quite figure out which category to post under or how to phrase such a big, vague question in a useful way.