Creating & changing patterns in VBA (scripted Let)

I have a simple problem (I hope), but I can’t find a solution. I’m looking to create a pattern dynamically in VBA for conditional and or unique platemaps for things like lib prep, cleanups, etc that can optimize aliquoting with 8ch pods. An example is below:

image

Let’s say I want to use the 8ch Pod to aliquot diluent to the blue wells, then use the 96ch to mix columns 1-4 simultaneously. How would I create, access, change or otherwise modify a pattern to associate to 8ch pod transfer commands?

I can see that there are .Pattern and .SelectionInfo commands with [96] arrays, but not sure how/where to access for changes and which will modify the info I want. Possibly something like Positions(“P6”).Labware.Pattern arr(i)?

@evwolfson What version of the Biomek software are you using?

v5.1.10.

I realize that Biomek counts wells row wise THEN column so I need to figure out a couple functions as well to utilize patterns naturally, but its all WIP. Just finding out how to modify the patterns would be a huge step forward.

Well unfortunately there was not a lot of feedback on this question from the Biomek support line… but I was able to find the following solution. The following group of functions first convert input sample number into your typical well format, column-row wise (biomek uses row-column wise by default), and creates the specified pattern if it doesn’t yet exist. It loads an array with the wells after conversion to col-row and finally loads that array into the existing or created pattern. This can probably be pretty-fied with an additional sub to replace the array redim, but this is the MVP as it stands.

Option Explicit 
Dim PatternName, SampleNumber, x, lwpat, pat, col, row

'   Reorient well number to col-row wise. e.g., A1, B1, C1... becomes 1, 13, 25... '
function WellNumCountingDown  ( wellNum ) 
   col = ((wellNum-1) \ 8)+1
   row = (wellNum-1) mod 8+1
   WellNumCountingDown = col + ((row-1) * 12)
end function 

'   Check if pattern exists, create it otherwise. '
sub SafeCreatePattern ( patternName, wellsX, wellsY )
set lwpat = world.lwpatterns.variantdictionary
  if not LwPat.isBound (  patternName ) then
    set pat =  createobject ( "Biomek5.eeor")
    pat.Name = patternName
    pat.WellsX = WellsX
    pat.WellsY = WellsY
    redim WellPatSelected (wellsX * wellsY - 1 ) 

    pat.selected = wellpatSelected
    world.Lwpatterns (patternName) = pat
    
  end if
end sub

'   Designate your desired sample number and pattern name '
SampleNumber = 38
patternName = "WellPattern1"

'   Load array x() with sample number and make pattern accessible outside of script. '
redim x(95)
  for i = 1 to SampleNumber
   x(WellNumCountingDown  (i)-1) = i <= SampleNumber
  next

SafeCreatePattern "WellPattern1", 12, 8
world.lwpatterns(patternName).selected = x
1 Like

Extra note, it appears as if patterns cannot be variable within transfer steps. In order to create custom patterns then use them, they have to share a similar name so the strategy is to either modify patterns as needed, or load a generic pattern as needed and refer to it in the transfer steps. Patterns, as I understand, are 0-index 96-item arrays and can be loaded into another pattern very easily.

world.lwpatterns("GenericPattern").selected = world.lwpatterns(PatternVariable).selected
In the above example, GenericPattern is a str, the name of an existing pattern, and PatternVariable is a variable containing the string name of a second pattern, existing or created.

1 Like

To expand a bit:

  • Switching Between Multiple Patterns in a Method Step
    • The Pattern field in a transfer does not accept expressions
    • The Pattern field in a transfer only accepts patterns that are listed in the drop-down
    • To make pattern selection dynamic use scripting to copy a desired pattern to a placeholder pattern
    • Create a placeholder pattern in either the Define Pattern Step or the Well Pattern Editor
      • Patterns created in the Define Pattern step are stored as a variable and have a scope of the method only
      • Patterns created in the Well Pattern Editor are project items and will be available to all methods within that project
    • Create whatever patterns you intend on using in either the Define Pattern Step or the Well Pattern Editor
    • Patterns created in the Define Pattern step are referred to using the notation World.Globals.PropertyChanger.LWPatterns.PatternName.selected
    • Patterns created in the Well Pattern editor are referred to using the notation World.LWPatterns.PatternName.selected
    • VBScript line to copy your desired pattern to the generic pattern would be World.LWPatterns.GenericPattern.selected = World.LWPatterns.DesiredPattern.selected
    • After copying your desired pattern to the generic pattern, configure the Transfer Step to use the generic pattern to select the wells
2 Likes

This is exactly what I ended up doing!

The thought about loading them with an array dynamically was so I could create something akin to Hamilton sequences. My idea was to define the platemap in a pattern for the largest-case number of replicates and samples, then to load it partially for each condition. e.g., if each sample has 7 replicates + 1 control, I would need one full column per sample and a max of 12 samples. However, since I was having issues loading a pattern such as this dynamically, I ended up utilizing the transfer command, replicating the source well x number of times, where x is equal to my 7 replicats + 1 control.

In this image, the l_PatternVolatile is loaded with a step-specific pattern/platemap and then the “Replicate each well” entry is filled with basically [Number_Wells_Per_Sample * Number_of_Samples] such that the source well is replicated following the plate map for as many wells as I need while following the platemap. I don’t think this is the best solution, but its one of many solutions and it works for what I need.