Worklist
Basics#
The most flexible way to give pipetting instructions to the Tecan EVO or Fluent are Gemini worklist files (*.gwl
).
A simple worklist might look like this:
W1;
A;MasterMix;;;1;;50.00;;;;
D;AssayPlate;;;1;;50.00;;;;
W1;
A;MasterMix;;;2;;50.00;;;;
D;AssayPlate;;;2;;50.00;;;;
Between the ;
, the EVOware or Fluent Control accept various parameters such as the liquid class or rack type.
As you might guess from the above example you don’t want to write such worklist files by hand.
Instead, robotools
can write these worklists for you!
This is typically done with a robot-specific subtype of BaseWorklist
.
The BaseWorklist
classes are context managers that automatically creates a worklist with the commands corresponding to the methods you are calling.
Let’s see an example 👇
import robotools
Labware Definition#
Let’s say we are writing a simple assay procedure where samples and mastermix are combined in an MTP.
# Let's say we have 6 1.5 mL Eppis with 500 µL sample each.
samples = robotools.Labware("Samples", 6, 1, min_volume=20, max_volume=1500, initial_volumes=500)
# We want to run an assay in a microtiterplate
assay = robotools.Labware("AssayMTP", 8, 12, min_volume=30, max_volume=300)
# We have a trough with assay mastermix
mastermix = robotools.Trough("MasterMix", 8, 1, min_volume=5000, max_volume=25_000, initial_volumes=10_000)
# To inspect the initial volumes:
print(samples)
print(assay)
print(mastermix)
Samples
[[500.]
[500.]
[500.]
[500.]
[500.]
[500.]]
AssayMTP
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
MasterMix
[[10000.]]
Choosing the Worklist Type#
As shown above, there are three worklist classes, with BaseWorklist
being the generic one, and EvoWorklist
/FluentWorklist
featuring slightly different APIs.
Notable differences between EvoWorklist
and FluentWorklist
are:
EvoWorklist
also hasevo_wash()
,evo_aspirate()
andevo_dispense()
methods.Numbering of trough wells in the generated worklist commands accounts for EVO/Fluent differences.
Writing a Worklist#
The BaseWorklist
has a ton of methods that are available with both EvoWorklist
and FluentWorklist
.
It doesn’t make sense to list them all here, but you can use help(robotools.BaseWorklist)
or look them up in the documentation.
The most commonly used method is .transfer()
:
help(robotools.EvoWorklist.transfer)
Help on function transfer in module robotools.evotools.worklist:
transfer(self, source: robotools.liquidhandling.labware.Labware, source_wells: Union[str, Sequence[str], numpy.ndarray], destination: robotools.liquidhandling.labware.Labware, destination_wells: Union[str, Sequence[str], numpy.ndarray], volumes: Union[float, Sequence[float], numpy.ndarray], *, label: Optional[str] = None, wash_scheme: int = 1, partition_by: str = 'auto', **kwargs) -> None
Transfer operation between two labwares.
Parameters
----------
source : liquidhandling.Labware
Source labware
source_wells : str or iterable
List of source well ids
destination : liquidhandling.Labware
Destination labware
destination_wells : str or iterable
List of destination well ids
volumes : float or iterable
Volume(s) to transfer
label : str
Label of the operation to log into labware history
wash_scheme : int
Wash scheme to apply after every tip use
partition_by : str
one of 'auto' (default), 'source' or 'destination'
'auto': partitioning by source unless the source is a Trough
'source': partitioning by source columns
'destination': partitioning by destination columns
kwargs
Additional keyword arguments to pass to aspirate and dispense.
Most prominent example: `liquid_class`.
Take a look at `Worklist.aspirate_well` for the full list of options.
The worklist is created by entering its context manager.
We can optionally pass a file path and it will automatically write the worklist to that file when leaving the context.
n_samples = samples.n_rows
n_replicates = 3
with robotools.EvoWorklist("02_assay.gwl") as wl:
wl.wash()
# Add triplicates of the samples
for r in range(n_replicates):
wl.transfer(
samples, samples.wells,
assay, assay.wells[:n_samples, r],
10,
label=f"Add replicate {r+1} samples",
)
# Select trough wells to aspirate from
trough_wells = robotools.get_trough_wells(
n=n_samples*n_replicates,
trough_wells=mastermix.wells[:,0],
)
# Add buffer to all wells
wl.transfer(
mastermix, trough_wells,
assay, assay.wells[:n_samples,:n_replicates],
50,
label="Add mastermix",
)
Our three labwares were modified by the pipetting steps. We can inspect the history of the 96-well plate to check if we selected the right wells & volumes:
print(assay.report)
AssayMTP
initial
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
Add replicate 1 samples
[[10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
Add replicate 2 samples
[[10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
Add replicate 3 samples
[[10. 10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[10. 10. 10. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
Add mastermix
[[60. 60. 60. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[60. 60. 60. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[60. 60. 60. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[60. 60. 60. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[60. 60. 60. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[60. 60. 60. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
If a filepath
was passed, the worklist automatically writes worklist (wl
) to it, overwriting any previous content.
with Worklist(filepath=...) as wl:
...
Note that it includes the label
s as comments.
with open("02_assay.gwl") as wlfile:
print(wlfile.read())
W1;
C;Add replicate 1 samples
A;Samples;;;1;;10.00;;;;
D;AssayMTP;;;1;;10.00;;;;
W1;
A;Samples;;;2;;10.00;;;;
D;AssayMTP;;;2;;10.00;;;;
W1;
A;Samples;;;3;;10.00;;;;
D;AssayMTP;;;3;;10.00;;;;
W1;
A;Samples;;;4;;10.00;;;;
D;AssayMTP;;;4;;10.00;;;;
W1;
A;Samples;;;5;;10.00;;;;
D;AssayMTP;;;5;;10.00;;;;
W1;
A;Samples;;;6;;10.00;;;;
D;AssayMTP;;;6;;10.00;;;;
W1;
C;Add replicate 2 samples
A;Samples;;;1;;10.00;;;;
D;AssayMTP;;;9;;10.00;;;;
W1;
A;Samples;;;2;;10.00;;;;
D;AssayMTP;;;10;;10.00;;;;
W1;
A;Samples;;;3;;10.00;;;;
D;AssayMTP;;;11;;10.00;;;;
W1;
A;Samples;;;4;;10.00;;;;
D;AssayMTP;;;12;;10.00;;;;
W1;
A;Samples;;;5;;10.00;;;;
D;AssayMTP;;;13;;10.00;;;;
W1;
A;Samples;;;6;;10.00;;;;
D;AssayMTP;;;14;;10.00;;;;
W1;
C;Add replicate 3 samples
A;Samples;;;1;;10.00;;;;
D;AssayMTP;;;17;;10.00;;;;
W1;
A;Samples;;;2;;10.00;;;;
D;AssayMTP;;;18;;10.00;;;;
W1;
A;Samples;;;3;;10.00;;;;
D;AssayMTP;;;19;;10.00;;;;
W1;
A;Samples;;;4;;10.00;;;;
D;AssayMTP;;;20;;10.00;;;;
W1;
A;Samples;;;5;;10.00;;;;
D;AssayMTP;;;21;;10.00;;;;
W1;
A;Samples;;;6;;10.00;;;;
D;AssayMTP;;;22;;10.00;;;;
W1;
C;Add mastermix
A;MasterMix;;;1;;50.00;;;;
D;AssayMTP;;;1;;50.00;;;;
W1;
A;MasterMix;;;2;;50.00;;;;
D;AssayMTP;;;2;;50.00;;;;
W1;
A;MasterMix;;;3;;50.00;;;;
D;AssayMTP;;;3;;50.00;;;;
W1;
A;MasterMix;;;4;;50.00;;;;
D;AssayMTP;;;4;;50.00;;;;
W1;
A;MasterMix;;;5;;50.00;;;;
D;AssayMTP;;;5;;50.00;;;;
W1;
A;MasterMix;;;6;;50.00;;;;
D;AssayMTP;;;6;;50.00;;;;
W1;
A;MasterMix;;;7;;50.00;;;;
D;AssayMTP;;;9;;50.00;;;;
W1;
A;MasterMix;;;8;;50.00;;;;
D;AssayMTP;;;10;;50.00;;;;
W1;
A;MasterMix;;;1;;50.00;;;;
D;AssayMTP;;;11;;50.00;;;;
W1;
A;MasterMix;;;2;;50.00;;;;
D;AssayMTP;;;12;;50.00;;;;
W1;
A;MasterMix;;;3;;50.00;;;;
D;AssayMTP;;;13;;50.00;;;;
W1;
A;MasterMix;;;4;;50.00;;;;
D;AssayMTP;;;14;;50.00;;;;
W1;
A;MasterMix;;;5;;50.00;;;;
D;AssayMTP;;;17;;50.00;;;;
W1;
A;MasterMix;;;6;;50.00;;;;
D;AssayMTP;;;18;;50.00;;;;
W1;
A;MasterMix;;;7;;50.00;;;;
D;AssayMTP;;;19;;50.00;;;;
W1;
A;MasterMix;;;8;;50.00;;;;
D;AssayMTP;;;20;;50.00;;;;
W1;
A;MasterMix;;;1;;50.00;;;;
D;AssayMTP;;;21;;50.00;;;;
W1;
A;MasterMix;;;2;;50.00;;;;
D;AssayMTP;;;22;;50.00;;;;
W1;
%load_ext watermark
%watermark -idu
Last updated: 2024-04-23T15:21:04.769387+02:00