pudu.plating

Classes for automated and manual serial-dilution spot plating.

  • Plating — OT-2 protocol that takes transformed bacteria from a thermocycler plate, performs up to two serial dilutions, and spots each dilution onto agar plates with replicates.

  • ManualPlating — generates a human-readable Markdown bench protocol.

On simulation, Plating writes:

  • {protocol_name}.json — machine-readable agar plate map

  • {protocol_name}.xlsx — colour-coded Excel grid (blue = dilution 1, orange = dilution 2)

class pudu.plating.Plating(plating_data=None, json_params=None, volume_total_reaction=20, volume_bacteria_transfer=2, volume_colony=4, dilution_factor=10, volume_lb=10000, replicates=1, number_dilutions=2, max_colonies=192, thermocycler_starting_well=0, thermocycler_labware='biorad_96_wellplate_200ul_pcr', small_tiprack='opentrons_96_filtertiprack_20ul', small_tiprack_position='9', initial_small_tip=None, large_tiprack='opentrons_96_filtertiprack_200ul', large_tiprack_position='1', initial_large_tip=None, small_pipette='p20_single_gen2', small_pipette_position='left', large_pipette='p300_single_gen2', large_pipette_position='right', dilution_plate='nest_96_wellplate_100ul_pcr_full_skirt', dilution_plate_position1='2', dilution_plate_position2='3', agar_plate='nest_96_wellplate_100ul_pcr_full_skirt', agar_plate_position1='5', agar_plate_position2='6', tube_rack='opentrons_15_tuberack_falcon_15ml_conical', tube_rack_position='4', lb_tube_position=0, aspiration_rate=0.5, dispense_rate=1, bacterium_locations=None, protocol_name='plating_layout', **kwargs)[source]

Bases: object

Automated serial-dilution and spot-plating protocol for the Opentrons OT-2.

Takes transformed bacteria from a thermocycler plate, performs up to two sequential 10× (or custom) dilutions in a dilution plate, and spots each dilution onto an agar plate. Supports multiple replicates and automatically distributes across two physical plates when colony counts exceed 96.

After simulation, writes a JSON and an Excel file mapping each agar-plate well to the construct name, dilution ratio, and replicate number.

Parameters:
  • plating_data (Dict | None)

  • json_params (Dict | None)

  • volume_total_reaction (float)

  • volume_bacteria_transfer (float)

  • volume_colony (float)

  • dilution_factor (float)

  • volume_lb (float)

  • replicates (int)

  • number_dilutions (int)

  • max_colonies (int)

  • thermocycler_starting_well (int)

  • thermocycler_labware (str)

  • small_tiprack (str)

  • small_tiprack_position (str)

  • initial_small_tip (str | None)

  • large_tiprack (str)

  • large_tiprack_position (str)

  • initial_large_tip (str | None)

  • small_pipette (str)

  • small_pipette_position (str)

  • large_pipette (str)

  • large_pipette_position (str)

  • dilution_plate (str)

  • dilution_plate_position1 (str)

  • dilution_plate_position2 (str)

  • agar_plate (str)

  • agar_plate_position1 (str)

  • agar_plate_position2 (str)

  • tube_rack (str)

  • tube_rack_position (str)

  • lb_tube_position (int)

  • aspiration_rate (float)

  • dispense_rate (float)

  • bacterium_locations (Dict | None)

  • protocol_name (str)

volume_total_reaction

Volume of bacteria loaded in each thermocycler source well, in µL. Used for liquid-tracking display only.

volume_bacteria_transfer

Volume transferred from each source well into the dilution well, in µL.

volume_colony

Volume spotted from each dilution well onto the agar plate per replicate, in µL.

dilution_factor

Serial dilution factor applied at each step (e.g. 10 for a 1:10 dilution). The LB volume pre-loaded into each dilution well is volume_bacteria_transfer × (dilution_factor 1).

volume_lb

Total LB volume in the stock tube, in µL. Used for liquid tracking on the Opentrons deck visualiser.

replicates

Number of agar spots per construct per dilution step.

number_dilutions

Number of serial dilution steps to perform (max 2).

number_constructs

Number of unique constructs derived from bacterium_locations.

total_colonies

Total agar wells that will be plated (number_constructs × number_dilutions × replicates).

max_colonies

Hard cap on total_colonies; raises ValueError if exceeded.

bacterium_locations

Dict mapping thermocycler well names to construct identifiers, e.g. {'A1': 'GFP_construct', 'B1': ['RFP', 'v2']}.

protocol_name

Base name for output files (JSON and Excel).

__init__(plating_data=None, json_params=None, volume_total_reaction=20, volume_bacteria_transfer=2, volume_colony=4, dilution_factor=10, volume_lb=10000, replicates=1, number_dilutions=2, max_colonies=192, thermocycler_starting_well=0, thermocycler_labware='biorad_96_wellplate_200ul_pcr', small_tiprack='opentrons_96_filtertiprack_20ul', small_tiprack_position='9', initial_small_tip=None, large_tiprack='opentrons_96_filtertiprack_200ul', large_tiprack_position='1', initial_large_tip=None, small_pipette='p20_single_gen2', small_pipette_position='left', large_pipette='p300_single_gen2', large_pipette_position='right', dilution_plate='nest_96_wellplate_100ul_pcr_full_skirt', dilution_plate_position1='2', dilution_plate_position2='3', agar_plate='nest_96_wellplate_100ul_pcr_full_skirt', agar_plate_position1='5', agar_plate_position2='6', tube_rack='opentrons_15_tuberack_falcon_15ml_conical', tube_rack_position='4', lb_tube_position=0, aspiration_rate=0.5, dispense_rate=1, bacterium_locations=None, protocol_name='plating_layout', **kwargs)[source]
Parameters:
  • plating_data (Dict | None)

  • json_params (Dict | None)

  • volume_total_reaction (float)

  • volume_bacteria_transfer (float)

  • volume_colony (float)

  • dilution_factor (float)

  • volume_lb (float)

  • replicates (int)

  • number_dilutions (int)

  • max_colonies (int)

  • thermocycler_starting_well (int)

  • thermocycler_labware (str)

  • small_tiprack (str)

  • small_tiprack_position (str)

  • initial_small_tip (str | None)

  • large_tiprack (str)

  • large_tiprack_position (str)

  • initial_large_tip (str | None)

  • small_pipette (str)

  • small_pipette_position (str)

  • large_pipette (str)

  • large_pipette_position (str)

  • dilution_plate (str)

  • dilution_plate_position1 (str)

  • dilution_plate_position2 (str)

  • agar_plate (str)

  • agar_plate_position1 (str)

  • agar_plate_position2 (str)

  • tube_rack (str)

  • tube_rack_position (str)

  • lb_tube_position (int)

  • aspiration_rate (float)

  • dispense_rate (float)

  • bacterium_locations (Dict | None)

  • protocol_name (str)

calculate_plate_layout(protocol, plate1, plate2=None, wells_per_dilution=None)[source]

Calculate the layout for wells on a plate with dynamic expansion across two plates.

Parameters:
  • protocol – Protocol context (used for comments)

  • plate1 – Primary labware object

  • plate2 – Optional secondary labware object, required when wells_per_dilution > 48

  • wells_per_dilution – Number of wells needed per dilution step. Defaults to number_constructs * replicates (original behaviour). Pass number_constructs for dilution plates and number_constructs * replicates for agar plates.

Returns:

dict with plate assignments and well positions keyed by ‘dilution_1’ / ‘dilution_2’

build_agar_plate_map()[source]

Build a nested mapping of agar plate wells to construct metadata.

Returns a dict keyed by plate ('plate_1', 'plate_2') then by dilution step ('dilution_1', 'dilution_2'). Each dilution entry contains 'ratio' (e.g. '1/10') and 'wells', a dict mapping well names (e.g. 'A1') to {'construct', 'source_well', 'replicate'}.

When both dilutions fit on a single 96-well plate (≤ 48 wells per dilution), they are placed in the top and bottom halves respectively. When a dilution exceeds 48 wells, each step gets its own physical plate.

Returns:

Nested dict describing the complete agar plate layout.

Return type:

Dict

get_plates_json()[source]

Return the full agar plate map wrapped under an 'agar_plates' key.

Return type:

Dict

write_plates_json(output_path)[source]

Serialize the agar plate map to a JSON file and return the data dict.

Parameters:

output_path (str) – Filesystem path for the output JSON file.

Returns:

The same dict that was written to disk.

Return type:

Dict

write_plates_excel(output_path)[source]

Write a colour-coded Excel representation of the agar plate map.

Each physical plate becomes a 8 × 12 grid in the worksheet, with cells colour-coded by dilution step (blue for dilution 1, orange for dilution 2) and labelled with the construct name and replicate number.

Parameters:

output_path (str) – Filesystem path for the output .xlsx file.

Raises:

ImportError – If xlsxwriter is not installed.

Return type:

None

run(protocol)[source]

Execute the automated plating protocol on the OT-2.

Deck layout (default positions):
  • Slot 7/8/10/11: Thermocycler module (source bacteria in PCR plate)

  • Slot 1: Large tip rack (200 µL, for LB distribution)

  • Slot 9: Small tip rack (20 µL, for bacteria and agar transfers)

  • Slot 4: Tube rack with LB stock tube

  • Slot 2 (and 3 if needed): Dilution plate(s)

  • Slot 5 (and 6 if needed): Agar plate(s)

Protocol steps:
  1. Distribute LB into all dilution wells using a single large-pipette tip (one aspiration height adjustment per 8-well chunk).

  2. For each construct: transfer bacteria → dilution 1, mix, seed dilution 2 (if requested), then spot dilution 1 onto agar.

  3. With a fresh tip, spot dilution 2 onto agar.

On simulation, writes {protocol_name}.json and {protocol_name}.xlsx describing the agar plate layout.

Parameters:

protocol (ProtocolContext) – Opentrons ProtocolContext provided by the OT-2 runtime.

class pudu.plating.ManualPlating(plating_data=None, bacterium_locations=None, volume_bacteria_transfer=2, volume_colony=4, volume_lb_transfer=18, replicates=1, number_dilutions=2)[source]

Bases: object

Manual counterpart of automated plating protocol.

Parameters:
  • plating_data (Dict | None)

  • bacterium_locations (Dict | None)

  • volume_bacteria_transfer (float)

  • volume_colony (float)

  • volume_lb_transfer (float)

  • replicates (int)

  • number_dilutions (int)

__init__(plating_data=None, bacterium_locations=None, volume_bacteria_transfer=2, volume_colony=4, volume_lb_transfer=18, replicates=1, number_dilutions=2)[source]
Parameters:
  • plating_data (Dict | None)

  • bacterium_locations (Dict | None)

  • volume_bacteria_transfer (float)

  • volume_colony (float)

  • volume_lb_transfer (float)

  • replicates (int)

  • number_dilutions (int)

process_bacterium_locations()[source]
render_markdown()[source]
Return type:

str

write_markdown(output_path)[source]
Parameters:

output_path (str)

class pudu.plating.ManualPlatingRecord(source_well: str, construct_name: str)[source]

Bases: object

Parameters:
  • source_well (str)

  • construct_name (str)

source_well: str
construct_name: str